首页 > 解决方案 > 如何通过在 svg 中开始一个新循环来停止以前的动画

问题描述

我有 6 个要设置动画的对象。动画在第一个圆圈加载页面后开始,并一个接一个地继续。关键是它应该在任何时候通过单击任何圆圈重新启动,应该从那个圆圈开始,并且应该在右边的下一个继续。问题是点击后,上一个循环不会停止并继续播放 - 上一个和新的。我应该在代码中添加什么以使其正常工作?

我尝试添加不同的“end”属性值,但没有一个起作用

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 640 480" enable-background="new 0 0 640 480" xml:space="preserve">

<defs>
  	<animate id="1p_anim" xlink:href="#_1p-circle" attributeName="stroke-dashoffset" begin="0s; click" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
	end="1p_anim.click; 2p_anim.click; 3p_anim.click"
 	/>
 	<animate id="2p_anim" xlink:href="#_2p-circle" attributeName="stroke-dashoffset" begin="1p_anim.end; click" values="600; 0" 
	restart="always"
 	dur="1s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
	end="1p_anim.click; 2p_anim.click; 3p_anim.click"
 	/>
 	<animate id="3p_anim" xlink:href="#_3p-circle" attributeName="stroke-dashoffset" begin="2p_anim.end; click" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
	end="1p_anim.click; 2p_anim.click; 3p_anim.click"
 	/>
 	<animate id="4p_anim" xlink:href="#_4p-circle" attributeName="stroke-dashoffset" begin="3p_anim.end; click" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
 	end="1p_anim.click; 2p_anim.click; 3p_anim.click"
	/>
 	<animate id="5p_anim" xlink:href="#_5p-circle" attributeName="stroke-dashoffset" begin="4p_anim.end; click" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
 	end="1p_anim.click; 2p_anim.click; 3p_anim.click"
	/>
 	<animate id="6p_anim" xlink:href="#_6p-circle" attributeName="stroke-dashoffset" begin="5p_anim.end; click" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
 	end="1p_anim.click; 2p_anim.click; 3p_anim.click"
	/>
</defs>
<g id="1p">
	<circle id="_1p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#fff" cx="103.5" cy="194.5" r="20"/>
</g>
<g id="2p">
	<circle id="_2p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="158.5" cy="194.5" r="20"/>
</g>
<g id="3p">
	<circle id="_3p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="210.5" cy="194.5" r="20"/>
</g>
<g id="4p">
	<circle id="_4p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="262.5" cy="194.5" r="20"/>
</g>
<g id="5p">
	<circle id="_5p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="314.5" cy="194.5" r="20"/>
</g>
<g id="6p">
	<circle id="_6p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="366.5" cy="194.5" r="20"/>
</g>
</svg>

标签: javascripthtmlcsssvg

解决方案


我认为这个用例对于标准动画功能来说有点太复杂了。

我建议只使用一点 Javascript。

var circleElements = document.querySelectorAll("svg circle");
var animateElements = document.querySelectorAll("svg animate");
var currentIndex = -1;
var timeoutHandle = null;

circleElements.forEach(function(elem, index) {
  // Add a click event listener to all the circles 
  elem.addEventListener("click", function(evt) {
    circleClick(index);
  });
});


function circleClick(index) {
  // A circle has been clicked on
  currentIndex = index;
  // Trigger the animation of this circle
  animateElements.item(currentIndex).beginElement();
  // Clear any timeout that is running
  clearTimeout(timeoutHandle);
  // Start a new timeout which, when it expires, will trigger the animation on the next circle
  timeoutHandle = setTimeout(function() {
    nextCircle();
  }, 1000);
}

function nextCircle() {
  // We have been called by a timeout.
  // Incement the index
  currentIndex++;
  if (currentIndex < animateElements.length) {
    // If we are not yet at the last circle, trigger the animation on the new circle
    animateElements.item(currentIndex).beginElement();
    // Start a timeout for the circle after this one.
    timeoutHandle = setTimeout(function() {
      nextCircle();
    }, 1000);
  }
}

// Start animating right away with the first circle
circleClick(0);
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 640 480" enable-background="new 0 0 640 480" xml:space="preserve">

<defs>
  	<animate id="1p_anim" xlink:href="#_1p-circle" attributeName="stroke-dashoffset" begin="indefinite" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
 	/>
 	<animate id="2p_anim" xlink:href="#_2p-circle" attributeName="stroke-dashoffset" begin="indefinite" values="600; 0" 
	restart="always"
 	dur="1s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
 	/>
 	<animate id="3p_anim" xlink:href="#_3p-circle" attributeName="stroke-dashoffset" begin="indefinite" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
 	/>
 	<animate id="4p_anim" xlink:href="#_4p-circle" attributeName="stroke-dashoffset" begin="indefinite" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
	/>
 	<animate id="5p_anim" xlink:href="#_5p-circle" attributeName="stroke-dashoffset" begin="indefinite" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
	/>
 	<animate id="6p_anim" xlink:href="#_6p-circle" attributeName="stroke-dashoffset" begin="indefinite" values="600; 0" 
	restart="always"
 	dur="2s" repeatCount="1"  
 	fill="remove"  
 	calcMode="linear" 
 	stroke-opacity="1"
	/>
</defs>
<g id="1p">
	<circle id="_1p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#fff" cx="103.5" cy="194.5" r="20"/>
</g>
<g id="2p">
	<circle id="_2p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="158.5" cy="194.5" r="20"/>
</g>
<g id="3p">
	<circle id="_3p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="210.5" cy="194.5" r="20"/>
</g>
<g id="4p">
	<circle id="_4p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="262.5" cy="194.5" r="20"/>
</g>
<g id="5p">
	<circle id="_5p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="314.5" cy="194.5" r="20"/>
</g>
<g id="6p">
	<circle id="_6p-circle" stroke-dasharray= "600" stroke-dashoffset="0" stroke="#000" fill="#FFFFFF" cx="366.5" cy="194.5" r="20"/>
</g>
</svg>


推荐阅读