211 lines
6.0 KiB
TypeScript
211 lines
6.0 KiB
TypeScript
|
// Copyright: Ankitects Pty Ltd and contributors
|
||
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||
|
|
||
|
import type { fabric } from "fabric";
|
||
|
|
||
|
export const alignLeft = (canvas: fabric.canvas): void => {
|
||
|
if (!canvas.getActiveObject()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const activeObject = canvas.getActiveObject();
|
||
|
if (canvas.getActiveObject().type == "activeSelection") {
|
||
|
alignLeftGroup(canvas, activeObject);
|
||
|
} else {
|
||
|
activeObject.set({ left: 0 });
|
||
|
}
|
||
|
|
||
|
activeObject.setCoords();
|
||
|
canvas.renderAll();
|
||
|
};
|
||
|
|
||
|
export const alignHorizontalCenter = (canvas: fabric.Canvas): void => {
|
||
|
if (!canvas.getActiveObject()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const activeObject = canvas.getActiveObject();
|
||
|
if (canvas.getActiveObject().type == "activeSelection") {
|
||
|
alignHorizontalCenterGroup(canvas, activeObject);
|
||
|
} else {
|
||
|
activeObject.set({ left: canvas.width / 2 - activeObject.width / 2 });
|
||
|
}
|
||
|
|
||
|
activeObject.setCoords();
|
||
|
canvas.renderAll();
|
||
|
};
|
||
|
|
||
|
export const alignRight = (canvas: fabric.Canvas): void => {
|
||
|
if (!canvas.getActiveObject()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const activeObject = canvas.getActiveObject();
|
||
|
if (canvas.getActiveObject().type == "activeSelection") {
|
||
|
alignRightGroup(canvas, activeObject);
|
||
|
} else {
|
||
|
activeObject.set({ left: canvas.getWidth() - activeObject.width });
|
||
|
}
|
||
|
|
||
|
activeObject.setCoords();
|
||
|
canvas.renderAll();
|
||
|
};
|
||
|
|
||
|
export const alignTop = (canvas: fabric.Canvas): void => {
|
||
|
if (!canvas.getActiveObject()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const activeObject = canvas.getActiveObject();
|
||
|
if (canvas.getActiveObject().type == "activeSelection") {
|
||
|
alignTopGroup(canvas, activeObject);
|
||
|
} else {
|
||
|
activeObject.set({ top: 0 });
|
||
|
}
|
||
|
|
||
|
activeObject.setCoords();
|
||
|
canvas.renderAll();
|
||
|
};
|
||
|
|
||
|
export const alignVerticalCenter = (canvas: fabric.Canvas): void => {
|
||
|
if (!canvas.getActiveObject()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const activeObject = canvas.getActiveObject();
|
||
|
if (canvas.getActiveObject().type == "activeSelection") {
|
||
|
alignVerticalCenterGroup(canvas, activeObject);
|
||
|
} else {
|
||
|
activeObject.set({ top: canvas.getHeight() / 2 - activeObject.height / 2 });
|
||
|
}
|
||
|
|
||
|
activeObject.setCoords();
|
||
|
canvas.renderAll();
|
||
|
};
|
||
|
|
||
|
export const alignBottom = (canvas: fabric.Canvas): void => {
|
||
|
if (!canvas.getActiveObject()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const activeObject = canvas.getActiveObject();
|
||
|
if (canvas.getActiveObject().type == "activeSelection") {
|
||
|
alignBottomGroup(canvas, activeObject);
|
||
|
} else {
|
||
|
activeObject.set({ top: canvas.height - activeObject.height });
|
||
|
}
|
||
|
|
||
|
activeObject.setCoords();
|
||
|
canvas.renderAll();
|
||
|
};
|
||
|
|
||
|
// group aligns
|
||
|
|
||
|
const alignLeftGroup = (canvas: fabric.Canvas, group: fabric.Group | fabric.IObject) => {
|
||
|
const objects = group.getObjects();
|
||
|
let leftmostShape = objects[0];
|
||
|
|
||
|
for (let i = 1; i < objects.length; i++) {
|
||
|
if (objects[i].left < leftmostShape.left) {
|
||
|
leftmostShape = objects[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
objects.forEach((object) => {
|
||
|
object.left = leftmostShape.left;
|
||
|
object.setCoords();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const alignRightGroup = (canvas: fabric.Canvas, group: fabric.Group | fabric.IObject): void => {
|
||
|
const objects = group.getObjects();
|
||
|
let rightmostShape = objects[0];
|
||
|
|
||
|
for (let i = 1; i < objects.length; i++) {
|
||
|
if (objects[i].left > rightmostShape.left) {
|
||
|
rightmostShape = objects[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
objects.forEach((object) => {
|
||
|
object.left = rightmostShape.left + rightmostShape.width - object.width;
|
||
|
object.setCoords();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const alignTopGroup = (canvas: fabric.Canvas, group: fabric.Group | fabric.IObject): void => {
|
||
|
const objects = group.getObjects();
|
||
|
let topmostShape = objects[0];
|
||
|
|
||
|
for (let i = 1; i < objects.length; i++) {
|
||
|
if (objects[i].top < topmostShape.top) {
|
||
|
topmostShape = objects[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
objects.forEach((object) => {
|
||
|
object.top = topmostShape.top;
|
||
|
object.setCoords();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const alignBottomGroup = (canvas: fabric.Canvas, group: fabric.Group | fabric.IObject): void => {
|
||
|
const objects = group.getObjects();
|
||
|
let bottommostShape = objects[0];
|
||
|
|
||
|
for (let i = 1; i < objects.length; i++) {
|
||
|
if (objects[i].top + objects[i].height > bottommostShape.top + bottommostShape.height) {
|
||
|
bottommostShape = objects[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
objects.forEach(function(object) {
|
||
|
if (object !== bottommostShape) {
|
||
|
object.set({ top: bottommostShape.top + bottommostShape.height - object.height });
|
||
|
object.setCoords();
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const alignHorizontalCenterGroup = (canvas: fabric.Canvas, group: fabric.Group | fabric.IObject) => {
|
||
|
const objects = group.getObjects();
|
||
|
let leftmostShape = objects[0];
|
||
|
let rightmostShape = objects[0];
|
||
|
|
||
|
for (let i = 1; i < objects.length; i++) {
|
||
|
if (objects[i].left < leftmostShape.left) {
|
||
|
leftmostShape = objects[i];
|
||
|
}
|
||
|
if (objects[i].left > rightmostShape.left) {
|
||
|
rightmostShape = objects[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const centerX = (leftmostShape.left + rightmostShape.left + rightmostShape.width) / 2;
|
||
|
objects.forEach((object) => {
|
||
|
object.left = centerX - object.width / 2;
|
||
|
object.setCoords();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const alignVerticalCenterGroup = (canvas: fabric.Canvas, group: fabric.Group | fabric.IObject) => {
|
||
|
const objects = group.getObjects();
|
||
|
let topmostShape = objects[0];
|
||
|
let bottommostShape = objects[0];
|
||
|
|
||
|
for (let i = 1; i < objects.length; i++) {
|
||
|
if (objects[i].top < topmostShape.top) {
|
||
|
topmostShape = objects[i];
|
||
|
}
|
||
|
if (objects[i].top > bottommostShape.top) {
|
||
|
bottommostShape = objects[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const centerY = (topmostShape.top + bottommostShape.top + bottommostShape.height) / 2;
|
||
|
objects.forEach((object) => {
|
||
|
object.top = centerY - object.height / 2;
|
||
|
object.setCoords();
|
||
|
});
|
||
|
};
|