Search code examples
htmlcsssvgtransformscale

Scale an SVG element using a transform origin


<html lang="en-US">
  <head>
    <link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
  </head>
  
  <body>
    <iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"></iframe>
    
    <div class="wrp">  
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"
           width="100" height="100"
           class="canvas"
      > 
        <defs>   
          <style type="text/css"> 
            polygon { fill: none; stroke-width: 0.5; stroke: #f00; }
          </style>       
        </defs>
        
        <g transform="translate( 0 12.5 ) scale( 1 )">
        
          <polygon 
            points="
              75,6.7
              75,93.3
              0,50
            " 
            transform="rotate( -30 50 50 )"
          />
          
        </g>   
        
      </svg>
    </div>
    <script src="origin.js"></script>
  </body>
</html>

I want to make the red triangle in the snippet above scale larger while defining a specific transform origin. With the rotate attribute in SVG we can do this:

transform="rotate( -30 50 50 )"

The first value: -30 rotates element counter-clockwise. The 50 50 defines the transform origin ( x and y respectively ). Can I do this with scale?. I want my red triangle to scale up but keep it's origin centered.

Note: I know about transform-origin in CSS but I'm assuming the coordinate system that CSS uses will be relative to the whole web page or it's closest positioned element like it usually is... I want to define it in SVG coordinate terms like done with the rotate property.


Solution

  • You can translate --> scale --> translate_back e.g.

    <g transform="translate( 0 12.5 ) translate( 50 50) scale( 1.5 ) translate( -50 -50)">
    

    Explanation: Assuming you would like to use (50 50) as the scale origin, this will first translate your shape by (-50, -50) so that your desired scale origin will now be at (0, 0). Then you scale, and finally you reverse the translation to put the shape back where it were.