跨动态加载元素的连续动画
我需要有一个连续运行的 CSS @keyframe 动画跨元素,这些元素是通过 ajax/fetch 动态添加、销毁和替换的.
但是将动画绑定到动态添加的元素会使动画在每次替换元素时从 0% 重新开始.
部分解决方案是将动画绑定到不可变的父元素.然后动画将连续运行并影响任何子元素,即使它们被动态替换.
但这个解决方案的局限性在于我无法选择哪些动画由哪个子元素继承.
对于此代码:
HTML
CSS (SASS)
.parent动画:BY 15s 无限交替.child.two动画:RG 15s无限交替@keyframes BY0%颜色:蓝色100%颜色:黄色@keyframes RG0%红色100%颜色:绿色
只有.parent"中影响.child.one"文本的 BY 动画在.child.one"的任何动态替换中保持连续.而'.child.two'的动画每次动态替换时都会以0%重新开始.
这是一个说明此行为的代码笔:https://codepen.io/plagasul/pen/WNerBvO
我希望.child.one"和.child.two"有不同的动画,它们在这些元素的动态替换中都是连续的.
谢谢
解决方案这似乎是一个单独使用 CSS 可能无法解决的问题.如果我理解正确,您希望被另一个孩子替换的孩子的动画从上一个动画结束的地方开始.
您可以查看 网络动画 API.目前浏览器支持不是很好,但未来可能会变得更好.
但是,它确实具有您正在寻找的功能.正如 这篇 MDN 上的文章 中所引用的,可以使用 currentTime 动画的属性.
//就像使用 CSS 一样,我们使用关键帧来创建动画.常量关键帧 = [{颜色:蓝色"},{颜色:'黄色'}];//像在 CSS 中一样设置动画的时间属性.常量时间 = {持续时间:15000,方向:替代",迭代:无限,};//并将它们加在一起.const currentAnimation = document.querySelector('.child').animate(关键帧,时间);
这里的代码是 CSS 动画的 JavaScript 等价物.只要元素存在,.child
类的颜色就会改变,就像在 CSS 中一样.
在用新的孩子替换孩子之前,您需要知道动画在时间方面的位置.如前所述,通过访问 currentTime
属性来获取它.
//以毫秒为单位返回动画的时间位置.常量位置 = currentAnimation.currentTime;
所以现在你有了动画的位置.您可以使用它在新元素上设置动画的起点.就像这样:
//创建一个新动画const newAnimation = docum...//你懂的.//用上一个动画的位置更新 currentTime.newAnimation.currentTime = 位置;
新动画将从我们存储的位置开始.
您仍然需要将这些示例包装到函数中以在您的代码中使用它们,但我希望您能弄清楚这一点.如果 Web Animations API 不是您可以使用的东西,那么寻找具有更好支持的框架,例如 GreenSock 或AnimeJS.这篇文章还有一个不错的替代品列表.
希望这对您有所帮助,祝您有美好的一天!
I need to have a continuously running CSS @keyframe animation across elements that are dynamically added, destroyed and replaced via ajax/fetch.
But binding an animation to a dynamically added element makes the animation restart from 0% every time the element is replaced.
A partial solution is binding the animation to an unmutable parent element. The animation then will run continuously and affect any child elements, even if they are dynamically replaced.
But this solution is limited in that I cannot select which animations are inherited by which child element.
For this code:
HTML
<div class='parent'>
<div class='child one'>Some text</div>
<div class='child two'>Other text</div>
</div>
CSS (SASS)
.parent
animation: BY 15s infinite alternate
.child.two
animation: RG 15s infinite alternate
@keyframes BY
0%
color: blue
100%
color: yellow
@keyframes RG
0%
color: red
100%
color: green
Only the BY animation from '.parent' which affects '.child.one' text remains continous across any dynamic replacement of '.child.one'. While the animation of '.child.two' restarts at 0% every time it is dynamically replaced.
This is a codepen illustrating this behaviour: https://codepen.io/plagasul/pen/WNerBvO
I would like '.child.one' and '.child.two' to have different animations, that are both continuous across dynamic replacement of these elements.
Thank you
解决方案This seems like a problem that might not be solvable with CSS alone. If I understand correctly you want the animation, of the child that is replaced by another child, to start at the point where it the previous animation ended.
You could look into the Web Animations API. As of this moment browser support is not great, but might get better in the future.
It does, however, have the capabilities that you are looking for. As referenced in this article on MDN, it is possible to get the point in time of your animation where it should start from by using the currentTime property of an animation.
// Just like with CSS we use keyframes to create an animation.
const keyframes = [
{
color: 'blue'
},
{
color: 'yellow'
}
];
// Set the timing properties of the animation just like you have in CSS.
const timing = {
duration: 15000,
direction: 'alternate',
iterations: Infinity,
};
// And add it all together.
const currentAnimation = document.querySelector('.child').animate(keyframes, timing);
The code here is the JavaScript equivalent of CSS animations. The color of the .child
class will change for as long as the element exists, just like in CSS.
Before you replace a child with a new one you'll want to know where the animation is in terms of time. Get it by accessing the currentTime
property as mentioned before.
// Returns the position in time of the animation in milliseconds.
const position = currentAnimation.currentTime;
So now you have the position of the animation. You can use it to set the starting point of the animation on the new element. Just like this:
// Create a new animation
const newAnimation = docum... // You know the drill.
// Update the currentTime with the position of the previous animation.
newAnimation.currentTime = position;
The new animation will start on the position that we stored.
You still need to wrap these examples into functions to use them in your code, but I hope you can figure that out. If the Web Animations API is not something you could use then look for a framework with better support, like GreenSock or AnimeJS. This article also has a list of good alternatives.
Hope this helps and have a nice day!
相关文章