2

I'm looking to animate the rotation of individual dashes of an SVG stroke-dasharray, does anyone know how, given it is possible?

I realize I can rotate the entire object of SVG element with CSS' transform:rotate(), but is there any way I can rotate individual dashes? I also realize I could recreate it all using individual elements and rotate those, but that's not what I'm looking to do for performance and brevity reasons

Here's a demo if you're looking to have one. I'd like the squares to stay upright in their place, not rotating as they go around in a circular path. I'm looking to recreate this gif

P.S. I know the circles aren't perfectly aligned, I asked about that before

Community
  • 1
  • 1
Zach Saucier
  • 24,871
  • 12
  • 85
  • 147

2 Answers2

3

I made sample.

http://jsdo.it/defghi1977/sQOc

Robert Longson's "markers" approach is very nice! Thank you!

<?xml version="1.0" standalone="no"?>
<svg width="400px" height="400px" viewBox="-200 -200 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" style="background-color:black;">
<defs>
    <rect id="markerShape" x="-1" y="-1" width="2" height="2" fill="yellow">
        <animateTransform attributeName="transform" type="rotate" to="360,0,0" begin="0s" dur="30s" repeatCount="indefinite"/>
    </rect>

    <marker id="marker1" markerUnits="strokeWidth" viewBox="-1 -1 2 2" overflow="visible" markerWidth="1" markerHeight="1">
        <use xlink:href="#markerShape" transform="scale(0.02,0.02)"/><!--NOTE: =1/50-->
        <animate attributeName="orient" from="0" to="-30" begin="0s" dur="5s" repeatCount="indefinite"/>
    </marker>
    <marker id="marker2" markerUnits="strokeWidth" viewBox="-1 -1 2 2" overflow="visible" markerWidth="1" markerHeight="1">
        <use xlink:href="#markerShape" transform="scale(0.01428,0.01428)"/><!--NOTE: =1/70-->
        <animate attributeName="orient" from="0" to="-60" begin="0s" dur="5s" repeatCount="indefinite"/>
    </marker>
    <marker id="marker3" markerUnits="strokeWidth" viewBox="-1 -1 2 2" overflow="visible" markerWidth="1" markerHeight="1">
        <use xlink:href="#markerShape" transform="scale(0.01111,0.01111)"/><!--NOTE: =1/90-->
        <animate attributeName="orient" from="0" to="-90" begin="0s" dur="5s" repeatCount="indefinite"/>
    </marker>
    <marker id="marker4" markerUnits="strokeWidth" viewBox="-1 -1 2 2" overflow="visible" markerWidth="1" markerHeight="1">
        <use xlink:href="#markerShape" transform="scale(0.00909,0.00909)"/><!--NOTE: =1/110-->
        <animate attributeName="orient" from="0" to="-120" begin="0s" dur="5s" repeatCount="indefinite"/>
    </marker>
    <marker id="marker5" markerUnits="strokeWidth" viewBox="-1 -1 2 2" overflow="visible" markerWidth="1" markerHeight="1">
        <use xlink:href="#markerShape" transform="scale(0.007692,0.007692)"/><!--NOTE: =1/130-->
        <animate attributeName="orient" from="0" to="-150" begin="0s" dur="5s" repeatCount="indefinite"/>
    </marker>
    <marker id="marker6" markerUnits="strokeWidth" viewBox="-1 -1 2 2" overflow="visible" markerWidth="1" markerHeight="1">
        <use xlink:href="#markerShape" transform="scale(0.00666,0.00666)"/><!--NOTE: =1/150-->
        <animate attributeName="orient" from="0" to="-180" begin="0s" dur="5s" repeatCount="indefinite"/>
    </marker>
    <marker id="marker7" markerUnits="strokeWidth" viewBox="-1 -1 2 2" overflow="visible" markerWidth="1" markerHeight="1">
        <use xlink:href="#markerShape" transform="scale(0.00588,0.00588)"/><!--NOTE: =1/180-->
        <animate attributeName="orient" from="0" to="-210" begin="0s" dur="5s" repeatCount="indefinite"/>
    </marker>

    <polygon id="basicShape" fill="none" points="
        0,1
        0.5,0.86603
        0.86603,0.5
        1,0
        0.86603,-0.5
        0.5,-0.86603
        0,-1
        -0.5,-0.86603
        -0.86603,-0.5
        -1,0
        -0.86603,0.5
        -0.5,0.86603" 
    />
</defs>

<g>
    <use xlink:href="#basicShape" transform="scale(50,50)" stroke-width="14" marker-mid="url(#marker1)" marker-start="url(#marker1)"/>
    <animateTransform attributeName="transform" type="rotate" to="30,0,0" begin="0s" dur="5s" repeatCount="indefinite"/>
</g>
<g>
    <use xlink:href="#basicShape" transform="scale(70,70)" stroke-width="15" marker-mid="url(#marker2)" marker-start="url(#marker2)"/>
    <animateTransform attributeName="transform" type="rotate" to="60,0,0" begin="0s" dur="5s" repeatCount="indefinite"/>
</g>
    <g>
    <use xlink:href="#basicShape" transform="scale(90,90)" stroke-width="16" marker-mid="url(#marker3)" marker-start="url(#marker3)"/>
    <animateTransform attributeName="transform" type="rotate" to="90,0,0" begin="0s" dur="5s" repeatCount="indefinite"/>
</g>
<g>
    <use xlink:href="#basicShape" transform="scale(110,110)" stroke-width="17" marker-mid="url(#marker4)" marker-start="url(#marker4)"/>
    <animateTransform attributeName="transform" type="rotate" to="120,0,0" begin="0s" dur="5s" repeatCount="indefinite"/>
</g>
<g>
    <use xlink:href="#basicShape" transform="scale(130,130)" stroke-width="18" marker-mid="url(#marker5)" marker-start="url(#marker5)"/>
    <animateTransform attributeName="transform" type="rotate" to="150,0,0" begin="0s" dur="5s" repeatCount="indefinite"/>
</g>
<g>
    <use xlink:href="#basicShape" transform="scale(150,150)" stroke-width="19" marker-mid="url(#marker6)" marker-start="url(#marker6)"/>
    <animateTransform attributeName="transform" type="rotate" to="180,0,0" begin="0s" dur="5s" repeatCount="indefinite"/>
</g>
<g>
    <use xlink:href="#basicShape" transform="scale(170,170)" stroke-width="21" marker-mid="url(#marker7)" marker-start="url(#marker7)"/>
    <animateTransform attributeName="transform" type="rotate" to="210,0,0" begin="0s" dur="5s" repeatCount="indefinite"/>
</g>
</svg>
defghi1977
  • 5,081
  • 1
  • 30
  • 29
2

stroke-dasharray is the wrong approach as you can't affect the dash rotation.

A better approach would be to use square markers on a path such that each path vertex has a marker with a fixed orient attribute. The path itself could be transparent so just the markers are visible.

Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • Could you give an example of a circular path with square markers as you're describing? I'm afraid I am not used to the syntax – Zach Saucier Mar 01 '14 at 22:10
  • Yes, but how can I get multiple markers (as many as I show in the demo) around one circle path? It seems I can only have them at the `marker-start`, `marker-mid` and `marker-end` – Zach Saucier Mar 01 '14 at 22:24
  • Create a path where every vertex is where you want to put a marker. Use individual subpaths to form the circular shape rather than a single circle or arc path. – Robert Longson Mar 01 '14 at 22:27
  • That seems nearly as bad as just placing squares around in a circular path – Zach Saucier Mar 01 '14 at 22:28
  • Feel free to try both but you'll be telling me later that performance is much better my way. You get 10 paths with 1 marker that's 11 DOM elements my way, your way is 100+ DOM rect elements. If you're clever enough with the path construction 1 path and 1 marker would do. – Robert Longson Mar 01 '14 at 22:30