我对动画有点新意,所以请原谅我,如果我在这里错过了一个巨大的概念。我需要设置指向曲线上某个点的箭头的动画,让我们说这是一个立方曲线,为了这篇文章。箭头沿着曲线的线移动,始终指向它下方的几个像素。
所以我做的是,我使用CSS3在曲线的线上设置关键帧:
@-webkit-keyframes ftch {
0% {
opacity: 0;
left: -10px;
bottom: 12px;
}
25% {
opacity: 0.25;
left: 56.5px;
bottom: -7px;
}
50% {
opacity: 0.5;
left: 143px;
bottom: -20px;
}
75% {
opacity: 0.75;
left: 209.5px;
bottom: -24.5px;
}
100% {
opacity: 1;
left: 266px;
bottom: -26px;
}
}
但是,当我使用-webkit-animation-timing-function:ease-in运行这个动画时,它会将缓动应用于每个单独的关键帧,这绝对不是我想要的。我希望将缓动应用于整个动画。
我应该采取不同的方式吗?是否有一些属性可以将缓动应用于整个序列而不是每个关键帧?
答案 0 :(得分:17)
您无法在一系列关键帧上应用缓动函数,因为您专门告诉对象在特定时间位于特定点。如果你在一系列关键帧上应用了一个缓入,那么在25%时,对象就会在它后面需要“检查点”,最终加速直到达到100%。
如果您的积分或多或少等距,您可以申请:
.animatedobject {
-webkit-animation-timing-function: linear;
}
如果有点机器人,你的动画看起来会更不好。
更自然的方法是加速,保持速度,然后“刹车”:
@-webkit-keyframes ftch {
0% {
opacity: 0;
left: -10px;
bottom: 12px;
-webkit-animation-timing-function: ease-in;
}
25% {
opacity: 0.25;
left: 56.5px;
bottom: -7px;
-webkit-animation-timing-function: linear;
}
50% {
opacity: 0.5;
left: 143px;
bottom: -20px;
-webkit-animation-timing-function: linear;
}
75% {
opacity: 0.75;
left: 209.5px;
bottom: -24.5px;
-webkit-animation-timing-function: linear;
}
100% {
opacity: 1;
left: 266px;
bottom: -26px;
-webkit-animation-timing-function: ease-out;
}
}
如果webkit支持沿着路径的动画,则不需要这些关键帧,并且您可以毫不费力地将缓动应用于仅两个关键帧。
答案 1 :(得分:2)
当您希望将不同的缓动函数应用于动画的不同方面时,您应该通过将内容嵌套在两个div中来分离动画。
在这种情况下,您应创建一个父div以应用移动动画,并创建一个子div来应用不透明度动画。不透明度动画应该有一个缓动曲线:线性,并且运动动画应该具有最适合您的缓动函数。但是,我会重复Duopixel关于混合缓动曲线和固定检查点的说法 - 在这种情况下,您实际上不需要动画,只需要两个0%:100%动画 - 一个用于父级,一个用于子div。
完成了很多CSS3动画后,我为Sencha Animator产品写了this guide - 它有一些有用的一般信息,说明如何使用CSS3来制作复杂的动画 - 即使你不想使用工具。
答案 2 :(得分:1)
有些人喜欢你:http://www.w3.org/TR/css3-animations/
更具体地说:http://www.w3.org/TR/css3-animations/#timing-functions-for-keyframes-
您可能希望进行动画堆叠,例如移动到一个位置,然后移动到另一个位置,然后移动到多个关键帧动画中的另一个位置,而不只是一个。
答案 3 :(得分:0)
您不能使用 CSS Animations 来实现,但如果您不介意将其转换为 JavaScript,那么您可以can 改用 Web Animations API。
相当于这样的 CSS 动画:
.css-animation-ease {
animation-name: move-animation;
animation-duration: 3s;
}
@keyframes move-animation {
25% {
transform: translate(100px, 0);
}
50% {
transform: translate(100px, 100px);
background-color: green;
}
75% {
transform: translate(0, 100px);
}
100% {
transform: translate(0, 200px);
background-color: blue;
}
}
会是这个JS代码:
box.animate(
[
{ easing: "ease" },
{ transform: "translate(100px, 0)", offset: 0.25, easing: "ease" },
{ transform: "translate(100px, 100px)", backgroundColor: "green",
offset: 0.5, easing: "ease" },
{ transform: "translate(0, 100px)", offset: 0.75, easing: "ease" },
{ transform: "translate(0, 200px)", backgroundColor: "blue", easing: "ease" },
],
{ duration: 3000 }
);
但是,您不需要传递 offset
and easing
参数。如果您省略它们,则关键帧将均匀分布,您可以使用 easing
选项定义计时函数,该选项将应用于整个动画。
box.animate(
[
{},
{ transform: "translate(100px, 0)" },
{ transform: "translate(100px, 100px)", backgroundColor: "green" },
{ transform: "translate(0, 100px)" },
{ transform: "translate(0, 200px)", backgroundColor: "blue" },
],
{ duration: 3000, easing: "ease" }
);
这是比较这两种方法的示例(CSS 动画与 Web 动画 API)
document.getElementById("animateAll").addEventListener("click", () => {
for (const btn of document.querySelectorAll(".examples button")) {
btn.click();
}
});
document
.getElementById("cssAnimationLinearBtn")
.addEventListener("click", () => {
const box = document.getElementById("cssAnimationLinear");
box.classList.add("css-animation-linear");
box.addEventListener("animationend", () => {
box.classList.remove("css-animation-linear");
});
});
document.getElementById("cssAnimationEaseBtn").addEventListener("click", () => {
const box = document.getElementById("cssAnimationEase");
box.classList.add("css-animation-ease");
box.addEventListener("animationend", () => {
box.classList.remove("css-animation-ease");
});
});
document
.getElementById("webAnimationLinearBtn")
.addEventListener("click", () => {
const box = document.getElementById("webAnimationLinear");
box.animate(
[
{},
{ transform: "translate(100px, 0)" },
{ transform: "translate(100px, 100px)", backgroundColor: "green" },
{ transform: "translate(0, 100px)" },
{ transform: "translate(0, 200px)", backgroundColor: "blue" },
],
{ duration: 3000 }
);
});
document
.getElementById("webAnimationEaseOffsetBtn")
.addEventListener("click", () => {
const box = document.getElementById("webAnimationEaseOffset");
box.animate(
[
{ easing: "ease" },
{ transform: "translate(100px, 0)", offset: 0.25, easing: "ease" },
{
transform: "translate(100px, 100px)",
backgroundColor: "green",
offset: 0.5,
easing: "ease",
},
{ transform: "translate(0, 100px)", offset: 0.75, easing: "ease" },
{
transform: "translate(0, 200px)",
backgroundColor: "blue",
easing: "ease",
},
],
{ duration: 3000 }
);
});
document.getElementById("webAnimationEaseBtn").addEventListener("click", () => {
const box = document.getElementById("webAnimationEase");
box.animate(
[
{},
{ transform: "translate(100px, 0)" },
{ transform: "translate(100px, 100px)", backgroundColor: "green" },
{ transform: "translate(0, 100px)" },
{ transform: "translate(0, 200px)", backgroundColor: "blue" },
],
{ duration: 3000, easing: "ease" }
);
});
.examples {
display: grid;
grid-template-columns: repeat(5, 130px);
}
.box {
width: 30px;
height: 30px;
background-color: red;
}
.box.css-animation-linear {
animation: move-animation 3s linear 1;
}
.box.css-animation-ease {
animation-name: move-animation;
animation-duration: 3s;
}
@keyframes move-animation {
25% {
transform: translate(100px, 0);
}
50% {
transform: translate(100px, 100px);
background-color: green;
}
75% {
transform: translate(0, 100px);
}
100% {
transform: translate(0, 200px);
background-color: blue;
}
}
<button id="animateAll">Animate all</button>
<div class="examples">
<div>
<span style="color:brown">CSS Animation API (linear)</span>
<button id="cssAnimationLinearBtn">Animate</button>
<div id="cssAnimationLinear" class="box"></div>
</div>
<div>
<span style="color:green">CSS Animation API (ease)</span>
<button id="cssAnimationEaseBtn">Animate</button>
<div id="cssAnimationEase" class="box"></div>
</div>
<div>
<span style="color:brown">Web Animation API (linear)</span>
<button id="webAnimationLinearBtn">Animate</button>
<div id="webAnimationLinear" class="box"></div>
</div>
<div>
<span style="color:green">Web Animation API (ease, offset)</span>
<button id="webAnimationEaseOffsetBtn">Animate</button>
<div id="webAnimationEaseOffset" class="box"></div>
</div>
<div>
<strong>Web Animation API (ease)</strong>
<button id="webAnimationEaseBtn">Animate</button>
<div id="webAnimationEase" class="box"></div>
</div>
</div>