0
votes

How do you apply path rotation to graphic elements such as a rectangle or a path?

For example, applying rotation to a path:

<svg width="200px" height="200px" viewbox="0 0 200 200">
  <rect x="100" y="0" width="20" height="20" fill="red" transform="rotate(45)"/>
</svg>

IMPORTANT NOTE:
I'm not running an browser. I remember seeing solutions that use browser or canvas to do the calculations.

I only have the markup. For a path I have the path data, for a rectangle the position and width and height, and the line the x1 y1 and x2 y2 data.

UPDATE:
It's important to know the transform origin. That would be rotated from the element center.

1
You are going to need lots of math here, basically recreating SVG rendering stack (parts of it). It might be simpler to use some headless browser to get access to browser-specific things (like SVG rendering; here is an example github.com/somebody32/generate-svg-on-the-server-with-js)alx

1 Answers

1
votes

I would use an array of points to draw the path. For the rotation I would rotate the points and draw the rotated shape.Please read the comments in my code. I hope this is what you were asking.

const SVG_NS = svg.namespaceURI;
// the rotation
let angle = Math.PI/4;
// the points used to rotate the initial rect
let theRect = [
  { x: 100, y: 0 },
  { x: 100 + 20, y: 0 },
  { x: 100 + 20, y: 0 + 20 },
  { x: 100, y: 0 + 20 }
];

// calculating the rotated points 
let rotatedRect = [];
theRect.forEach(p => {
  rotatedRect.push(rotatePoint(p, angle));
});


drawRect(theRect);
drawRect(rotatedRect);


// a function to draw the rect. For this I'm using the points array
function drawRect(ry) {
  let d = `M${ry[0].x},${ry[0].y}L${ry[1].x},${ry[1].y} ${ry[2].x},${ry[2].y} ${
  ry[3].x
  },${ry[3].y}`;
  drawSVGelmt({ d: d }, "path", svg);
}


// a function used to rotate a point around the origin {0,0}
function rotatePoint(p, rot) {
  let cos = Math.cos(rot);
  let sin = Math.sin(rot);
  return {
    x: p.x * cos - p.y * sin,
    y: p.x * sin + p.y * cos
  };
}


// a function to draw an svg element
function drawSVGelmt(o, tag, parent) {
  let elmt = document.createElementNS(SVG_NS, tag);
  for (let name in o) {
    if (o.hasOwnProperty(name)) {
      elmt.setAttributeNS(null, name, o[name]);
    }
  }
  parent.appendChild(elmt);
  return elmt;
}
svg{border:1px solid; max-width:90vh;}
<svg id="svg" viewbox="0 0 200 200">
  <rect x="100" y="0" width="20" height="20" fill="red" transform="rotate(45)"/>
</svg>