在android webview上暂停/恢复svg动画

Posted

技术标签:

【中文标题】在android webview上暂停/恢复svg动画【英文标题】:pause/resume svg animation on android webview 【发布时间】:2021-03-07 00:25:08 【问题描述】:

我想使用 javascriptandroid WebView 上暂停/恢复 SVG 动画。

在 jsfiddle 上试过,但也没有工作 http://jsfiddle.net/ysbo5zdw/1/

/assets/svg/trial.html

    <!DOCTYPE html>
<html>
<head>
    <title>dynamic Image</title>
</head>

<body>

<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="cloudDrizzleSunFillAlt" class="climacon climacon_cloudDrizzleSunFillAlt" x="0px" y="0px"
     viewBox="15 15 70 70" enable-background="new 15 15 70 70" xmlns="http://www.w3.org/2000/svg">
    <style type="text/css">

        svg
            shape-rendering: geometricPrecision
        

        g, path, circle, rect
            -webkit-transform-origin: 50% 50%;
            -webkit-animation-iteration-count: infinite;
            -webkit-animation-timing-function: linear;
            -webkit-animation-duration: 12s;
            -webkit-animation-direction: normal;
            -moz-transform-origin: 50% 50%;
            -moz-animation-iteration-count: infinite;
            -moz-animation-timing-function: linear;
            -moz-animation-duration: 12s;
            -moz-animation-direction: normal;
            -o-transform-origin: 50% 50%;
            -o-animation-iteration-count: infinite;
            -o-animation-timing-function: linear;
            -o-animation-duration: 12s;
            -o-animation-direction: normal;
            transform-origin: 50% 50%;
            transform-box: fill-box;
            animation-iteration-count: infinite;
            animation-timing-function: linear;
            animation-duration: 12s;
            animation-direction: normal;
        

       .climacon_componentWrap-sun_cloud 

            -webkit-animation-name: behindCloudMove, rotate;
            -moz-animation-name: behindCloudMove, rotate;
            -o-animation-name: behindCloudMove, rotate;
            animation-name: behindCloudMove, rotate;

            -webkit-animation-iteration-count: 1, infinite;
            -moz-animation-iteration-count: 1, infinite;
            -o-animation-iteration-count: 1, infinite;
            animation-iteration-count: 1, infinite;

            -webkit-animation-timing-function: ease-out, linear;
            -moz-animation-timing-function: ease-out, linear;
            -o-animation-timing-function: ease-out, linear;
            animation-timing-function: ease-out, linear;

            -webkit-animation-delay: 0, 3s;
            -moz-animation-delay: 0, 3s;
            -o-animation-delay: 0, 3s;
            animation-delay: 0, 3s;

            -webkit-animation-duration: 3s, 12s;
            -moz-animation-duration: 3s, 12s;
            -o-animation-duration: 3s, 12s;
            animation-duration: 3s, 12s;

        

        .climacon_component-stroke_sunSpoke 
            fill-opacity: 0;
            -webkit-animation-name: fillOpacity, scale;
            -moz-animation-name: fillOpacity, scale;
            -o-animation-name: fillOpacity, scale;
            animation-name: fillOpacity, scale;

            -webkit-animation-direction: alternate;
            -moz-animation-direction: alternate;
            -o-animation-direction: alternate;
            animation-direction: alternate;

            -webkit-animation-iteration-count: 1, infinite;
            -moz-animation-iteration-count: 1, infinite;
            -o-animation-iteration-count: 1, infinite;
            animation-iteration-count: 1, infinite;

            -webkit-animation-delay: 3s, 0;
            -moz-animation-delay: 3s, 0;
            -o-animation-delay: 3s, 0;
            animation-delay: 3s, 0;

            -webkit-animation-duration: 3s;
            -moz-animation-duration: 3s;
            -o-animation-duration: 3s;
            animation-duration: 3s;

            -webkit-animation-fill-mode: both;
            -moz-animation-fill-mode: both;
            -o-animation-fill-mode: both;
            animation-fill-mode: both;

        

        .climacon_component-stroke_sunSpoke:nth-child(even) 
            -webkit-animation-delay: 3s;
            -moz-animation-delay: 3s;
            -o-animation-delay: 3s;
            animation-delay: 3s;

        


        .climacon_component-stroke_drizzle 
            fill-opacity: 0;

            -webkit-animation-name: drizzleFall, fillOpacity2;
            -moz-animation-name: drizzleFall, fillOpacity2;
            -o-animation-name: drizzleFall, fillOpacity2;
            animation-name: drizzleFall, fillOpacity2;

            -webkit-animation-timing-function: ease-in;
            -moz-animation-timing-function: ease-in;
            -o-animation-timing-function: ease-in;
            animation-timing-function: ease-in;

            -webkit-animation-duration: 1s;
            -moz-animation-duration: 1s;
            -o-animation-duration: 1s;
            animation-duration: 1s;

        

        .climacon_component-stroke_drizzle:nth-child(1) 
            -webkit-animation-delay: 0s;
            -moz-animation-delay: 0s;
            -o-animation-delay: 0s;
            animation-delay: 0s;
        

        .climacon_component-stroke_drizzle:nth-child(2) 
            -webkit-animation-delay: 0.6s;
            -moz-animation-delay: 0.6s;
            -o-animation-delay: 0.6s;
            animation-delay: 0.6s;
        

        .climacon_component-stroke_drizzle:nth-child(3) 
            -webkit-animation-delay: 1.2s;
            -moz-animation-delay: 1.2s;
            -o-animation-delay: 1.2s;
            animation-delay: 1.2s;
        

           @-webkit-keyframes rotate
                0%
                    -webkit-transform: rotate(0);
                
                100%
                    -webkit-transform: rotate(360deg);
                
            


            @-moz-keyframes rotate
                0%
                    -moz-transform: rotate(0);
                
                100%
                    -moz-transform: rotate(360deg);
                
            


            @-o-keyframes rotate
                0%
                    -o-transform: rotate(0);
                
                100%
                    -o-transform: rotate(360deg);
                
            

            @keyframes rotate
                0%
                    transform: rotate(0);
                
                100%
                    transform: rotate(360deg);
                
            

            @-webkit-keyframes scale
                0%
                    -webkit-transform: scale(1,1)
                
                100%
                    -webkit-transform: scale(.5,.5)
                
            

            @-moz-keyframes scale
                0%
                    -moz-transform: scale(1,1)
                
                100%
                    -moz-transform: scale(.5,.5)
                
            

            @-o-keyframes scale
                0%
                    -o-transform: scale(1,1)
                
                100%
                    -o-transform: scale(.5,.5)
                
            

            @keyframes scale
                0%
                    transform: scale(1,1)
                
                100%
                    transform: scale(.5,.5)
                
            

            @-webkit-keyframes behindCloudMove 
              0% 
                -webkit-transform: translateX(-1.75px) translateY(1.75px);
              

              100% 
                -webkit-transform: translateX(0) translateY(0);
              
            

            @-moz-keyframes behindCloudMove 
              0% 
                -moz-transform: translateX(-1.75px) translateY(1.75px);
              

              100% 
                -moz-transform: translateX(0) translateY(0);
              
            


            @-o-keyframes behindCloudMove 
              0% 
                -o-transform: translateX(-1.75px) translateY(1.75px);
              

              100% 
                -o-transform: translateX(0) translateY(0);
              
            

            @keyframes behindCloudMove 
              0% 
                transform: translateX(-1.75px) translateY(1.75px);
              

              100% 
                transform: translateX(0) translateY(0);
              
            

       @-webkit-keyframes drizzleFall 
          0% 
            -webkit-transform: translateY(0);
          

          100% 
            -webkit-transform: translateY(21px);
          
        

        @-moz-keyframes drizzleFall 
          0% 
            -moz-transform: translateY(0);
          

          100% 
            -moz-transform: translateY(21px);
          
        

        @-o-keyframes drizzleFall 
          0% 
            -o-transform: translateY(0);
          

          100% 
            -o-transform: translateY(21px);
          
        

        @keyframes drizzleFall 
          0% 
            transform: translateY(0);
          

          100% 
            transform: translateY(21px);
          
        

        @-webkit-keyframes fillOpacity 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          100% 
            fill-opacity: 1;
            stroke-opacity: 1;
          
        

        @-moz-keyframes fillOpacity 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          100% 
            fill-opacity: 1;
            stroke-opacity: 1;
          
        

        @-o-keyframes fillOpacity 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          100% 
            fill-opacity: 1;
            stroke-opacity: 1;
          
        

        @keyframes fillOpacity 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          100% 
            fill-opacity: 1;
            stroke-opacity: 1;
          
        

        @-webkit-keyframes fillOpacity2 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          50% 
            fill-opacity: 1;
            stroke-opacity: 1;
          

          100% 
            fill-opacity: 0;
            stroke-opacity: 0;
          
        

        @-moz-keyframes fillOpacity2 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          50% 
            fill-opacity: 1;
            stroke-opacity: 1;
          

          100% 
            fill-opacity: 0;
            stroke-opacity: 0;
          
        

        @-o-keyframes fillOpacity2 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          50% 
            fill-opacity: 1;
            stroke-opacity: 1;
          

          100% 
            fill-opacity: 0;
            stroke-opacity: 0;
          
        

        @keyframes fillOpacity2 
          0% 
            fill-opacity: 0;
            stroke-opacity: 0;
          

          50% 
            fill-opacity: 1;
            stroke-opacity: 1;
          

          100% 
            fill-opacity: 0;
            stroke-opacity: 0;
          
        
    </style>
    <g class="climacon_iconWrap climacon_iconWrap-cloudDrizzleSunFillAlt" transform="matrix(1, 0, 0, 1, -8.226453, -0.543087)">
        <g class="climacon_componentWrap climacon_componentWrap-sun climacon_componentWrap-sun_cloud">
            <g class="climacon_componentWrap climacon_componentWrap_sunSpoke">
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M80.029,43.611h-3.998c-1.105,0-2-0.896-2-1.999s0.895-2,2-2h3.998c1.104,0,2,0.896,2,2S81.135,43.611,80.029,43.611z" style="fill: rgb(87, 248, 7);"/>
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M72.174,30.3c-0.781,0.781-2.049,0.781-2.828,0c-0.781-0.781-0.781-2.047,0-2.828l2.828-2.828c0.779-0.781,2.047-0.781,2.828,0c0.779,0.781,0.779,2.047,0,2.828L72.174,30.3z" style="fill: rgb(87, 248, 7);"/>
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M58.033,25.614c-1.105,0-2-0.896-2-2v-3.999c0-1.104,0.895-2,2-2c1.104,0,2,0.896,2,2v3.999C60.033,24.718,59.135,25.614,58.033,25.614z" style="fill: rgb(87, 248, 7);"/>
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M43.892,30.3l-2.827-2.828c-0.781-0.781-0.781-2.047,0-2.828c0.78-0.781,2.047-0.781,2.827,0l2.827,2.828c0.781,0.781,0.781,2.047,0,2.828C45.939,31.081,44.673,31.081,43.892,30.3z" style="fill: rgb(87, 248, 7);"/>
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M42.033,41.612c0,1.104-0.896,1.999-2,1.999h-4c-1.104,0-1.998-0.896-1.998-1.999s0.896-2,1.998-2h4C41.139,39.612,42.033,40.509,42.033,41.612z" style="fill: rgb(87, 248, 7);"/>
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M43.892,52.925c0.781-0.78,2.048-0.78,2.827,0c0.781,0.78,0.781,2.047,0,2.828l-2.827,2.827c-0.78,0.781-2.047,0.781-2.827,0c-0.781-0.78-0.781-2.047,0-2.827L43.892,52.925z" style="fill: rgb(87, 248, 7);"/>
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M58.033,57.61c1.104,0,2,0.895,2,1.999v4c0,1.104-0.896,2-2,2c-1.105,0-2-0.896-2-2v-4C56.033,58.505,56.928,57.61,58.033,57.61z" style="fill: rgb(87, 248, 7);"/>
                <path class="climacon_component climacon_component-stroke climacon_component-stroke_sunSpoke climacon_component-stroke_sunSpoke-north" d="M72.174,52.925l2.828,2.828c0.779,0.78,0.779,2.047,0,2.827c-0.781,0.781-2.049,0.781-2.828,0l-2.828-2.827c-0.781-0.781-0.781-2.048,0-2.828C70.125,52.144,71.391,52.144,72.174,52.925z" style="fill: rgb(87, 248, 7);"/>
            </g>
            <g class="climacon_wrapperComponent climacon_wrapperComponent-sunBody">
                <circle class="climacon_component climacon_component-stroke climacon_component-stroke_sunBody" cx="58.033" cy="41.612" r="11.999" style="fill: rgb(87, 248, 7);"/>
                <circle class="climacon_component climacon_component-fill climacon_component-fill_sunBody" fill="#FFFFFF" cx="58.033" cy="41.612" r="7.999"/>
            </g>
        </g>
        <g class="climacon_wrapperComponent climacon_wrapperComponent-drizzle">
            <path class="climacon_component climacon_component-stroke climacon_component-stroke_drizzle climacon_component-stroke_drizzle-left" id="Drizzle-Left_1_" d="M56.969,57.672l-2.121,2.121c-1.172,1.172-1.172,3.072,0,4.242c1.17,1.172,3.07,1.172,4.24,0c1.172-1.17,1.172-3.07,0-4.242L56.969,57.672z" style="fill: rgb(87, 248, 7);"/>
            <path class="climacon_component climacon_component-stroke climacon_component-stroke_drizzle climacon_component-stroke_drizzle-middle" d="M50.088,57.672l-2.119,2.121c-1.174,1.172-1.174,3.07,0,4.242c1.17,1.172,3.068,1.172,4.24,0s1.172-3.07,0-4.242L50.088,57.672z" style="fill: rgb(87, 248, 7);"/>
            <path class="climacon_component climacon_component-stroke climacon_component-stroke_drizzle climacon_component-stroke_drizzle-right" d="M43.033,57.672l-2.121,2.121c-1.172,1.172-1.172,3.07,0,4.242s3.07,1.172,4.244,0c1.172-1.172,1.172-3.07,0-4.242L43.033,57.672z" style="fill: rgb(87, 248, 7);"/>
        </g>
        <g class="climacon_componentWrap climacon_componentWrap_cloud">
            <path class="climacon_component climacon_component-stroke climacon_component-stroke_cloud" d="M43.945,65.639c-8.835,0-15.998-7.162-15.998-15.998c0-8.836,7.163-15.998,15.998-15.998c6.004,0,11.229,3.312,13.965,8.203c0.664-0.113,1.338-0.205,2.033-0.205c6.627,0,11.998,5.373,11.998,12c0,6.625-5.371,11.998-11.998,11.998C57.168,65.639,47.143,65.639,43.945,65.639z" style="fill: rgb(87, 248, 7);"/>
            <path class="climacon_component climacon_component-fill climacon_component-fill_cloud" d="M59.943,61.639c4.418,0,8-3.582,8-7.998c0-4.417-3.582-8-8-8c-1.601,0-3.082,0.481-4.334,1.291c-1.23-5.316-5.973-9.29-11.665-9.29c-6.626,0-11.998,5.372-11.998,11.999c0,6.626,5.372,11.998,11.998,11.998C47.562,61.639,56.924,61.639,59.943,61.639z" style="fill: rgb(255, 255, 255);"/>
        </g>
    </g>
    <script type="text/javascript">
function pauseAnim()
document.getElementById('cloudDrizzleSunFillAlt').pauseAnimations();

</script>
</svg>

</body>
</html>

MainActivity.java

svgWebView = (WebView) findViewById(R.id.svg_web_view);
svgWebView.setWebViewClient(new WebViewClient());
svgWebView.getSettings().setJavaScriptEnabled(true);
svgWebView.loadUrl("file:///android_asset/svg/trial.html");

        svgWebView.setOnTouchListener(new View.OnTouchListener() 
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) 
                svgWebView.loadUrl("javascript:pauseAnim();");
                return false;
            
        );

javascript 在 SVG 元素内,但无法正常工作。

根据 John Ktejik 回答 Can svg animations be suspended without loosing accumulative information? 但没有运气

我的问题是我不想更改 SVG 文件,因为我需要修改很多 SVG,这将是一项艰巨的任务。 我想使用 https://developer.mozilla.org/en-US/docs/Web/API/SVGSVGElement 上记录的 SVGroot.pauseAnimations() 之类的东西或任何解决方法

Pause an external SVG animation 的这个答案听起来很有效,但我不知道如何在 Android 中实现它!

【问题讨论】:

【参考方案1】:

我建议你放

不同css类中的动画开始/停止功能:

svg.animation-on * 
    animation-iteration-count: infinite;


svg.animation-off * 
    animation-iteration-count: 0;

从现有样式表中删除任何其他 animation-iteration-count 设置

使用javascript将适当的类animation-onanimation off设置为***&lt;svg&gt;节点

【讨论】:

以上是关于在android webview上暂停/恢复svg动画的主要内容,如果未能解决你的问题,请参考以下文章

.svg 文件作为 HTML 中的对象未显示在 Android WebVIew 中

Android webView 支持 svg 渲染

Android WebView:svg 或 webm 在 HTML 中的对象标记中时调用 shouldOverrideUrlLoading

如何在android的webview上播放音频?

Android - 恢复 Fragment WebView 状态以避免重新加载

当我的活动不可见时,如何在 Android WebView 中暂停 Flash 内容?