简体   繁体   中英

Set length of stroke-dasharray and dashoffset with javascript

I have the following animation with CSS:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304) -->
<!-- Title: G Pages: 1 -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="247pt" height="543pt" viewBox="0.00 0.00 246.86 543.19">
   <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 539.1859)">

<style>
#a1123 {
stroke-dasharray: 100.5;
stroke-dashoffset: 100.5;
animation: dash2 2s linear infinite;}
@keyframes dash2 {to {stroke-dashoffset: 0;}}
#a1124 {
stroke-dasharray: 100.5;
stroke-dashoffset: 100.5;
animation: dash2 2s linear infinite;}
@keyframes dash2 {to {stroke-dashoffset: 0;}}
</style>   
   <g id="node4" class="node">
         <title>c</title>
         <ellipse fill="none" stroke="#000000" cx="211" cy="-315.8894" rx="27" ry="18" />
         <text text-anchor="middle" x="211" y="-311.6894" font-family="font-awesome" font-size="14.00" fill="#000000">c</text>
      </g>
      <!-- 2&#45;&gt;c -->
      <g id="a1123" class="edge">
         <title>2-&gt;c</title>
         <path fill="none" stroke="#ff0000" stroke-width="3" d="M149.4218,-420.9789C160.4144,-409.9076 171.2176,-397.7063 180,-385.1859 188.9863,-372.3746 196.3054,-356.5405 201.5708,-343.2434" />
         <polygon fill="#ff0000" stroke="#ff0000" stroke-width="3" points="204.9306,-344.2533 205.1904,-333.6617 198.3823,-341.7795 204.9306,-344.2533" />
      </g>

      <!-- c&#45;&gt;e -->
      <g id="a1124" class="edge">
         <title>c-&gt;e</title>
         <path fill="none" stroke="#ff0000" stroke-width="3" d="M208.109,-297.8625C205.1217,-279.2357 200.2512,-248.8658 195.5911,-219.8076" />
         <polygon fill="#ff0000" stroke="#ff0000" stroke-width="3" points="198.9943,-218.9251 193.9549,-209.6055 192.0827,-220.0336 198.9943,-218.9251" />
      </g>
   </g>
</svg>

But the problem is that the attributes stroke-dasharray and stroke-dashoffset are set statically here. But I want to compute the length of every edge and set stroke-dasharray and stroke-dashoffset via javascript with the computed path length. How can I do that? I tried many things but it doesn't work.

UPDATE With the code @Alexandr_T has given, I have update my code and I am able to compute the length of the path. And I am getting the value, but setting the value via javascript does not create the animation like I have it in the first part of the code with CSS. There must be something I am doing. Here the code via javascript (I kept both codes in the question, so you can see the first code which I want to achieve, but via javascript and the second code which is the current status via javascript):

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304) -->
<!-- Title: G Pages: 1 -->
   <script>
         function TotalLength(){
          var path = document.querySelector('#check');
        var len = Math.round(path.getTotalLength() );
        path.style.strokeDasharray = len;
        path.style.strokeDashoffset = len;


        alert("Path length - " + len);
        };
  </script>
  <style>
#a1123 {
animation: dash2 2s linear infinite;}
@keyframes dash2 {to {stroke-dashoffset: 0;}}
#a1124 {
stroke-dasharray: 100.5;
stroke-dashoffset: 100.5;
animation: dash2 2s linear infinite;}
@keyframes dash2 {to {stroke-dashoffset: 0;}}
</style>
<body>
  <input  type="button" value="Total"  onclick="TotalLength()"/>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="247pt" height="543pt" viewBox="0.00 0.00 246.86 543.19">
   <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 539.1859)">

        <g id="node4" class="node">
             <title>c</title>
             <ellipse fill="none" stroke="#000000" cx="211" cy="-315.8894" rx="27" ry="18" />
             <text text-anchor="middle" x="211" y="-311.6894" font-family="font-awesome" font-size="14.00" fill="#000000">c</text>
        </g>
          <!-- 2&#45;&gt;c -->
        <g id="a1123" class="edge">
             <title>2-&gt;c</title>
             <path fill="none" stroke="#ff0000" stroke-width="3" d="M149.4218,-420.9789C160.4144,-409.9076 171.2176,-397.7063 180,-385.1859 188.9863,-372.3746 196.3054,-356.5405 201.5708,-343.2434" />
             <polygon fill="#ff0000" stroke="#ff0000" stroke-width="3" points="204.9306,-344.2533 205.1904,-333.6617 198.3823,-341.7795 204.9306,-344.2533" />
        </g>

          <!-- c&#45;&gt;e -->
        <g id="a1124" class="edge">
             <title>c-&gt;e</title>
             <path id="check" fill="none" stroke="#ff0000" stroke-width="3" d="M208.109,-297.8625C205.1217,-279.2357 200.2512,-248.8658 195.5911,-219.8076" />
             <polygon fill="#ff0000" stroke="#ff0000" stroke-width="3" points="198.9943,-218.9251 193.9549,-209.6055 192.0827,-220.0336 198.9943,-218.9251" />
        </g>
    </g>
</svg>

</body>

You can calculate the length of the path using the command JavaScript getTotalLength()

  `<script> function TotalLength(){ var path = document.querySelector('#check'); var len = Math.round(path.getTotalLength() ); alert("Path length - " + len); }; </script>` 

The resulting number will need to be used in stroke-dasharray and stroke-dashoffset

At the maximum value of stroke-dashoffset the line will be hidden,
with stroke-dashoffset = "0" the line will be drawn completely.

For the convenience of calculating the `stroke-dashoffset 'for each patch, I use this technique:

 <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <input type="button" value="Total" onclick="TotalLength()"/> <div> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500" viewBox="0 0 1000 1000" > <path id="check" transform="scale(1 1) rotate(0) translate(4 539.1859)" fill= "none" stroke ="red" stroke-width ="1" d="M208.109,-297.8625C205.1217,-279.2357 200.2512,-248.8658 195.5911,-219.8076" /> </svg> </div> <script> function TotalLength(){ var path = document.querySelector('#check'); var len = Math.round(path.getTotalLength() ); alert("Path length - " + len); }; </script> 

You can copy this file to your local computer and use it every time you need to calculate the length of the patch.

To do this, you need to take from your application the parameter "d" of your patch and insert it instead of the existing one in the file.

After changing the value of "d", press the Total

Update

The getTotalLength () method only supports the patch
To calculate the length of polygon in your application, make the polygon conversion into a patch

<polygon fill="#ff0000" stroke="#ff0000" stroke-width="3" points="204.9306,-344.2533 205.1904,-333.6617 198.3823,-341.7795 204.9306,-344.2533" /> 

 <path d="M204.9306,-344.2533 205.1904,-333.6617 198.3823,-341.7795 204.9306,-344.2533"/>

New answer for questions and answers in the comments

I do not know what kind of animation you want to get in the end.

But if you are satisfied with the successive animation of drawing arrows, triangles, then I can suggest the following option.

I converted in your code polygon --> path
I learned using the method getTotalLength () length of all patches:

#firstLine - 90.4px #firstTriangle - 29px #secondLine - 79px #secondTriangle - 28px

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <!-- Generated by graphviz version 2.40.1 (20161225.0304) --> <!-- Title: G Pages: 1 --> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="247pt" height="543pt" viewBox="0.00 100 246.86 543.19"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 539.1859)"> <style> #firstLine { stroke-dasharray: 90.4; stroke-dashoffset: 90.4; animation: dash1 2s linear forwards;} @keyframes dash1 {to {stroke-dashoffset: 0;}} #firstTriangle { stroke-dasharray: 29; stroke-dashoffset: 29; animation: dash2 1s linear 2s forwards;} @keyframes dash2 {to {stroke-dashoffset: 0;}} #secondLine { stroke-dasharray: 79; stroke-dashoffset: 79; animation: dash3 2s linear 3s forwards;} @keyframes dash3 {to {stroke-dashoffset: 0;}} #secondTriangle { stroke-dasharray: 28; stroke-dashoffset: 28; animation: dash3 1s linear 5s forwards;} @keyframes dash3 {to {stroke-dashoffset: 0;}} </style> <g id="node4" class="node"> <title>c</title> <ellipse fill="none" stroke="#000000" cx="211" cy="-315.8894" rx="27" ry="18" /> <text text-anchor="middle" x="211" y="-311.6894" font-family="serif" font-size="18" fill="#000000">c</text> </g> <!-- 2&#45;&gt;c --> <g id="a1123" class="edge"> <title>2-&gt;c</title> <path id="firstLine" fill="none" stroke="#ff0000" stroke-width="3" d="M149.4218,-420.9789C160.4144,-409.9076 171.2176,-397.7063 180,-385.1859 188.9863,-372.3746 196.3054,-356.5405 201.5708,-343.2434" /> <path id="firstTriangle" fill="none" transform="translate(-2 -3)" stroke="#ff0000" stroke-width="3" d="M204.9306,-344.2533 205.1904,-333.6617 198.3823,-341.7795 205.9306,-343.2533" /> </g> <!-- c&#45;&gt;e --> <g id="a1124" class="edge"> <title>c-&gt;e</title> <path id="secondLine" fill="none" stroke="#ff0000" stroke-width="3" d="M208.109,-297.8625C205.1217,-279.2357 200.2512,-248.8658 195.5911,-219.8076" /> <path id="secondTriangle" fill="none" stroke="#ff0000" stroke-width="3" d="M198.9943,-218.9251 193.9549,-209.6055 192.0827,-220.0336 198.9943,-218.9251" /> </g> </g> </svg> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM