按下“停止”按钮时如何停止动画并冻结图像
Posted
技术标签:
【中文标题】按下“停止”按钮时如何停止动画并冻结图像【英文标题】:How to stop the animation and freeze the image when pressing the `Stop` button 【发布时间】:2019-07-18 12:37:53 【问题描述】:我创建了工作行星齿轮的布局。
当您点击Stop
按钮时,齿轮旋转动画应该停止并且图像“冻结”。
但实际上图像会恢复到原来的状态。这可以在齿轮上的黄色标记上看到。
以下是我目前制作的代码:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink='http://www.w3.org/1999/xlink' viewBox="0 0 400 400" >
<title>animation planetary mechanism</title>
<defs>
<marker id="MarkerArrow" viewBox="0 0 20 20" refX="2" refY="5" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line1" x1="150" y1="100" x2="60" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow);
marker-start: url(#MarkerArrow);
stroke:#22211D; stroke-width:6; ">
</line>
<marker id="MarkerArrow-s" viewBox="0 0 20 20" refX="3" refY="1.7" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line-s" x1="175" y1="100" x2="202" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow-s1);
marker-start: url(#MarkerArrow-s);
stroke:#22211D; stroke-width:2; ">
</line>
<linearGradient id="vertical" x2="0%" y2="100%" spreadMethod="pad">
<stop offset="0%" stop-color="powderblue" />
<stop offset="100%" stop-color="lightgreen" />
</linearGradient>
</defs>
<rect fill="url(#vertical)" />
<g transform="translate(90,50)">
<g id="wheel">
<g>
<animateTransform attributeName="transform" type="rotate" from="0 100 100" to="360 100 100" begin="gO1.click" end="stop1.click" dur="14s" repeatCount="indefinite" />
<use xlink:href="#line1" transform="rotate(0 100 100)" />
<use xlink:href="#line1" transform="rotate(120 100 100)" />
<use xlink:href="#line1" transform="rotate(240 100 100)" />
<circle cx="100" cy="100" r="15" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="100" cy="100" r="50" style="stroke: #22211D; fill:none; stroke-width: 15px;" />
<circle cx="100" cy="100" r="60" style="stroke: #22211D; fill:none; stroke-dasharray: 5 6; stroke-width: 10px;" />
<circle cx="150" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g id="col-small">
<g>
<animateTransform attributeName="transform" type="rotate" from="0 188 100" to="-360 188 100" begin="gO1.click" end="stop1.click" dur="3.5s" repeatCount="indefinite" />
<use xlink:href="#line-s" transform="rotate(0 188 100)" />
<use xlink:href="#line-s" transform="rotate(120 188 100)" />
<use xlink:href="#line-s" transform="rotate(240 188 100)" />
<circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none; stroke-width: 7px;" />
<circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g id="planetar">
<g>
<animateTransform attributeName="transform" type="rotate" from="0 100 100" to="-360 100 100" begin="gO1.click" end="stop1.click" dur="28s" repeatCount="indefinite" />
<circle cx="100" cy="100" r="116" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="100" cy="100" r="124" style="stroke: #22211D; fill:none; stroke-width: 12px;" />
<circle cx="224" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g>
<use xlink:href="#col-small" transform="rotate(240 100 100)" />
<use xlink:href="#col-small" transform="rotate(120 100 100)" />
</g>
<g transform="translate(-10,160)">
<g id="gO1">
<rect x="45" y="85" rx="5" fill="#0080B8" stroke="dodgerblue" />
<text x="62" y="102" font-size="16" fill="yellow">GO</text>
</g>
<g id="stop1">
<rect x="110" y="85" rx="5" fill="crimson" stroke="red" />
<text x="120" y="102" font-size="16" fill="yellow">STOP</text>
</g>
</g>
</g>
</svg>
问题:
如何使当您单击Stop
按钮时图像停止在当前状态,并且下次按下GO
按钮时,动画不会从头开始,而是从锁定状态开始.
我做不到。如有任何解决方案,我将不胜感激。
【问题讨论】:
你可以找到CSS解决方案here 但是需要将动画从SMIL样式改为CSS样式 @Duannx 感谢您提供有用的链接。我以前试过这个,但没有用。请公布您的决定 这是我在Using SVG with CSS3 and html5: Vector Graphics for Web Design 中发现的:说到 SMIL 动画的局限性:“您不能轻易暂停正在处理的单个动画效果”。我的解释:你需要 javascript 来处理它。 @enxaneta 谢谢你,我读到了这本很棒的书。我希望能得到你出色的 JS 解决方案。 【参考方案1】:我对sn-p做了一些改动。请看一下,如果这是您想要的,请告诉我。
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink='http://www.w3.org/1999/xlink' viewBox="0 0 400 400" onload='Init(evt)' id = "SVGRoot">
<title>animation planetary mechanism</title>
<defs>
<marker id="MarkerArrow" viewBox="0 0 20 20" refX="2" refY="5" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line1" x1="150" y1="100" x2="60" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow);
marker-start: url(#MarkerArrow);
stroke:#22211D; stroke-width:6; ">
</line>
<marker id="MarkerArrow-s" viewBox="0 0 20 20" refX="3" refY="1.7" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line-s" x1="175" y1="100" x2="202" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow-s1);
marker-start: url(#MarkerArrow-s);
stroke:#22211D; stroke-width:2; ">
</line>
<linearGradient id="vertical" x2="0%" y2="100%" spreadMethod="pad">
<stop offset="0%" stop-color="powderblue" />
<stop offset="100%" stop-color="lightgreen" />
</linearGradient>
</defs>
<rect fill="url(#vertical)" />
<g transform="translate(90,50)">
<g id="wheel">
<g>
<animateTransform attributeName="transform" type="rotate" from="0 100 100" to="360 100 100" dur="14s" id = "innerCircle" begin="click" repeatCount="indefinite" />
<use xlink:href="#line1" transform="rotate(0 100 100)" />
<use xlink:href="#line1" transform="rotate(120 100 100)" />
<use xlink:href="#line1" transform="rotate(240 100 100)" />
<circle cx="100" cy="100" r="15" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="100" cy="100" r="50" style="stroke: #22211D; fill:none; stroke-width: 15px;" />
<circle cx="100" cy="100" r="60" style="stroke: #22211D; fill:none; stroke-dasharray: 5 6; stroke-width: 10px;" />
<circle cx="150" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g id="col-small">
<g>
<animateTransform attributeName="transform" type="rotate" from="0 188 100" to="-360 188 100" id = "smallerCircle" begin="click" dur="3.5s" repeatCount="indefinite" />
<use xlink:href="#line-s" transform="rotate(0 188 100)" />
<use xlink:href="#line-s" transform="rotate(120 188 100)" />
<use xlink:href="#line-s" transform="rotate(240 188 100)" />
<circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none; stroke-width: 7px;" />
<circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g id="planetar">
<g>
<animateTransform attributeName="transform" type="rotate" from="0 100 100" to="-360 100 100" id = "outerCircle" begin="click" dur="28s" repeatCount="indefinite" />
<circle cx="100" cy="100" r="116" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="100" cy="100" r="124" style="stroke: #22211D; fill:none; stroke-width: 12px;" />
<circle cx="224" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g>
<use xlink:href="#col-small" transform="rotate(240 100 100)" />
<use xlink:href="#col-small" transform="rotate(120 100 100)" />
</g>
<g transform="translate(-10,160)">
<g id="gO1" onclick='Play()'>
<rect x="45" y="85" rx="5" fill="#0080B8" stroke="dodgerblue" />
<text x="62" y="102" font-size="16" fill="yellow">GO</text>
</g>
<g id="stop1" onclick='Pause()'>
<rect x="110" y="85" rx="5" fill="crimson" stroke="red" />
<text x="120" y="102" font-size="16" fill="yellow">STOP</text>
</g>
</g>
</g>
</svg>
<script>
var SVGDocument = null;
var SVGRoot = null;
var pauseButton = null;
var playButton = null;
var innerCircle = null;
var outerCircle = null;
var smallerCircle = null;
function Init(evt)
SVGDocument = evt.target.ownerDocument;
SVGRoot = SVGDocument.getElementById('SVGRoot')
pauseButton = SVGDocument.getElementById('stop1');
playButton = SVGDocument.getElementById('gO1');
innerCircle = SVGDocument.getElementById('innerCircle');;
outerCircle = SVGDocument.getElementById('outerCircle');;
smallerCircle = SVGDocument.getElementById('smallerCircle');;
;
function Pause()
SVGRoot.pauseAnimations();
;
function Play()
if(SVGRoot.animationsPaused())
SVGRoot.unpauseAnimations();
else
innerCircle.beginElement();
outerCircle.beginElement();
smallerCircle.beginElement();
;
</script>
【讨论】:
对不起,但决定的条款是:“如何做到这一点,以便当您单击Stop
按钮时,图像会在当前状态下停止,并且下次您按下 GO
按钮,动画不是从头开始,而是从锁定状态开始"
乍一看,一切都很好,我很喜欢。我会研究你的决定
最好添加一些解释,而不是简单地说我已经编辑了..,这样我们就可以清楚地了解它是如何工作的,并可能链接到一些有用的资源
@Kumar Aman 谢谢。你的决定比其他人更适合我。所以它完全回答了我的问题。请添加 cmets 解释代码。
很棒的演示。不知道有animationsPaused
或者unpauseAnimations()这样的函数【参考方案2】:
这是一个使用 CSS 的技巧/hack。这个想法是依靠过渡来进行旋转,然后您使用持续时间来创建冻结的错觉。通过设置一个很大的值,您可以使过渡非常缓慢,因此它将为我们停止。
您必须调整每个车轮的转换/旋转值以获得所需的速度。您还需要使值足够大,以便用户永远不会到达过渡的末尾。
$('#gO1').click(function()
$('#wheel,#col-small,#planetar').addClass('rotate').removeClass('rotate-1');
)
$('#stop1').click(function()
$('#wheel,#col-small,#planetar').addClass('rotate-1').removeClass('rotate');
)
#wheel,
#col-small,
#planetar
transform-box:fill-box;
transform-origin:center;
#wheel.rotate
transform:rotate(36000deg);
transition:1400s linear;
#planetar.rotate
transform:rotate(-36000deg);
transition:2800s linear;
#col-small.rotate
transform:rotate(-36000deg);
transition:350s linear;
#wheel.rotate-1
transform:rotate(36001deg); /*we need a slight change to re-trigger the transition*/
transition:140000s linear;
#planetar.rotate-1
transform:rotate(-36001deg);
transition:280000s linear;
#col-small.rotate-1
transform:rotate(-36001deg);
transition:35000s linear;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink='http://www.w3.org/1999/xlink' viewBox="0 0 400 400" >
<title>animation planetary mechanism</title>
<defs>
<marker id="MarkerArrow" viewBox="0 0 20 20" refX="2" refY="5" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line1" x1="150" y1="100" x2="60" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow);
marker-start: url(#MarkerArrow);
stroke:#22211D; stroke-width:6; ">
</line>
<marker id="MarkerArrow-s" viewBox="0 0 20 20" refX="3" refY="1.7" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line-s" x1="175" y1="100" x2="202" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow-s1);
marker-start: url(#MarkerArrow-s);
stroke:#22211D; stroke-width:2; ">
</line>
<linearGradient id="vertical" x2="0%" y2="100%" spreadMethod="pad">
<stop offset="0%" stop-color="powderblue" />
<stop offset="100%" stop-color="lightgreen" />
</linearGradient>
</defs>
<rect fill="url(#vertical)" />
<g transform="translate(90,50)">
<g id="wheel">
<g>
<use xlink:href="#line1" transform="rotate(0 100 100)" />
<use xlink:href="#line1" transform="rotate(120 100 100)" />
<use xlink:href="#line1" transform="rotate(240 100 100)" />
<circle cx="100" cy="100" r="15" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="100" cy="100" r="50" style="stroke: #22211D; fill:none; stroke-width: 15px;" />
<circle cx="100" cy="100" r="60" style="stroke: #22211D; fill:none; stroke-dasharray: 5 6; stroke-width: 10px;" />
<circle cx="150" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g id="col-small">
<g>
<use xlink:href="#line-s" transform="rotate(0 188 100)" />
<use xlink:href="#line-s" transform="rotate(120 188 100)" />
<use xlink:href="#line-s" transform="rotate(240 188 100)" />
<circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none; stroke-width: 7px;" />
<circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g id="planetar">
<g>
<circle cx="100" cy="100" r="116" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="100" cy="100" r="124" style="stroke: #22211D; fill:none; stroke-width: 12px;" />
<circle cx="224" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g>
<use xlink:href="#col-small" transform="rotate(240 100 100)" />
<use xlink:href="#col-small" transform="rotate(120 100 100)" />
</g>
<g transform="translate(-10,160)">
<g id="gO1">
<rect x="45" y="85" rx="5" fill="#0080B8" stroke="dodgerblue" />
<text x="62" y="102" font-size="16" fill="yellow">GO</text>
</g>
<g id="stop1">
<rect x="110" y="85" rx="5" fill="crimson" stroke="red" />
<text x="120" y="102" font-size="16" fill="yellow">STOP</text>
</g>
</g>
</g>
</svg>
更新
上面的似乎只能在 chrome 上正常工作,所以这里另一个我必须复制小***的代码,所以它也可以在 Firefox 上正常工作:
$('#gO1').click(function()
$('#wheel,.col-small g,#planetar').addClass('rotate').removeClass('rotate-1');
)
$('#stop1').click(function()
$('#wheel,.col-small g,#planetar').addClass('rotate-1').removeClass('rotate');
)
#wheel,
.col-small g,
#planetar
transform-box:fill-box;
transform-origin:center;
#wheel.rotate
transform:rotate(36000deg); /*360 x 100*/
transition:1400s linear; /*14s x 100*/
#planetar.rotate
transform:rotate(-36000deg);
transition:2800s linear;
.col-small g.rotate
transform:rotate(-36000deg);
transition:350s linear;
#wheel.rotate-1
transform:rotate(36001deg); /*we need a slight change to re-trigger the transition*/
transition:140000s linear; /*14s x 100 x 100*/
#planetar.rotate-1
transform:rotate(-36001deg);
transition:280000s linear;
.col-small g.rotate-1
transform:rotate(-36001deg);
transition:35000s linear;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink='http://www.w3.org/1999/xlink' viewBox="0 0 400 400" >
<title>animation planetary mechanism</title>
<defs>
<marker id="MarkerArrow" viewBox="0 0 20 20" refX="2" refY="5" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line1" x1="150" y1="100" x2="60" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow);
marker-start: url(#MarkerArrow);
stroke:#22211D; stroke-width:6; ">
</line>
<marker id="MarkerArrow-s" viewBox="0 0 20 20" refX="3" refY="1.7" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
<rect rx="2" fill="#22211D" />
</marker>
<line id="line-s" x1="175" y1="100" x2="202" y2="100" style=" fill:none;
marker-end: url(#MarkerArrow-s1);
marker-start: url(#MarkerArrow-s);
stroke:#22211D; stroke-width:2; ">
</line>
<linearGradient id="vertical" x2="0%" y2="100%" spreadMethod="pad">
<stop offset="0%" stop-color="powderblue" />
<stop offset="100%" stop-color="lightgreen" />
</linearGradient>
</defs>
<rect fill="url(#vertical)" />
<g transform="translate(90,50)">
<g id="wheel">
<g>
<use xlink:href="#line1" transform="rotate(0 100 100)" />
<use xlink:href="#line1" transform="rotate(120 100 100)" />
<use xlink:href="#line1" transform="rotate(240 100 100)" />
<circle cx="100" cy="100" r="15" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="100" cy="100" r="50" style="stroke: #22211D; fill:none; stroke-width: 15px;" />
<circle cx="100" cy="100" r="60" style="stroke: #22211D; fill:none; stroke-dasharray: 5 6; stroke-width: 10px;" />
<circle cx="150" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g class="col-small">
<g>
<use xlink:href="#line-s" transform="rotate(0 188 100)" />
<use xlink:href="#line-s" transform="rotate(120 188 100)" />
<use xlink:href="#line-s" transform="rotate(240 188 100)" />
<circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none; stroke-width: 7px;" />
<circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g id="planetar">
<g>
<circle cx="100" cy="100" r="116" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="100" cy="100" r="124" style="stroke: #22211D; fill:none; stroke-width: 12px;" />
<circle cx="224" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g class="col-small" transform="rotate(240 100 100)">
<g>
<use xlink:href="#line-s" transform="rotate(0 188 100)" />
<use xlink:href="#line-s" transform="rotate(120 188 100)" />
<use xlink:href="#line-s" transform="rotate(240 188 100)" />
<circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none; stroke-width: 7px;" />
<circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g class="col-small" transform="rotate(120 100 100)">
<g>
<use xlink:href="#line-s" transform="rotate(0 188 100)" />
<use xlink:href="#line-s" transform="rotate(120 188 100)" />
<use xlink:href="#line-s" transform="rotate(240 188 100)" />
<circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none; stroke-width: 4px;" />
<circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none; stroke-width: 7px;" />
<circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" />
<circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
</g>
</g>
<g transform="translate(-10,160)">
<g id="gO1">
<rect x="45" y="85" rx="5" fill="#0080B8" stroke="dodgerblue" />
<text x="62" y="102" font-size="16" fill="yellow">GO</text>
</g>
<g id="stop1">
<rect x="110" y="85" rx="5" fill="crimson" stroke="red" />
<text x="120" y="102" font-size="16" fill="yellow">STOP</text>
</g>
</g>
</g>
</svg>
【讨论】:
不错的答案,但是您的 sn-p 中的 2 个齿轮不旋转 @souzan Firefox 我想? .. 总是忘记在那里测试,在 Chrome 上没问题 @Alexandr_T 是的,我没有花很多时间来修复同步,但这只是调整的问题,你需要找到正确的值来使用转换和旋转来增加/减少每次旋转的速度并获得所需的效果(如果我发现有时会编辑)。但是外观怎么破呢? @Alexandr_T 它已修复。我被轮换催眠了,甚至没有注意到这一点:p @Alexandr_T 没有问题,您必须选择一种最适合您的解决方案,如果不是我的,我很好;) SO 的目的是提供不同的答案,提供不同的方法未来的读者,如果他们好的话,他们都会在以后获得点赞奖励(所以请不要连续点赞我)【参考方案3】:这是我的解决方案,与@Duannx 解决方案非常相似。然而,当谈到齿轮时,我喜欢看到它们合适。 (没有重叠的牙齿)。所以我所做的是试图重新计算牙齿的大小。我希望你会喜欢它。
动画在单击 svg 画布时开始播放
c1r = 140;//the radius of the _c1 circle
c1perim = 2*Math.PI * c1r;// the perimeter of the _c1 circle
let sda = c1perim / 120;//sda = value for stroke-dasharray
// a css variable used to set the value for stroke-dasharray
cogs.style.setProperty("--foo", sda);
// the perimeter of _c2. This is the smaller circle used for the 3 identical cogs
c2perim = c1perim / Math.PI;
c2r = c1r/4; //the radius of the c2 circle
// the value of the cx attribute of the _c2
c2cx = 150 + c1r - c2r;// 150 = center.x of the cogs
//the radius of the 3-rd circle, the one in the middle
c3r = c1r - c2r*2
// setting attributes
c1.setAttributeNS(null,"r",(c1r + sda));
_c1.setAttributeNS(null,"r",c1r);
_c2.setAttributeNS(null,"cx",c2cx);
c2.setAttributeNS(null,"cx",c2cx);
_c2.setAttributeNS(null,"r",c2r);
c2.setAttributeNS(null,"r",(c2r-sda));
g2.style.transformOrigin=`$c2cxpx 150px`;
_c3.setAttributeNS(null,"r",c3r);
c3.setAttributeNS(null,"r",(c3r-sda));
//event listener to toggle the class animated of the svg element
cogs.addEventListener("click",()=>cogs.classList.toggle("animated"))
svg
width: 300px;
border: 1px solid;
circle
stroke-width: var(--foo);
fill: none;
g
transform-origin: 150px 150px;
animation: rotate 80s linear infinite;
stroke: black;
.animated ganimation-play-state: paused;
#g2
animation-duration:20s;
stroke:#444;
#g3
animation-duration:40s;
animation-direction: reverse;
[id ^="_"]
stroke-dasharray: var(--foo);
#_c2
stroke-dashoffset: var(--foo);
@keyframes rotate
to
transform: rotate(360deg);
<svg id="cogs" class="animated" viewBox="-20 -20 340 340">
<g id="g1">
<circle id="c1" cx="150" cy="150" r="" />
<circle id="_c1" cx="150" cy="150" r="" />
</g>
<g id="g2">
<circle id="c2" cx="" cy="150" r="" />
<circle id="_c2" cx="" cy="150" r="" />
</g>
<g id="g3">
<circle id="c3" cx="150" cy="150" r="" />
<circle id="_c3" cx="150" cy="150" r="" />
</g>
<use xlink:href="#g2" transform="rotate(120 150 150 )" />
<use xlink:href="#g2" transform="rotate(240 150 150 )" />
</svg>
【讨论】:
我有一个艰难的选择。一种解决方案比另一种更好。但是,不幸的是,我不能同时选择多个解决方案。真的齿轮传动看起来很棒。旋转齿轮时的齿彼此完美。高级别的代码实现。但不幸的是,另一种解决方案更适合我。【参考方案4】:这是我为模拟这个想法而创建的简单代码片段。你只需要
将 SMIL 样式更改为 CSS 样式(不要使用animateTransform
。使用 css transform
属性)。
点击按钮时切换animation-play-state
const runBtn = document.getElementById('runBtn')
const pauseBtn = document.getElementById('pauseBtn')
const circle = document.getElementById('circle')
runBtn.addEventListener('click', () =>
if (!circle.classList.contains('running'))
circle.classList.add('running')
)
pauseBtn.addEventListener('click', () =>
circle.classList.remove('running')
)
body
text-align: center;
#circle
animation: rotate 3s linear infinite;
transform-origin: 200px 200px;
animation-play-state: paused;
#circle.running
animation-play-state: running;
@keyframes rotate
0%
transform: rotateZ(0)
100%
transform: rotateZ(360deg)
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink='http://www.w3.org/1999/xlink' viewBox="0 0 400 400" id="rootSvg">
<g id="circle">
<circle cx="200" cy="200" r="100" stroke- stroke="black" fill="none"/>
<circle cx="200" cy="100" r="5" fill="yellow"/>
</g>
</svg><br>
<button id="runBtn">run</button>
<button id="pauseBtn">pause</button>
【讨论】:
尝试将您的决定转移到我的问题中的一个示例。 (+) @Alexandr_T 抱歉,我只能提供这个简单的示例,因为将您的问题示例转换为 css 样式需要时间。你应该自己做 @Alexandr_T 你基本上需要做的和我为过渡所做的一样......你将动画应用于每个元素,你调整原点和不同的值。以上是关于按下“停止”按钮时如何停止动画并冻结图像的主要内容,如果未能解决你的问题,请参考以下文章