Javascript 网络动画 API 或 CSS 动画关键帧?
Javascript Web Animations API or CSS Animation Keyframes?
我希望我的页面以一个简单的动画开始,介绍我可以做什么“嗨,我叫保罗,我制作网站”之类的。
为了实现它,我认为使用 Javascript 网络动画 API 将是一个很好的机会来立即展示我的原版 javascript 能力(我正在制作用于演示的部分我在框架和 WordPress 方面的能力),但是,在开始之后我注意到发生了一些奇怪的事情,可能是因为我没有正确使用它。
const fade = (a = 0, b = 1) => {
return [
{ opacity: a },
{ opacity: b }
];
}
const glideX = (a = '-10000px', b = '0px') => {
return [
{ marginLeft: a, position: 'absolute' },
{ display: 'block', offset:0.1 },
{ marginLeft: b, position: 'unset' }
];
}
const glideY = (a = '-10000px', b = '0px') => {
return [
{ marginTop: a, position: 'absolute' },
{ display: 'block', offset:0.1 },
{ marginTop: b, position: 'unset' }
];
}
const animateSettings = (dur = 1500, it = 1, fill = 'forwards', ease = 'ease-in-out') => {
return {
duration: 1500,
iterations: 1,
fill: 'forwards',
easing: 'ease-in-out'
};
}
const start = h1.animate( fade(), animateSettings() );
start.onfinish = () => {
myNameIs.style.display = 'block';
const nameIn = myNameIs.animate( glideX(), animateSettings() );
nameIn.onfinish = () => {
const welcomeGo = h1.animate ( glideY( '0px', '10000px' ), animateSettings() )
welcomeGo.onfinish = () => {
console.log('all done');
}
}
}
代码笔:https://codepen.io/makingstuffs/pen/xxKVoKK
我希望初始文本 Hi 淡入。
完成后,我希望我的名字是保罗从左边进来
完成后,我希望 Hi 掉落页面。
这是动画的开头三帧,我已经使用 onfinish event/promise。
但是,一个问题是最后一帧似乎也会影响前一帧的文本。
我想问一下这是否是我使用 API 的结果,或者这是 API 中的错误,我最好只使用 CSS 关键帧和链接事件侦听器,用于侦听每个转换完成,然后应用特定关键帧 class?
两者都适合在您的项目中使用。但是请注意,Web 动画 API 尚未(尚未)supported in Safari,因此它会在那里中断。
我在您的代码中注意到一些事情。
- 您正在使用边距更改元素的位置。尝试使用
transform
属性,因为它的动画性能更高,并且不会干扰文档流中的其他元素。我的猜测是这会导致元素之间的干扰。
- 您想在上一个动画完成后触发下一个动画,您可以使用
finish
事件来实现。虽然当动画持续时间是动态的时这是一个选项,但它似乎与您的情况无关。当触发后续动画时,您可以使用动画的 delay
属性。
你想要达到的目标
第一个动画必须立即开始,持续时间为 1500
毫秒。第二个动画必须在第一个动画完成后开始。只需添加 1500
毫秒的延迟,使其在第一个之后开始。
第三个动画必须在前两个动画完成后开始。这在开始时间延迟中总计 1500 * 2
毫秒。我认为这应该会让你更进一步。
在 CSS 中看起来像这样:
.el-one { animation: first-animation 1500ms forwards ease-in-out; }
.el-two { animation: second-animation 1500ms 1500ms forwards ease-in-out; }
.el-three { animation: third-animation 1500ms 3000ms forwards ease-in-out; }
在您的 JS 中,您必须创建 3 种不同的动画设置。您已经有一个函数可以让您控制动画属性,将其重写为:
const animateSettings = (delay = 0) => ({
delay: delay,
duration: 1500,
iterations: 1,
fill: 'forwards',
easing: 'ease-in-out'
});
const animationOne = elementOne.animate(yourFirstAnimation, animateSettings());
const animationTwo = elementTwo.animate(yourSecondAnimation, animateSettings(1500));
const animationThree = elementThree.animate(yourThirdAnimation, animateSettings(3000));
何时使用 Web 动画 API 或 CSS 关键帧?
这取决于您是否需要为动画计算。如果您不能在 CSS 中硬编码您的动画并且您需要计算从点 a 到点 b 的距离,请使用 Web动画 API 或持续时间、延迟或任何其他 属性 取决于用户的输入,请使用 API。
如果您已经知道点 a 和点 b 在像素、百分比等方面的位置,那么它更容易使用 CSS 关键帧。
为什么 CSS 变换?
变换对于拥有良好性能的动画是必不可少的。它们工作得很好,因为当一个元素被转换时,它永远不会离开流程,而只是元素的视觉表示被操纵。这可以防止每次移动元素时重新绘制整个页面,例如使用 margin
或 top
和 left
属性时发生的情况。 The chrome devtools have a tool to see what is going on with repaints.
结论
- 使用
transform
属性 来操作一个元素,它有更好的性能并且不会打乱你的流程。
- 延迟属性将为您提供开火能力
一个接一个的动画。
- 如果需要计算动画,请使用 Web Animations API,否则只需使用 CSS。
我希望我的页面以一个简单的动画开始,介绍我可以做什么“嗨,我叫保罗,我制作网站”之类的。
为了实现它,我认为使用 Javascript 网络动画 API 将是一个很好的机会来立即展示我的原版 javascript 能力(我正在制作用于演示的部分我在框架和 WordPress 方面的能力),但是,在开始之后我注意到发生了一些奇怪的事情,可能是因为我没有正确使用它。
const fade = (a = 0, b = 1) => {
return [
{ opacity: a },
{ opacity: b }
];
}
const glideX = (a = '-10000px', b = '0px') => {
return [
{ marginLeft: a, position: 'absolute' },
{ display: 'block', offset:0.1 },
{ marginLeft: b, position: 'unset' }
];
}
const glideY = (a = '-10000px', b = '0px') => {
return [
{ marginTop: a, position: 'absolute' },
{ display: 'block', offset:0.1 },
{ marginTop: b, position: 'unset' }
];
}
const animateSettings = (dur = 1500, it = 1, fill = 'forwards', ease = 'ease-in-out') => {
return {
duration: 1500,
iterations: 1,
fill: 'forwards',
easing: 'ease-in-out'
};
}
const start = h1.animate( fade(), animateSettings() );
start.onfinish = () => {
myNameIs.style.display = 'block';
const nameIn = myNameIs.animate( glideX(), animateSettings() );
nameIn.onfinish = () => {
const welcomeGo = h1.animate ( glideY( '0px', '10000px' ), animateSettings() )
welcomeGo.onfinish = () => {
console.log('all done');
}
}
}
代码笔:https://codepen.io/makingstuffs/pen/xxKVoKK
我希望初始文本 Hi 淡入。 完成后,我希望我的名字是保罗从左边进来 完成后,我希望 Hi 掉落页面。
这是动画的开头三帧,我已经使用 onfinish event/promise。
但是,一个问题是最后一帧似乎也会影响前一帧的文本。
我想问一下这是否是我使用 API 的结果,或者这是 API 中的错误,我最好只使用 CSS 关键帧和链接事件侦听器,用于侦听每个转换完成,然后应用特定关键帧 class?
两者都适合在您的项目中使用。但是请注意,Web 动画 API 尚未(尚未)supported in Safari,因此它会在那里中断。
我在您的代码中注意到一些事情。
- 您正在使用边距更改元素的位置。尝试使用
transform
属性,因为它的动画性能更高,并且不会干扰文档流中的其他元素。我的猜测是这会导致元素之间的干扰。 - 您想在上一个动画完成后触发下一个动画,您可以使用
finish
事件来实现。虽然当动画持续时间是动态的时这是一个选项,但它似乎与您的情况无关。当触发后续动画时,您可以使用动画的delay
属性。
你想要达到的目标
第一个动画必须立即开始,持续时间为 1500
毫秒。第二个动画必须在第一个动画完成后开始。只需添加 1500
毫秒的延迟,使其在第一个之后开始。
第三个动画必须在前两个动画完成后开始。这在开始时间延迟中总计 1500 * 2
毫秒。我认为这应该会让你更进一步。
在 CSS 中看起来像这样:
.el-one { animation: first-animation 1500ms forwards ease-in-out; }
.el-two { animation: second-animation 1500ms 1500ms forwards ease-in-out; }
.el-three { animation: third-animation 1500ms 3000ms forwards ease-in-out; }
在您的 JS 中,您必须创建 3 种不同的动画设置。您已经有一个函数可以让您控制动画属性,将其重写为:
const animateSettings = (delay = 0) => ({
delay: delay,
duration: 1500,
iterations: 1,
fill: 'forwards',
easing: 'ease-in-out'
});
const animationOne = elementOne.animate(yourFirstAnimation, animateSettings());
const animationTwo = elementTwo.animate(yourSecondAnimation, animateSettings(1500));
const animationThree = elementThree.animate(yourThirdAnimation, animateSettings(3000));
何时使用 Web 动画 API 或 CSS 关键帧?
这取决于您是否需要为动画计算。如果您不能在 CSS 中硬编码您的动画并且您需要计算从点 a 到点 b 的距离,请使用 Web动画 API 或持续时间、延迟或任何其他 属性 取决于用户的输入,请使用 API。
如果您已经知道点 a 和点 b 在像素、百分比等方面的位置,那么它更容易使用 CSS 关键帧。
为什么 CSS 变换?
变换对于拥有良好性能的动画是必不可少的。它们工作得很好,因为当一个元素被转换时,它永远不会离开流程,而只是元素的视觉表示被操纵。这可以防止每次移动元素时重新绘制整个页面,例如使用 margin
或 top
和 left
属性时发生的情况。 The chrome devtools have a tool to see what is going on with repaints.
结论
- 使用
transform
属性 来操作一个元素,它有更好的性能并且不会打乱你的流程。 - 延迟属性将为您提供开火能力 一个接一个的动画。
- 如果需要计算动画,请使用 Web Animations API,否则只需使用 CSS。