CSS3动画–使用贝塞尔曲线创建具有弹跳效果的扇出
您是否知道可以使用transform
CSS属性(例如缩放,倾斜和旋转)将动画转换添加到HTML元素中, ? 可以使用transition
属性和@keyframes
动画对它们进行动画@keyframes
,但是更酷的是,可以使用cubic-bezier()
定时函数在动画转换的基础上增加一点弹跳效果 。
它指定过渡的速度,除其他外,它还可以用于在动画中创建弹跳效果 。
简而言之, cubic-bezier()
(在CSS中)是transition的计时函数 。
这是最终结果(单击以查看效果)。
在本教程的最后,您将了解如何创建同时使用扇出效果和弹跳效果的动画。
在本文中,我们首先要创建一个简单的转换动画 ,然后在其中添加一个cubic-bezier()
计时函数 。
该演示的灵感来自克里斯托弗·琼斯 ( Christopher Jones) 拍摄的有关动态位置标记的美丽的Dribbble 。
1.创造叶子
单个角的border-radius
由水平和垂直两个半径组成 ,如下图所示。
为了创建叶子的椭圆形 ,让我们使用border-radius
CSS属性。
位置标记的形状由五片叶子(我们称之为叶子)组成。
我们将使用更复杂的标记形状:
border-radius
属性具有许多不同的语法 。
border-radius: htl htr hbr hbl / vtl vtr vbr vbl;
例如, vbl
代表vbl
的垂直半径。
h
和v
代表水平和垂直半径, t
, l
, b
和r
代表上,左,下和右上角。
用这种语法,水平半径和垂直半径被分组在一起。
如果您只为水平或垂直侧提供一个值 ,则该值将被浏览器复制到所有其他水平或垂直半径。
水平侧将仅使用一个值: 50%
。
要创建垂直椭圆形 ,请将所有角的水平半径保持在50%
,然后调整垂直角,直到看到所需的形状。
左上角和右上角的垂直半径将为30%
,而左下角和右下角的垂直半径将使用70%
值。
<div class="pinStarLeaf"></div>
.pinStarLeaf {
width: 60px;
height: 120px;
border-radius: 50%/30% 30% 70% 70%;
background-color: #B8F0F5;
}
2.乘以树叶
由于标记会散开,显示出五片叶子,因此我们又创建了另外四个颜色不同的叶子副本 ,并以绝对位置放置以便彼此堆叠。
<div id="pinStarWrapper">
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
</div>
#pinStarWrapper{
width: 300px;
height: 300px;
position: relative;
}
.pinStarLeaf{
width: 60px;
height: 120px;
position: absolute;
border-radius: 50%/30% 30% 70% 70% ;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
opacity: .5;
}
.pinStarLeaf:nth-of-type(1){
background-color: #B8F0F5;
}
.pinStarLeaf:nth-of-type(2){
background-color: #9CF3DC;
}
.pinStarLeaf:nth-of-type(3){
background-color: #94F3B0;
}
.pinStarLeaf:nth-of-type(4){
background-color: #D2F8A1;
}
.pinStarLeaf:nth-of-type(5){
background-color: #F3EDA2;
}
3.捕捉点击事件并改善美学
它将位于标记的顶部,并且将是位置标记的中心。
为了美观,我们还需要添加带有#pinStarCenter
标识符的白色圆圈 。
选中此复选框后,树叶将扇出(旋转)。
让我们添加一个带有#pinStarCenterChkBox
标识符的复选框 ,以捕获单击事件。
我们将复选框放置在叶子的前面,然后将白色圆圈放置在叶子的前面:
<div id="pinStarWrapper">
<input type="checkbox" id="pinStarCenterChkBox">
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
<div class="pinStarLeaf"></div>
<div id="pinStarCenter"></div>
</div>
首先,我们为复选框和覆盖圈设置基本样式:
#pinStarCenter, #pinStarCenterChkBox{
width: 45px;
height: 50px;
position: absolute;
left: 0;
right: 0;
top: -60px;
bottom: 0;
margin: auto;
background-color: #fff;
border-radius: 50%;
cursor: pointer;
}
#pinStarCenter, .pinStarLeaf{
pointer-events: none;
}
#pinStarCenter > input[type="checkbox"]{
width: 100%;
height: 100%;
cursor: pointer;
}
我们还为旋转效果应用了transition
属性(更准确地说,我们使用transition: transform 1s linear
对叶子进行transition: transform 1s linear
)。
属性相应地创建星形 。
由于每片叶子将沿z轴以不同角度旋转,因此我们需要设置以下transform: rotatez();
#pinStarCenterChkBox:checked ~ .pinStarLeaf{
transition: transform 1s linear;
}
#pinStarCenterChkBox:checked ~ .pinStarLeaf:nth-of-type(5){
transform: rotatez(35deg);
}
#pinStarCenterChkBox:checked ~ .pinStarLeaf:nth-of-type(4){
transform: rotatez(105deg);
}
#pinStarCenterChkBox:checked ~ .pinStarLeaf:nth-of-type(3){
transform: rotatez(180deg);
}
#pinStarCenterChkBox:checked ~ .pinStarLeaf:nth-of-type(2){
transform: rotatez(255deg);
}
#pinStarCenterChkBox:checked ~ .pinStarLeaf:nth-of-type(1){
transform: rotatez(325deg);
}
如果您查看上面CSS,则可以从#pinStarCenterChkBox:checked ~
常规同级选择器的存在中看到,我们仅在选中复选框 (当用户单击标记时)才添加transition
和transform
属性。
4.修改旋转中心
我们可以通过使用transform-origin
CSS属性来更改转换后的元素的位置,以实现此目的 。
我们需要将转换的中心移到叶子的内端。
默认情况下,旋转中心位于旋转元素的中心 ,在我们的情况下,位于叶子的中心。
为了使旋转效果正常工作,我们将以下两个规则添加到CSS文件中的.pinStarLeaf
选择器中:
.pinStarLeaf{
transform-origin: 30px 30px;
transition: transform 1s linear;
}
单击标记顶部的白色圆圈。
让我们看看我们的扇出动画在运行中-在这一点上,还没有反弹效果。
了解ubic-Bezier()的工作方式
现在,要添加弹跳效果,我们需要在CSS文件的transition
声明中将linear
计时函数替换为cubic-bezier()
。
但是,首先,让我们了解cubic-bezier()
计时函数背后的逻辑,以便您可以轻松理解反弹效果。
cubic-bezier (t1, d1, t2, d2)
即使用距离和时间来解释cubic-bezier()
也不是很准确,但是用这种方式理解它要容易得多。
让我们使用以下cubic-bezier()
时序函数进行t1 = 0
和d1 = 1
值的转换。
假设有一个盒子在6秒内从A点移到B点 。
/* t1 = 0 , d1 = 1, t2 = 0, d2 = 0 */
cubic-bezier(0,1,0,0)
盒子几乎没有时间从A移到中点,其余时间到达B。
让我们尝试使用值t1 = 1
和d1 = 0
进行相同的转换。
/* t1 = 1 , d1 = 0, t2 = 0, d2 = 0 */
cubic-bezier(1,0,0,0)
在开始的三秒钟内,盒子移动不大,后来几乎跳到中点,并开始稳定地向B移动。
如您所见, d1
控制A与中点 之间的距离 ,而t1
控制从A到达中点所花费的时间 。
t1
和d1
1, t2 = 1
且d2 = 0
。
现在使用d2
和t2
。
/* t1 = 1 , d1 = 1, t2 = 0, d2 = 1 */
cubic-bezier(1,1,0,1)
盒子在3秒内几乎移动了一半(由于t1 = 1
, d1 = 1
),并且没有时间就跳到B点。
最后一个示例交换了先前的t2
和d2
值:
/* t1 = 1 , d1 = 1, t2 = 1, d2 = 0 */
cubic-bezier(1,1,1,0)
盒子在3秒内几乎移动了一半(由于t1 = 1
, d1 = 1
),然后d1 = 1
3秒在跳到B点之前移动不多。
这些示例表明, d2
和t2
控制框从中点到达B点的距离和时间。
现在,所有这些反弹在哪里出现?
尽管此时您可能不需要这么长的(但仍为稀疏的) cubic-bezier()
)解释,但我认为这将有助于您更好地理解此功能。
5.使用Cubic-Bezier()添加反弹效果
小于1的 d1
值会在动画开始时朝B前进之前在点A后面放置一个框。
弹跳效果的关键参数是距离d1
和d2
。
因此来回弹跳效果。
大于1的 d2
值会使框超出B点,然后在动画结束时回到B处。
现在,我将cubic-bezier()
值直接添加到我们的演示中,以代替之前的transition
属性的linear
值,并让您看到结果。
#pinStarCenterChkBox:checked ~ .pinStarLeaf{
transition: transform 1s cubic-bezier(.8,-.5,.2,1.4);
}
这是最终结果,具有反弹效果的纯CSS扇出动画:
为了进行比较并更好地了解弹跳效果,以下是当将动画的cubic-bezier()
值应用于示例框时的行为:
翻译自: https://www.hongkiat.com/blog/css3-fan-out-bounce-effect-animation/