I am building SVG canvas program for making shapes and editing them.
I need to be able to display <rect />
using x, y, width, height attributes and I need to be able to use transform rotate on them. After using this rotate, I am kinda forced to use transform-origin attribute and it's value will be the center coordinates of this rectangle.
My struggle is when I want to select two of such a rectangles and rotate them around one origin point.
If I just give the transfer-origin the value of coordinates in between those two rectangles and start rotating, it of course jumps.
I know using css matrix instead of just transfer-origin and transform rotate and translate is just different notation, but it seems to be easier to work with them. However, I have this issue that I cannot achieve the same behavior by css matrix without using transfer-origin (which if am doing some calc I am including in the matrix), and getting this offset of when I rotate the object with he matrix and modify it's x, y, it goes different direction.
I know this question might be getting into very broad question but will give it a try: What approach would you use for this "transfer" or transformations, from rotating around its center into rotating around center between two shapes and that those two shapes will remain the same distance in between each other and same angle.
I also tried this with matrix using gl-matrix and d3-select
const selectedElement = select(`[id="${id}"]`);
const transformOriginX = centerOfElement.x;
const transformOriginY = centerOfElement.y;
// Suppose this is your new transform-origin
const newTransformOriginX = centerOrigin!.x;
const newTransformOriginY = centerOrigin!.y;
const angleInRadians = angleDegrees * (Math.PI / 180);
// Create identity matrix
let matrix = mat2d.create();
// Translate to the origin by the transform-origin point
let translateToOrigin = mat2d.fromTranslation(mat2d.create(), [
-transformOriginX,
-transformOriginY,
]);
matrix = mat2d.multiply(matrix, matrix, translateToOrigin);
// Apply rotation transformation
let rotationMatrix = mat2d.fromRotation(mat2d.create(), angleInRadians);
matrix = mat2d.multiply(matrix, matrix, rotationMatrix);
// Translate back to its original location by the transform-origin point
let translateBack = mat2d.fromTranslation(mat2d.create(), [
transformOriginX,
transformOriginY,
]);
matrix = mat2d.multiply(matrix, matrix, translateBack);
// Now, counteract the effect of the new transform-origin
let translateDiff = mat2d.fromTranslation(mat2d.create(), [
transformOriginX - newTransformOriginX,
transformOriginY - newTransformOriginY,
]);
matrix = mat2d.multiply(matrix, matrix, translateDiff);
selectedElement.attr(
'transform',
`matrix(${matrix[0]}, ${matrix[1]}, ${matrix[2]}, ${matrix[3]}, ${matrix[4]}, ${matrix[5]})`,
);
For reasons related to my specific scenario, I cannot use SVG groups.
I tried to use only css matrix without transfer-origin and the translation was taken into consideration while calculating the matrix, but getting bad behavior when dragging rotated rectangle.
I tried keeping the transform-origin attribute as a center of each of those rectangles but it causes not easy calculation when transfering from one to another trasnform-origin.