svg 圆圈颜色在某个点发生变化

时间:2021-05-13 03:01:57

标签: svg svg-animate svg-animationelements

我有一个圆形正在通过路径移动的 svg。我希望圆圈的颜色在某些点(例如路径的中间)发生变化

https://codepen.io/lzwdct/pen/poRYVXZ

<circle r="20" fill="blue" mask="url(#myMask)">
    <animateMotion dur="5s" repeatCount="indefinite"
      path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
            s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
            c-48.89-48.89-128.09-48.95-176.91-0.13" />
</circle>

请指导我如何更新颜色。颜色最终会随着路径长而多次改变。

2 个答案:

答案 0 :(得分:0)

我不确定 SVG 中是否有任何内容可以让您直接执行此操作。

但是您可以检查 currentTime 与 animateMotion 元素的持续时间,并基于此通过 javascript 设置颜色。

const color = (n) => {
  const R = Math.round((255 * n) / 100);
  const G = Math.round((255 * (100 - n)) / 100);
  const B = 0;
  return `rgb(${R}, ${G}, ${B})`;
};

const circles = document.querySelectorAll("circle");

window.setInterval(() => {
  circles.forEach(circle => {
    const ani = circle.querySelector('animateMotion');
    const duration = ani.getSimpleDuration();
    const currentTime = ani.getCurrentTime() % duration;
    const colorValue = color((currentTime / duration) * 100);
    circle.parentNode.style.fill = colorValue;
  });
}, 500);
circle {
  transition: 500ms;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 2549.62 3338.72" style="enable-background:new 0 0 2549.62 3338.72;" xml:space="preserve">
<style type="text/css">
    .st0{fill:none;stroke:#8EA5AE;stroke-width:50;stroke-miterlimit:10;}
    .st1{fill:none;stroke:#8EA5AE;stroke-width:50;stroke-linecap:round;stroke-miterlimit:10;}
    .st2{fill:none;stroke:#758992;stroke-width:50;stroke-miterlimit:10;}
    .st3{fill:none;stroke:#758992;stroke-width:50;stroke-linecap:round;stroke-miterlimit:10;}
    .st4{fill:none;stroke:#4E5F65;stroke-width:50;stroke-miterlimit:10;}
    .st5{fill:none;stroke:#4E5F65;stroke-width:50;stroke-linecap:round;stroke-miterlimit:10;}
</style>
<g>
  <mask id="myMask">
    <!--   Pixels under white are rendered   -->
    <rect x="0" y="0" width="1015" height="855" fill="white" />
    <!--   Pixels under black are hidden   -->
    <rect class="moveme" x="315" y="335" height="150" width="150" transform="rotate(45 395 395)">
      <animateTransform attributeName="transform"
                          attributeType="XML"
                          type="scale"
                          keyTimes="0; 0.25999; 0.26; 1"
                          values="1; 1; 0; 0"
                          dur="5s"
                          additive="sum"
                          repeatCount="indefinite"/>
    </rect>
  </mask>
    <g>
        <path class="st0" d="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
            s128.09-48.95,176.91-0.13" />
        <path class="st1" d="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07
            c29.29-29.29,76.78-29.29,106.07,0"/>
        <path class="st2" d="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
            s179.15-68.34,247.49,0"/>
      
    </g>
    <g>
        <path class="st0" d="M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
            c-48.89-48.89-128.09-48.95-176.91-0.13"/>
        <path class="st2" d="M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07
            s-76.78-29.29-106.07,0"/>
        <path class="st1" d="M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49
            s-179.15-68.34-247.49,0"/>
    </g>
</g>
  <g mask="url(#myMask)">
<circle r="20" mask="url(#myMask)">
    <animateMotion dur="5s" repeatCount="indefinite"
      path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
            s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
            c-48.89-48.89-128.09-48.95-176.91-0.13" />
</circle>
<circle r="20">
    <animateMotion dur="5s" repeatCount="indefinite"
      path="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
            s179.15-68.34,247.49,0 M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07 s-76.78-29.29-106.07,0" />
</circle>
<circle r="20">
    <animateMotion id="circle1" dur="5s" repeatCount="indefinite"
      path="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07 c29.29-29.29,76.78-29.29,106.07,0 M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49 s-179.15-68.34-247.49,0" /></circle></g>
</svg>

答案 1 :(得分:0)

您需要针对路径进行调整,基本概念是在要更改的元素上添加 animate 并使用 valueskeyTimes(整个动画为 0 到1)

您会注意到,您可以免费获得颜色渐变。
如果您不想这样,请添加更多 keyTimes 以便更快地发生颜色褪色

<svg width="450" height="180">
<path id="PATH" d="M 50 90 H400" stroke="black"/>
  <g>  
    <circle class="circle" r="30" fill="black"></circle>
    <circle class="circle" r=25 fill="red" >
      <animate 
         attributeName="fill"
         attributeType="XML"
         values="red;green;yellow;hotpink;blue"
         keyTimes= "0;0.4;0.6;0.8;1"
         dur="3s"
         repeatCount="indefinite"/>
    </circle>
    <animateMotion dur="3s" repeatCount="indefinite">
      <mpath href="#PATH" />
    </animateMotion>
  </g>       
</svg>