在android webview上暂停/恢复svg动画
Posted
技术标签:
【中文标题】在android webview上暂停/恢复svg动画【英文标题】:pause/resume svg animation on android webview 【发布时间】:2021-03-07 00:25:08 【问题描述】:我想使用 javascript 在 android 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-on
或animation off
设置为***<svg>
节点
【讨论】:
以上是关于在android webview上暂停/恢复svg动画的主要内容,如果未能解决你的问题,请参考以下文章
.svg 文件作为 HTML 中的对象未显示在 Android WebVIew 中
Android WebView:svg 或 webm 在 HTML 中的对象标记中时调用 shouldOverrideUrlLoading