SVG stroke-dashoffset不起作用

时间:2017-11-04 15:06:42

标签: javascript html css svg

我一直在使用stroke-dasharraystroke-dashoffset将SVG的路径设置为动画。用Js计算路径长度。下面我已经包含了一个JsFiddle,正好显示了我想要完成的任务。

我搜索过并搜索过,我遇到的很多例子都不适合我。在这一点上,我得出结论,我错过了一些东西,但我最终想知道那是什么。

<div>
  <svg x="0px" y="0px" width="312px" height="312px" viewBox="0 0 512 512">
    <g>
      <path class="pathOne" d="M320,128c52.562,0,95.375,42.438,96,94.813c-0.25,1.938-0.438,3.875-0.5,5.875l-0.812,23.5l22.25,7.75   C462.688,268.906,480,293.062,480,320c0,35.312-28.688,64-64,64H96c-35.281,0-64-28.688-64-64c0-34.938,28.188-63.438,63-64   c1.5,0.219,3.063,0.406,4.625,0.5l24.313,1.594l8-22.969C140.938,209.313,165.063,192,192,192c3.125,0,6.563,0.375,11.188,1.188   l22.406,4.031l11.156-19.844C253.875,146.938,285.75,128,320,128 M320,96c-47.938,0-89.219,26.688-111.156,65.688   C203.375,160.719,197.781,160,192,160c-41.938,0-77.219,27.063-90.281,64.563C99.813,224.438,97.969,224,96,224c-53,0-96,43-96,96   s43,96,96,96h320c53,0,96-43,96-96c0-41.938-27.062-77.25-64.562-90.313C447.5,227.75,448,225.938,448,224   C448,153.313,390.688,96,320,96L320,96z" fill="#333333"/>
    </g>
  </svg>
</div>

svg {
 position: fixed;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
}
path.pathOne {
  stroke-dasharray: 2566;
  stroke-dataoffset: 2566;
  animation: cloud 5s linear alternate infinite;
}
@keyframes cloud {
  from {
    stroke-dashoffset: 2566;
  }
  to {
    stroke-dashoffset: 0;
  }
}

https://jsfiddle.net/maisonm/9c3baxh5/

2 个答案:

答案 0 :(得分:1)

您的grafic不显示路径的笔划,而是显示没有笔划的填充路径。以下是您在svg编辑器Inkscape中可以看到的路径数据的说明: cloud path

这是你可以制作动画的路径。那是你想要的吗?在这种情况下,定义笔划并删除填充:

&#13;
&#13;
path.pathOne {
  fill: none;
  stroke: black;
  stroke-width: 3;
  stroke-dasharray: 2566;
  stroke-dataoffset: 2566;
  animation: cloud 5s linear alternate infinite;
}
@keyframes cloud {
  from {
    stroke-dashoffset: 2566;
  }
  to {
    stroke-dashoffset: 0;
  }
}
&#13;
  <svg x="0px" y="0px" width="250px" height="250px" viewBox="0 0 512 512">
<g>
  <path class="pathOne" d="M320,128c52.562,0,95.375,42.438,96,94.813c-0.25,1.938-0.438,3.875-0.5,5.875l-0.812,23.5l22.25,7.75   C462.688,268.906,480,293.062,480,320c0,35.312-28.688,64-64,64H96c-35.281,0-64-28.688-64-64c0-34.938,28.188-63.438,63-64   c1.5,0.219,3.063,0.406,4.625,0.5l24.313,1.594l8-22.969C140.938,209.313,165.063,192,192,192c3.125,0,6.563,0.375,11.188,1.188   l22.406,4.031l11.156-19.844C253.875,146.938,285.75,128,320,128 M320,96c-47.938,0-89.219,26.688-111.156,65.688   C203.375,160.719,197.781,160,192,160c-41.938,0-77.219,27.063-90.281,64.563C99.813,224.438,97.969,224,96,224c-53,0-96,43-96,96   s43,96,96,96h320c53,0,96-43,96-96c0-41.938-27.062-77.25-64.562-90.313C447.5,227.75,448,225.938,448,224   C448,153.313,390.688,96,320,96L320,96z" fill="#333333"/>
</g>
  </svg>
&#13;
&#13;
&#13;

请注意,两个子路径都是自己的虚线,导致产生两个动画的印象。但这不是正在发生的事情,只是破折号和偏移量分别应用于每个子路径。

由于路径长度是针对两个子路径的总和计算的,因此您会看到动画重复之前的时间延迟。

但也许你的目标是this

答案 1 :(得分:1)

手写解决方案

当SVG形状具有双向路径且路径之间的距离与方向改变点处的形状不同时,最好使用手写技术来动画绘制路径。
它的本质是为中间线设置动画,该中间线的宽度足以覆盖原始形状的最宽部分。

此中间线必须在矢量编辑器中绘制并保存为路径

enter image description here

接下来,通过绘制一条从最大值到零的线为该路径设置动画。将此元素添加到蒙版,然后将蒙版应用于云轮廓的原始形状。

<animate attributeName="stroke-dasharray"
  begin="svg1.click" dur="4s" values="1281,0;0,1281" fill="freeze" />

其中1281的最大中心线长度

动画蒙版的长度发生变化以显示云的原始轮廓。 同时,创造出具有不同宽度和形状的绘制线的幻觉。

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="312" height="312" viewBox="0 0 512 512" >
<defs>
 <mask id="msk"> 
     <rect width="100%" height="100%" fill="white" />
       <!-- middle line -->
    <path stroke="#111" stroke-dashoffset="700" stroke-width="45" fill="none" d="m262.3 400c56 0.2 111.3 0 168 0 14.8 0 28.2-10.8 39.1-20.7 9-8.2 15.8-19.2 19.9-30.7 5.2-14.5 9.1-31 5.4-46-4.8-19.1-18.9-35.5-33.7-48.3-7.8-6.7-24.3-4.1-27.6-13.8-5.7-16.5-1.3-35.8-7.7-52.2-7.1-18.4-17.9-36.4-33-49.1-18.4-15.4-42-27.5-66-29.1-24.1-1.7-49.5 6.8-69.8 19.9-16.9 10.9-21.1 35.5-39.1 46-12.4 6.2-27.9-0.8-41.4 2.3-13 3-26.9 6.5-36.8 15.3-13.2 11.7-14.3 25-26.1 46-3.1 5.6-12.9 0.2-19.2 1.5-15.4 3.2-31.9 5.9-44.5 15.3-15.3 11.5-27.7 28.5-33 46.8-4 14-4.3 30.7 2.3 43.7 12.1 24 35.3 50.8 62.1 51.4 65.1 1.5 120.7 1.3 181 1.5z">
      <!-- A mask animation with a wide line that reveals the outlines of the cloud -->
      <animate id="an" attributeName="stroke-dasharray" begin="svg1.click" dur="8s" values="1281,0;0,1281" fill="freeze" repeatCount="1" /> 
   
    </path>
 </mask>
</defs>
                <!-- Cloud contours -->
 <path mask="url(#msk)" fill="dodgerblue" class="pathOne" d="m320 128c52.6 0 95.4 42.4 96 94.8-0.2 1.9-0.4 3.9-0.5 5.9l-0.8 23.5 22.3 7.8C462.7 268.9 480 293.1 480 320c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64 0-34.9 28.2-63.4 63-64 1.5 0.2 3.1 0.4 4.6 0.5l24.3 1.6 8-23C140.9 209.3 165.1 192 192 192c3.1 0 6.6 0.4 11.2 1.2l22.4 4 11.2-19.8C253.9 146.9 285.8 128 320 128m0-32C272.1 96 230.8 122.7 208.8 161.7 203.4 160.7 197.8 160 192 160 150.1 160 114.8 187.1 101.7 224.6 99.8 224.4 98 224 96 224 43 224 0 267 0 320c0 53 43 96 96 96h320c53 0 96-43 96-96 0-41.9-27.1-77.2-64.6-90.3C447.5 227.8 448 225.9 448 224 448 153.3 390.7 96 320 96Z"/>
 
 <text x="200" y="300" font-size="36px" fill="dodgerblue" > Click me
   <animate id="op" attributeName="opacity" begin="an.end" dur="1s" values="1;0" fill="freeze" repeatCount="1" />
 </text>
</svg>

暂停2秒后具有重复动画的选项

为此,请在2秒钟的暂停后添加重新启动条件: begin="svg1.click;an.end+2s"

<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="312" height="312" viewBox="0 0 512 512" >
<defs>
 <mask id="msk"> 
     <rect width="100%" height="100%" fill="white" />
       <!-- middle line -->
    <path stroke="#111" stroke-dashoffset="700" stroke-width="45" fill="none" d="m262.3 400c56 0.2 111.3 0 168 0 14.8 0 28.2-10.8 39.1-20.7 9-8.2 15.8-19.2 19.9-30.7 5.2-14.5 9.1-31 5.4-46-4.8-19.1-18.9-35.5-33.7-48.3-7.8-6.7-24.3-4.1-27.6-13.8-5.7-16.5-1.3-35.8-7.7-52.2-7.1-18.4-17.9-36.4-33-49.1-18.4-15.4-42-27.5-66-29.1-24.1-1.7-49.5 6.8-69.8 19.9-16.9 10.9-21.1 35.5-39.1 46-12.4 6.2-27.9-0.8-41.4 2.3-13 3-26.9 6.5-36.8 15.3-13.2 11.7-14.3 25-26.1 46-3.1 5.6-12.9 0.2-19.2 1.5-15.4 3.2-31.9 5.9-44.5 15.3-15.3 11.5-27.7 28.5-33 46.8-4 14-4.3 30.7 2.3 43.7 12.1 24 35.3 50.8 62.1 51.4 65.1 1.5 120.7 1.3 181 1.5z">
      <!-- A mask animation with a wide line that reveals the outlines of the cloud -->
      <animate id="an" attributeName="stroke-dasharray" begin="svg1.click;an.end+2s" dur="6s" values="1281,0;0,1281" fill="freeze" />
    </path>
 </mask>
</defs>
                <!-- Cloud contours -->
 <path mask="url(#msk)" fill="dodgerblue" class="pathOne" d="m320 128c52.6 0 95.4 42.4 96 94.8-0.2 1.9-0.4 3.9-0.5 5.9l-0.8 23.5 22.3 7.8C462.7 268.9 480 293.1 480 320c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64 0-34.9 28.2-63.4 63-64 1.5 0.2 3.1 0.4 4.6 0.5l24.3 1.6 8-23C140.9 209.3 165.1 192 192 192c3.1 0 6.6 0.4 11.2 1.2l22.4 4 11.2-19.8C253.9 146.9 285.8 128 320 128m0-32C272.1 96 230.8 122.7 208.8 161.7 203.4 160.7 197.8 160 192 160 150.1 160 114.8 187.1 101.7 224.6 99.8 224.4 98 224 96 224 43 224 0 267 0 320c0 53 43 96 96 96h320c53 0 96-43 96-96 0-41.9-27.1-77.2-64.6-90.3C447.5 227.8 448 225.9 448 224 448 153.3 390.7 96 320 96Z"/>
 
 <text x="200" y="300" font-size="36px" fill="dodgerblue" > Click me 
    <animate id="op" attributeName="opacity" begin="6s" dur="1s" values="1;0" fill="freeze" />
 </text>
 
</svg>