101

I have following piece of code :

<svg>

<defs>
<rect id = "myRect"
      x = "10"
      y = "10"
      height = "120"
      width = "120"
      stroke-width = "2px"
      stroke = "red"
      fill = "blue" />

</defs>


<g transform = "translate(100,30)">
  <use xlink:href = "#myRect" />
</g>

<g transform = "translate(100, 100) rotate(45 ? ?)">

  <rect id = "myRect"
      x = "10"
      y = "10"
      height = "120"
      width = "120"
      stroke-width = "2px"
      stroke = "green"
      fill = "yellow" />
</g>

</svg>

When I translate rectangle without rotation, it is working fine. But when I rotate it, I wanted to rotate it around its center axis point. What should I need to pass to rotate attribute?

dsummersl
  • 6,588
  • 50
  • 65
Vinay Bagale
  • 2,361
  • 4
  • 36
  • 45

6 Answers6

136

You would have to set the center as the center of the filled element. Like this:

svg .rotate {
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(45deg);
}
bjoster
  • 1,665
  • 1
  • 12
  • 17
  • 29
    `transform-box: fill-box`: thanks for saving my day. – Rehmat Dec 15 '19 at 13:44
  • 1
    I got mine to work (a line in an SVG) with `transform-origin: 32px 40px; transform: rotate(45deg);`. I needed to remove `transform-box` and 32 is the center of the line in X and 40 is the bottom in y (it's a vertical line rotated from the bottom) – Justin May 03 '20 at 04:21
  • 2
    @vinay-bagale this should be the accepted answer ;) – lbrutti Oct 23 '20 at 10:14
  • 2
    "transform-box: fill-box" was what I've been missing. Thanks a lot! – user3107036 Nov 24 '20 at 16:30
  • 2
    Awesome. I often rotate animation with Image. SVG need this to rotate in right way. Thank you. – Phong Jan 08 '21 at 18:28
  • For me it worked after removing `transform-box`, but adding `transform-origin` – Justin Feb 12 '22 at 02:53
86

You just need to add half the width/height of the rectangle to get its centre.

<g transform = "translate(100, 100) rotate(45 60 60)">

See transform documentation of the rotate function for more information.

dsummersl
  • 6,588
  • 50
  • 65
Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • 24
    As a note, the syntax is `rotate(degree x y)`, so it is not "half width/height" if your rectangle is e.g. centered on 100x100 viewBox then it's trivially `rotate(45 50 50)`. – Ciantic Dec 31 '15 at 19:59
  • 10
    Just to add to this answer, you can apply the `transform` attribute directly to the `` element, you don't need to use a `` (group) if you only have one shape. I'm still new to the SVG standard, and this wasn't immediately obvious to me, maybe it'll save someone some time. – Illya Moskvin Feb 25 '17 at 16:28
  • 7
    Also, something that helped me, is if your svg says `viewBox="0 0 23 19"` then you must divide in half such as this: `transform="rotate(180 11.5 9.5)` to flip it upside down. – Rock Lee Aug 31 '18 at 17:17
38

The accepted answer works if you are drawing the rectangle starting at point (0,0) which was the OP case. However for me it was not!

Here is what worked for me:

  • To get the rectangle coordinates i used $('#rectID').getBBox() method, should return [rect-height , rect-width , rect-y , rect x ]
  • The center point is ( rect-x + (rect-width/2) , rect-y + (rect-height/2) )

Here is a snippet i used on the browser console:

var coord = $('#elemID')[0].getBBox();
coord.x + (coord.width/2) +' '+ coord.y + (coord.height/2)
marksyzm
  • 5,281
  • 2
  • 29
  • 27
Nimir
  • 5,727
  • 1
  • 26
  • 34
  • 21
    The OP doesn't even mention that this will be displayed in a browser, what does javascript have to do with anything? Let alone jQuery… – Nathan Hornby May 11 '17 at 13:41
8

origin
x = x + width / 2
y = y + height / 2
here
x is 10
y is 10
width is 120
height is 120

<g transform = "translate(100, 100) rotate(45 70 70)">
SUDHIR KUMAR
  • 381
  • 4
  • 10
1

I know this is an old post but if there are people out there who are looking make the values modifiable outside the group element

    const centerX=100;
    const centerY=100;
    const firstAngle=45;
    const secondAngle=60;
    const thirdAngle =60;
  
    <g transform ={`translate(${centerX}, ${centerY}) rotate(${firstAngle} ${secondAngle}, 
    ${thirdAngle})`}>
-16

Nothing you just need to write the following code with the element in javascript:

element.rotate(angle Degree);
perror
  • 7,071
  • 16
  • 58
  • 85