如何停止CSS3的动画

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何停止CSS3的动画相关的知识,希望对你有一定的参考价值。

  们在移动端一般使用zepto框架,与其说zepto是jquery的轻量级替代版,不如说是html5替代版
  我们在js中会用到animate方法执行动画,这个家伙可是真资格的动画,完全是css一点点变化的!
  而zepto则不然,使用的是HTML5/CSS3的方案,而CSS相关是不保存元素状态值的,也没办法保存,所以停止动画就成了一大问题
  我们今天就一起来讨论下相关停止动画的方案,反正没有什么好的......

  CSS3动画原理

  在现有浏览器中,一般有两种模式(我只知道两种):
  一种是js动画,他是动态改写元素的style实现动画,所以任意时间想停止动画都是没问题的,因为我们可以获得各个阶段的状态值
  另一种就是CSS3动画了,至于CSS3动画的原理,我不知道但是可以说一点的就是——见代码

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4 <title></title>
  5 <script id="Script1" type="text/javascript" class="library" src="/js/sandbox/other/zepto.min.js"></script>
  6 </head>
  7 <body>
  8 <div id="Div1" style="background-color: Orange; width: 100px; height: 100px; position: absolute;
  9 left: 0; border: 1px solid black; ">
  10 </div>
  11 </body>
  12 <script src="../zepto.js" type="text/javascript"></script>
  13 <script type="text/javascript">
  14 var d = $('#d');
  15 d.animate(
  16 left: '100px'
  17 , 10000);
  18
  19 setTimeout(function ()
  20 d.html('left: ' + d.css('left'));
  21 , 1);
  22
  23 </script>
  24 </html>

  http://sandbox.runjs.cn/show/xziwuir2

  zepto的animate事实上马上就改变了style的值,所以我们在里面看到了left为100px,虽然他正在运动
  而他动画的实现事实上使用的是CSS3的transition动画属性,我们这里来看看zepto的源码:

  View Code
  最后实际上是执行anim实现我们的动画,大家注意看这里
  $(this).css(cssReset)
  this.css(cssValues)
  他事实上搞了个先设置动画属性,再给style属性给元素,所以会产生动画
  到此,zepto实现动画原理我们大概知道了,现在问题就是如何停止他了,所以我们继续往下看

  如何停止动画

  我们先看看这个东西:

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4 <title></title>
  5 <script id="Script2" type="text/javascript" class="library" src="/js/sandbox/other/zepto.min.js"></script>
  6 </head>
  7 <body>
  8 <div id="Div2" style="background-color: Orange; width: 100px; height: 100px; position: absolute;
  9 left: 0; border: 1px solid black;">
  10 </div>
  11 </body>
  12 <script src="../zepto.js" type="text/javascript"></script>
  13 <script type="text/javascript">
  14 var d = $('#d');
  15 d.animate(
  16 left: '100px'
  17 , 10000);
  18
  19 setInterval(function ()
  20 d.html('left: ' + d.css('left') + ' _ offsetLeft: ' + d[0].offsetLeft);
  21 , 1);
  22
  23 </script>
  24 </html>

  http://sandbox.runjs.cn/show/gdqezvdo

  其中虽然left一开始就变了,我们惊奇的发现,offset这个家伙居然保存了我们的状态!!!
  我和我的小伙伴都惊呆了,因为我之前一直以为什么状态都不能获得,于是我们为他加上mousedown事件,各位运动时候点击试试
  我们这里这样干了下:

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4 <title></title>
  5 <script id="Script3" type="text/javascript" class="library" src="/js/sandbox/other/zepto.min.js"></script>
  6 </head>
  7 <body>
  8 <div id="Div3" style="background-color: Orange; width: 100px; height: 100px; position: absolute;
  9 left: 0; border: 1px solid black;">
  10 </div>
  11 </body>
  12 <script src="../zepto.js" type="text/javascript"></script>
  13 <script type="text/javascript">
  14 var d = $('#d');
  15 d.animate(
  16 left: '100px'
  17 , 10000);
  18
  19 setInterval(function ()
  20 d.html('left: ' + d.css('left') + ' _ offsetLeft: ' + d[0].offsetLeft);
  21 , 1);
  22
  23 d.mousedown(function (e)
  24 console.log(d);
  25 d.css('transition', 'left 0s linear');
  26 d.css('left', d[0].offsetLeft + 'px');
  27 );
  28
  29 </script>
  30 </html>

  于是我们发现,动画停止了,亲!他真的停止了!!!
  PS:因为项目过程中,我这里要模仿类似iscroll的滚动效果,所以使用的最多的就是top或者translate3d(0, 0, 0)这种东西

  结语

  本来这里还想深入一点研究下的,但是现在时间有点来不及,事情有点多,暂时到这里了吧,具体的demo争取周末搞出来
参考技术A 首先请楼主看一个动画代码:(不是什么高大上的效果,只是简单的颜色变化)@-webkit-keyframes indexframe 0% background-color:#000000; color:#FFFFFF; 50% background-color:#FFFFFF; color:#000000; 100% background-color:#000000; color:#FFFFFF;#index_href -webkit-animation: indexframe 8s infinite; display:block; position:relative; top:400px; left:180px; width:200px; height:80px; border-radius:15px; text-align:center; line-height:80px; font-style:italic; font-size:24px; text-decoration:none; color:#FFFFFF; background-color:#000000; opacity:0.5;

为了方便,也就写了兼容chrome的css3样式,其他的换个前缀就好,在这里就不过多的说了。
2、为这个a(id=“index_href”)添加一个伪类:
这是原本准备添加的:
#index_href:hover background-color:#ffffff; color:#000000; opacity:0.5;

但是运行之后发现动画因为设置的是infinite //无限循环的效果

所以当需要触发伪类的效果时,动画还是会依然进行,这时候就需要停止之前的无限循环的动画了。
用css3的思路就是重新设置一个伪类的动画,把前面的动画给覆盖了。这样的话,我们就可以把伪类要改变的东西设置为动画效果,然后直接覆盖上去就行了。代码如下:
#index_href:hover -webkit-animation:indexend 0s; color:#000000; opacity:0.5;@-webkit-keyframes indexend 0% background:#000000; 100% background:#FFFFFF;

这里重新定义一个动画,命名为indexend,然后添加到hover伪类中去,设置动画的过渡时间为0s,这样可以达到瞬间变道动画的结束样式,以达到hover样式的直接改变。这样就成功的实现了之前动画的停止与后来样式的变化。
参考技术B 1、首先看看一个动画代码:(不是什么高大上的效果,只是简单的颜色变化)
@-webkit-keyframes indexframe 0% background-color:#000000; color:#FFFFFF; 50% background-color:#FFFFFF; color:#000000; 100% background-color:#000000; color:#FFFFFF; #index_href -webkit-animation: indexframe 8s infinite; display:block; position:relative; top:400px; left:180px; width:200px; height:80px; border-radius:15px; text-align:center; line-height:80px; font-style:italic; font-size:24px; text-decoration:none; color:#FFFFFF; background-color:#000000; opacity:0.5;
为了方便,也就写了兼容chrome的css3样式,其他的换个前缀就好,在这里就不过多的说了。
2、为这个a(id=“index_href”)添加一个伪类:
这是原本准备添加的:
#index_href:hover background-color:#ffffff; color:#000000; opacity:0.5;
但是运行之后发现动画因为设置的是
infinite //无限循环的效果
所以当需要触发伪类的效果时,动画还是会依然进行,这时候就需要停止之前的无限循环的动画了。
用css3的思路就是重新设置一个伪类的动画,把前面的动画给覆盖了。这样的话,我们就可以把伪类要改变的东西设置为动画效果,然后直接覆盖上去就行了。代码如下:
#index_href:hover -webkit-animation:indexend 0s; color:#000000; opacity:0.5; @-webkit-keyframes indexend 0% background:#000000; 100% background:#FFFFFF;
这里重新定义一个动画,命名为indexend,然后添加到hover伪类中去,设置动画的过渡时间为0s,这样可以达到瞬间变道动画的结束样式,以达到hover样式的直接改变。
这样就成功的实现了之前动画的停止与后来样式的变化。
参考技术C 用js改变动画元素的css
例如 将transtion 的时长设为0s

如何在路径上的特定位置停止 CSS 动画。没有时间

【中文标题】如何在路径上的特定位置停止 CSS 动画。没有时间【英文标题】:How to stop CSS Animation in Specific place on the Path. Without Timing 【发布时间】:2021-05-08 02:25:56 【问题描述】:

如何在 50% 处停止动画 2 秒然后恢复原路##

附注setInterval 方法不合适!!!!

            function pausee() 
                document.getElementById("0").style.animationPlayState = "paused";
            ;var myStop = setInterval(pausee, 2200);

            

            function Runn() 
                document.getElementById("0").style.animationPlayState = "running";
                ; var myContinue = setInterval(Runn, 2600);

@keyframes FourthBallStarting 0% 偏移距离:0%; 可见性:隐藏; 变换:rotateZ(0); 不透明度:0; 12.5% 偏移距离:3%; 不透明度:1.0; 能见度:可见; 50% 变换:scaleY(3); 90% 偏移距离:23%; 不透明度:1; 能见度:可见; 99%,100% 偏移距离:25%; 可见性:隐藏; 变换:rotateZ(-90deg); 不透明度:0; .ball 位置:绝对; 宽度:150 像素; 高度:150 像素; z-index: 1; 边框半径:50%; 边框:1px 纯黑色; 动画填充模式:转发; 偏移路径:路径(“M445 1.5C503.241 1.5 560.912 12.9715 614.72 35.2594C668.528 57.5474 717.419 90.2154 758.602 131.398C799.785 172.581 832.453 221.472 854.741 329.088 275.28C877.029 888.5 386.759 888.5 503.241 445C888.5 877.029 560.912 854.741 614.72C832。 453 668.528 799.785 717.419 758.602 799.785 758.602C717.419 668.528 832.453 614.72 854.741C560.912 877.029 503.241 888.5 445 888.5C386.759 888.5 329.088 877.028 275.28 854.741C221.472 832.453 172.581 799.785 131.398 717.419 758.602C90.2152 57.5473 668.528 35.2593 614.72C12.9714 560.912 1.49997 503.241 1.5 445C1.50003 386.759 12.9715 329.088 35.2595 275.28C57.5475 221.472 90.2155 172.581 131.398 131.398C172.581 90.2152 221.472 57.5473 275.28 35.2593C329.088 12.9714 386.759 1.49996 445 1.5L445 1.5Z“);结果 左边距:-70px;
            <div id="SpinningImages" class="SpinningImages">
            </div>
            <div id="BigCircle" >

            </div>


        </div>

`

            var x = document.createElement("IMG");

            x.setAttribute("src", imgArray[0].src);

            x.classList.add("ball");

            x.setAttribute("id", "0");

            x.setAttribute("style", "animation: FourthBallStarting 2s linear normal infinite;");

            x.setAttribute("alt", "Image");

            x.style.animationFillMode = "forwards";

            document.getElementById("SpinningImages").appendChild(x);

`

【问题讨论】:

你需要将它包含在你的关键帧中,这就是它们的用途。 将其构建到您的关键帧中 - 只需更改 %s 以便在某个 % (取决于整个运行的时间)上没有任何变化,直到另一个 % - 然后内置您的 2s 暂停而且你不必在运行时做任何事情。 谢谢它的工作原理!另外我想知道是否可以在路径上获得动画的确切位置? (百分比)由 JS 提供 【参考方案1】:

这有帮助吗?

var imgArray = new Array();

imgArray[0] = new Image();
imgArray[0].src = 'images/img/Splash_image1.jpg';

imgArray[1] = new Image();
imgArray[1].src = 'images/img/Splash_image2.jpg';

/* ... more images ... */

imgArray[5] = new Image();
imgArray[5].src = 'images/img/Splash_image6.jpg';

var x = document.createElement("IMG");

            x.setAttribute("src", imgArray[0].src);

            x.classList.add("ball");

            x.setAttribute("id", "0");

            x.setAttribute("style", "animation: FourthBallStarting 2s linear normal infinite;");

            x.setAttribute("alt", "Image");

            x.style.animationFillMode = "forwards";

            document.getElementById("SpinningImages").appendChild(x);
@keyframes FourthBallStarting 
0% 
offset-distance: 0%;
visibility: hidden;
transform: rotateZ(0);
opacity: 0;

12.5%
offset-distance: 3%;
opacity: 1.0;
visibility: visible;

15% 
offset-distance: 3%;
opacity: 1.0;
visibility: visible;
50% 
offset-distance: 3%;
opacity: 1.0;
visibility: visible;
80% 
transform: 0;

90% 
offset-distance: 23%;
opacity: 1;
visibility: visible;
 99%,100% 
offset-distance: 25%;
visibility: hidden;
transform: rotateZ(-90deg);
opacity: 0;


.ball 
position: absolute;
width: 50px;
height: 50px;
z-index: 1;
border-radius: 50%;
border: 1px solid black;
animation-fill-mode: forwards;
offset-path: path("M445 1.5C503.241 1.5 560.912 12.9715 614.72 35.2594C668.528 57.5474 717.419 90.2154 758.602 131.398C799.785 172.581 832.453 221.472 854.741 275.28C877.029 329.088 888.5 386.759 888.5 445C888.5 503.241 877.029 560.912 854.741 614.72C832.453 668.528 799.785 717.419 758.602 758.602C717.419 799.785 668.528 832.453 614.72 854.741C560.912 877.029 503.241 888.5 445 888.5C386.759 888.5 329.088 877.028 275.28 854.741C221.472 832.453 172.581 799.785 131.398 758.602C90.2152 717.419 57.5473 668.528 35.2593 614.72C12.9714 560.912 1.49997 503.241 1.5 445C1.50003 386.759 12.9715 329.088 35.2595 275.28C57.5475 221.472 90.2155 172.581 131.398 131.398C172.581 90.2152 221.472 57.5473 275.28 35.2593C329.088 12.9714 386.759 1.49996 445 1.5L445 1.5Z");
margin-left: -410px;


`
<div id="SpinningImages" class="SpinningImages">
            </div>
            <div id="BigCircle" >

            </div>

【讨论】:

是的,好主意!谢谢。另外我想知道是否可以在路径上获得动画的确切位置? (百分比)由 JS 提供

以上是关于如何停止CSS3的动画的主要内容,如果未能解决你的问题,请参考以下文章

如何停止requestAnimationFrame方法启动的动画

停止无限的 CSS3 动画并平滑恢复到初始状态

悬停时继续 CSS3 关键帧动画/悬停时停止重复

CSS3关于动画的问题,动画停止后让他的display等于none,再让他等于block就会出现动画重复问题。

如何使用JS停止CSS3里面的animation

CSS3动画与JS动画的优缺点?