how to keep text orientation unchanged during rotation in SVG

后端 未结 2 1242
悲&欢浪女
悲&欢浪女 2020-12-07 02:45

I am using in svg to roate som circles and texts around a point at the same time, however, I want to k

相关标签:
2条回答
  • 2020-12-07 03:12

    Pure SVG

    1. Rotate the entire group of elements: triangle, spiral and colored circles with the letters
    <g id = "common"`>
     ....
    </g> 
    <animateTransform xlink:href="#common"
      attributeName="transform"
      type="rotate"
      begin="svg1.click"
      restart="whenNotActive"
      repeatCount="indefinite"
      dur="10s"
      values="
           0, 75.74, 74.91;
          -360, 75.74, 74.91"
      additive="sum" />   
    
    1. Inside is the second animation of the rotation of circles and letters.
    <animateTransform  attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive"
    repeatCount="indefinite" dur="10s"  
    values="
        0, 56.13, 106.87;
        360, 56.13, 106.87"
    additive="sum" /> 
    
    1. We find the coordinates of the center of rotation of the letters using the getBBox () JS method
    <script> 
      //Find the center of rotation of the letter A
      let bb = a1.getBBox();
    console.log(bb.x+bb.width/2); 
    console.log(bb.y+bb.height/2);
    </script> 
    

    The animation will start after clicking

    text {
      font-family:sans-serif;
      font-size:14px;
      font-weight:bold;
      fill:#6E6E6E;
      }
    <svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink" width="190px" height="190px" viewBox="0 0 150 150" version="1.1">
     <defs> 
      </defs>
      <g id="common">
      <g transform="translate(-27.970238,-63.089294)">
        <circle cx="102.9" cy="138.0" r="75" fill="#faa"/> 
        <path   d="m163.7 175.2-121.5 0 60.8-105.2z" fill="#fea"/>
       
       
              <!-- Spiral -->
        <path  d="m101.3 136.5c1.1 2-2.1 2.5-3.3 1.9-3.2-1.7-2.6-6.2-0.5-8.4 3.7-4.1 10.2-2.9 13.6 0.9 5 5.6 3.3 14.3-2.3 18.8-7.4 6-18.4 3.7-23.9-3.6-7-9.2-4.1-22.5 5-29.1 11-8 26.6-4.4 34.3 6.4 9 12.8 4.8 30.7-7.8 39.4-14.6 10-34.8 5.2-44.6-9.2-11.1-16.4-5.6-39 10.6-49.7 18.2-12.1 43.1-6 54.9 11.9 13.1 19.9 6.4 47.2-13.3 60.1" style="fill:none;stroke-width:1;stroke:#6E6E6E">
          
        </path>
        <g id="La">
        <circle cx="55.9" cy="108.0" r="12.9" fill="#efa"/>
            <text id="a1"  x="51" y="112">
              A  
            </text> 
               <!-- Animation of the rotation of the letter `A` -->
             <animateTransform  attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 56.13, 106.87;360, 56.13, 106.87" additive="sum" /> 
        </g>
        <g>
        <circle cx="153.7" cy="110.3" r="12.9" fill="#efa"/>
        <text id="b1" xml:space="preserve" x="114" y="116" >
            B
        </text> 
            <!-- Animation of the rotation of the letter `B` -->
           <animateTransform  attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 153.7, 110.3;360, 153.7, 110.3" additive="sum" /> 
      </g> 
      <g>
      <circle cx="105.2" cy="192.5" r="12.9" fill="#efa"   />
        <text id="c1" x="100" y="198"  >
        C
      </text> 
           <!-- Animation of the rotation of the letter `C`   -->
           <animateTransform  attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 104.93, 193.46;360, 104.93, 193.46" additive="sum" /> 
        </g>
       </g>  
      </g>  
          <!-- Animating the rotation of the entire shape   -->
       <animateTransform xlink:href="#common" attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 75.74, 74.91;-360, 75.74, 74.91" additive="sum" />   
    </svg> 
    <script> 
      //Find the center of rotation of the letter A
      let bb = a1.getBBox();
    console.log(bb.x+bb.width/2); 
    console.log(bb.y+bb.height/2);
    </script> 

    Example with adding animation of the ball movement in a spiral

    text {
      font-family:sans-serif;
      font-size:14px;
      font-weight:bold;
      fill:#6E6E6E;
      }
    <svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink" width="190px" height="190px" viewBox="0 0 150 150" version="1.1">
     <defs> 
      </defs>
      <g id="common">
      <g transform="translate(-27.970238,-63.089294)">
        <circle cx="102.9" cy="138.0" r="75" fill="#faa"/> 
        <path   d="m163.7 175.2-121.5 0 60.8-105.2z" fill="#fea"/>
       
           
       <path   d="m163.7 175.2-121.5 0 60.8-105.2z" fill="#fea"/>
          <!-- Spiral track (pink) -->
        <path id="track"  d="m101.3 136.5c1.1 2-2.1 2.5-3.3 1.9-3.2-1.7-2.6-6.2-0.5-8.4 3.7-4.1 10.2-2.9 13.6 0.9 5 5.6 3.3 14.3-2.3 18.8-7.4 6-18.4 3.7-23.9-3.6-7-9.2-4.1-22.5 5-29.1 11-8 26.6-4.4 34.3 6.4 9 12.8 4.8 30.7-7.8 39.4-14.6 10-34.8 5.2-44.6-9.2-11.1-16.4-5.6-39 10.6-49.7 18.2-12.1 43.1-6 54.9 11.9 13.1 19.9 6.4 47.2-13.3 60.1" style="fill:none;stroke-width:3;stroke:#FFAAAA"/>
              <!-- Spiral -->
        <path  stroke-dasharray="0,432" d="m101.3 136.5c1.1 2-2.1 2.5-3.3 1.9-3.2-1.7-2.6-6.2-0.5-8.4 3.7-4.1 10.2-2.9 13.6 0.9 5 5.6 3.3 14.3-2.3 18.8-7.4 6-18.4 3.7-23.9-3.6-7-9.2-4.1-22.5 5-29.1 11-8 26.6-4.4 34.3 6.4 9 12.8 4.8 30.7-7.8 39.4-14.6 10-34.8 5.2-44.6-9.2-11.1-16.4-5.6-39 10.6-49.7 18.2-12.1 43.1-6 54.9 11.9 13.1 19.9 6.4 47.2-13.3 60.1" style="fill:none;stroke-width:2;stroke:#6E6E6E">
           <!-- Spiral animation -->
         <animate attributeName="stroke-dasharray" begin="svg1.click" repeatCount="indefinite" restart="whenNotActive" dur="10s" values="0,432;432,0;0,432" fill="freeze" />
        </path> 
        <circle cx="0" cy="0" r="6" fill="#6E6E6E">
           <!-- Ball movement in a spiral clockwise -->
        <animateMotion id="forwards"
          begin="svg1.click;back.end"
          dur="5s" >
          <mpath xlink:href="#track" />
        </animateMotion> 
           <!-- Ball movement in a spiral counterclockwise -->
          <animateMotion
               id="back"
               dur="5s"
               begin="forwards.end"
               repeatCount="1"
               keyPoints="1;0"
               keyTimes="0;1"
               calcMode="linear"
               rotate="auto"
               fill="freeze" > 
        <mpath xlink:href="#track" />
        </animateMotion> 
       </circle>    
        
        <g id="La">
        <circle cx="55.9" cy="108.0" r="12.9" fill="#efa"/>
            <text  x="51" y="112"> A  </text> 
             <animateTransform  attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 55.9, 108;360, 55.9, 108" additive="sum" /> 
        </g>
        <g>
        <circle cx="153.7" cy="110.3" r="12.9" fill="#efa"/>
        <text xml:space="preserve" x="114" y="116" >
            B
        </text> 
           <animateTransform  attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 153.7, 110.3;360, 153.7, 110.3" additive="sum" /> 
      </g> 
      <g>
      <circle cx="105.2" cy="192.5" r="12.9" fill="#efa"   />
        <text x="100" y="198"  > C
    </text> 
           <!-- Animation of the rotation of the letter `C`   -->
           <animateTransform  attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 105.2, 192.5;360, 105.2, 192.5" additive="sum" /> 
        </g>
       </g>  
      </g>  
          <!-- Animating the rotation of the entire shape   -->
       <animateTransform xlink:href="#common" attributeName="transform" type="rotate" begin="svg1.click" restart="whenNotActive" repeatCount="indefinite" dur="10s"  
            values="0, 75.38, 75;-360, 75.38, 75" additive="sum" />   
    </svg>

    0 讨论(0)
  • 2020-12-07 03:21

    Instead of rotation of <g>roup and reverse rotation of the text within it, try this alternate grouping. Center the <g> around origin(0,0) with negative x= and y= values & use rotate(degree, 0, 0) on circle_group, then translate(x,y) on the main_group.

    Edit: Here's an animated example, modified from this source. The trick is to move it around the origin with sin() and cos() trigonometric functions.

        <!DOCTYPE html>
        <html>
    
        <head>  
        <title>JavaScript SVG Animation</title>
        <meta http-equiv="X-UA-Compatible" content="IE=Edge"/> <!-- Remove this line in production. -->
        </head>
    
        <body>
        <svg width="800px" height="800px" viewBox="0 0 800 800">
        <g transform="translate(400, 400)"> <!-- Create a Cartesian coordinate system (with the y-axis flipped) for the animated square. That is, place the origin at the center of the 800 x 800 SVG viewport: -->
    
            <!-- A 200 x 200 square with the upper left-hand corner at (-100, -100). This places the center of the square 
            at the origin (0, 0): -->  
            <rect id="mySquare" x="-100" y="-100" width="200" height="200" rx="5" ry="5" 
                style=" fill: yellow; stroke: yellow; stroke-width: 1; stroke-dasharray: 10, 5;" />
                
            <!-- Represents the x-axis: -->
            <line x1="-400" y1="0" x2="400" y2="0" style="stroke: blue;" /> 
    
            <!-- Represents the y-axis (although up is negative and down is positive): -->  
            <line x1="0" y1="-400" x2="0" y2="400" style="stroke: blue;" /> 
            <circle cx="0" cy="0" r="141" fill="none" stroke="yellow"/>           
            <g id="circle_a">
              <circle cx="0" cy="0" r="10" fill="none" stroke="blue"/>
              <text x="-5" y="5" width="20" height="20">A</text>
            </g>
            <g id="circle_b">
               <circle cx="0" cy="0" r="10" fill="none" stroke="red"/>
                <text x="-5" y="5" width="20" height="20">B</text>
            </g>
        </g>
    
        </svg>
        <script>
        "use strict";
    
        /* CONSTANTS */
        var initialTheta = 0; // The initial rotation angle, in degrees.
        var thetaDelta = 0.3; // The amount to rotate the square about every 16.7 milliseconds, in degrees.
        var angularLimit = 180; // The maximum number of degrees to rotate the square.
        var theSquare = document.getElementById("mySquare");
        var circleA = document.getElementById("circle_a");
        var circleB = document.getElementById("circle_b");
    
        theSquare.currentTheta = initialTheta; // The initial rotation angle to use when the animation starts, stored in a custom property.
    
        var requestAnimationFrameID = requestAnimationFrame(doAnim); // Start the loop.
        function doAnim() {
          if (theSquare.currentTheta > angularLimit) {
            cancelAnimationFrame(requestAnimationFrameID); // The square has rotated enough, instruct the browser to stop calling the doAnim() function.
            return; // No point in continuing, bail now.
          }
    
          theSquare.setAttribute("transform", "rotate(" + theSquare.currentTheta + ")"); // Rotate the square by a small amount.
          circleA.setAttribute("transform", "translate(" +Math.cos((theSquare.currentTheta-45)*Math.PI/180)*141 + "," + Math.sin((theSquare.currentTheta-45)*Math.PI/180)*141+")"); // Move the circle A
          circleB.setAttribute("transform", "translate(" +Math.cos((theSquare.currentTheta+45)*Math.PI/180)*141 + "," + Math.sin((theSquare.currentTheta+45)*Math.PI/180)*141+")"); // move the circle B
          theSquare.currentTheta += thetaDelta;  // Increase the angle that the square will be rotated to, by a small amount.
          requestAnimationFrameID = requestAnimationFrame(doAnim); // Call the doAnim() function about 60 times per second (60 FPS), or about once every 16.7 milliseconds until cancelAnimationFrame() is called.
        }
        </script>

    0 讨论(0)
提交回复
热议问题