How to set transform origin in SVG
If you're like me and want to pan and then zoom with transform-origin, you'll need a little more.
// <g id="view"></g>
var view = document.getElementById("view");
var state = {
x: 0,
y: 0,
scale: 1
};
// Origin of transform, set to mouse position or pinch center
var oX = window.innerWidth/2;
var oY = window.innerHeight/2;
var changeScale = function (scale) {
// Limit the scale here if you want
// Zoom and pan transform-origin equivalent
var scaleD = scale / state.scale;
var currentX = state.x;
var currentY = state.y;
// The magic
var x = scaleD * (currentX - oX) + oX;
var y = scaleD * (currentY - oY) + oY;
state.scale = scale;
state.x = x;
state.y = y;
var transform = "matrix("+scale+",0,0,"+scale+","+x+","+y+")";
//var transform = "translate("+x+","+y+") scale("+scale+")"; //same
view.setAttributeNS(null, "transform", transform);
};
Here it is working: http://forresto.github.io/dataflow-prototyping/react/
To rotate use transform="rotate(deg, cx, cy)"
, where deg is the degree you want to rotate and (cx, cy) define the centre of rotation.
For scaling/resizing, you have to translate by (-cx, -cy), then scale and then translate back to (cx, cy). You can do this with a matrix transform:
transform="matrix(sx, 0, 0, sy, cx-sx*cx, cy-sy*cy)"
Where sx is the scaling factor in the x-axis, sy in the y-axis.
If you can use a fixed value (not "center" or "50%"), you can use CSS instead:
-moz-transform-origin: 25px 25px;
-ms-transform-origin: 25px 25px;
-o-transform-origin: 25px 25px;
-webkit-transform-origin: 25px 25px;
transform-origin: 25px 25px;
Some browsers (like Firefox) won't handle relative values correctly.
svg * {
transform-box: fill-box;
}
applying transform-box: fill-box
will make an element within an SVG behave as a normal HTML element. Then you can apply transform-origin: center
(or something else) as you would normally
that's right, transform-box: fill-box
. These days, there's no need for any complicated matrix stuff