- Fix router import path in main.js - Handle Django REST Framework pagination format in API calls - Add getTemplates function to project API - Restart frontend development server
117 lines
3.9 KiB
TypeScript
117 lines
3.9 KiB
TypeScript
import type { FabricObject, Point } from 'fabric';
|
|
import type { AligningGuidelines } from '..';
|
|
import type { LineProps } from '../typedefs';
|
|
import { getDistanceList } from './basic';
|
|
|
|
type CollectPointProps = {
|
|
target: FabricObject;
|
|
/** Operation points of the target element: top-left, bottom-left, top-right, bottom-right */
|
|
point: Point;
|
|
/** Position using diagonal points when resizing/scaling. */
|
|
diagonalPoint: Point;
|
|
/** Set of points to consider for alignment: [tl, tr, br, bl, center] */
|
|
list: Point[];
|
|
/** Change the zoom or change the size, determine by whether e.transform.action starts with the string "scale" */
|
|
isScale: boolean;
|
|
/** Whether to change uniformly is determined by canvas.uniformScaling and canvas.uniScaleKey. */
|
|
isUniform: boolean;
|
|
/** When holding the centerKey (default is altKey), the shape will scale based on the center point, with the reference point being the center. */
|
|
isCenter: boolean;
|
|
/** tl、tr、br、bl、mt、mr、mb、ml */
|
|
corner: string;
|
|
};
|
|
|
|
export function collectVerticalPoint(
|
|
this: AligningGuidelines,
|
|
props: CollectPointProps,
|
|
): LineProps[] {
|
|
const {
|
|
target,
|
|
isScale,
|
|
isUniform,
|
|
corner,
|
|
point,
|
|
diagonalPoint,
|
|
list,
|
|
isCenter,
|
|
} = props;
|
|
const { dis, arr } = getDistanceList(point, list, 'x');
|
|
const margin = this.margin / this.canvas.getZoom();
|
|
if (dis > margin) return [];
|
|
let v = arr[arr.length - 1].x - point.x;
|
|
// tl bl ml
|
|
// If modifying on the left side, the size decreases; conversely, it increases.
|
|
const dirX = corner.includes('l') ? -1 : 1;
|
|
v *= dirX;
|
|
|
|
const { width, height, scaleX, scaleY } = target;
|
|
// Because when modifying through the center point, isUniform is always false, so skew does not need to be considered.
|
|
const dStrokeWidth = target.strokeUniform ? 0 : target.strokeWidth;
|
|
const scaleWidth = scaleX * width + dStrokeWidth;
|
|
const sx = (v + scaleWidth) / scaleWidth;
|
|
// When v equals -scaleWidth, sx equals 0.
|
|
if (sx == 0) return [];
|
|
if (isScale) {
|
|
target.set('scaleX', scaleX * sx);
|
|
if (isUniform) target.set('scaleY', scaleY * sx);
|
|
} else {
|
|
target.set('width', width * sx);
|
|
if (isUniform) target.set('height', height * sx);
|
|
}
|
|
if (isCenter) {
|
|
target.setRelativeXY(diagonalPoint, 'center', 'center');
|
|
} else {
|
|
const originArr = this.contraryOriginMap;
|
|
target.setRelativeXY(diagonalPoint, ...originArr[corner]);
|
|
}
|
|
target.setCoords();
|
|
return arr.map((target) => ({ origin: point, target }));
|
|
}
|
|
|
|
export function collectHorizontalPoint(
|
|
this: AligningGuidelines,
|
|
props: CollectPointProps,
|
|
): LineProps[] {
|
|
const {
|
|
target,
|
|
isScale,
|
|
isUniform,
|
|
corner,
|
|
point,
|
|
diagonalPoint,
|
|
list,
|
|
isCenter,
|
|
} = props;
|
|
const { dis, arr } = getDistanceList(point, list, 'y');
|
|
const margin = this.margin / this.canvas.getZoom();
|
|
if (dis > margin) return [];
|
|
let v = arr[arr.length - 1].y - point.y;
|
|
// tl mt tr
|
|
// If modifying on the top side, the size decreases; conversely, it increases.
|
|
const dirY = corner.includes('t') ? -1 : 1;
|
|
v *= dirY;
|
|
|
|
const { width, height, scaleX, scaleY } = target;
|
|
// Because when modifying through the center point, isUniform is always false, so skew does not need to be considered.
|
|
const dStrokeWidth = target.strokeUniform ? 0 : target.strokeWidth;
|
|
const scaleHeight = scaleY * height + dStrokeWidth;
|
|
const sy = (v + scaleHeight) / scaleHeight;
|
|
// When v equals -scaleHeight, sy equals 0.
|
|
if (sy == 0) return [];
|
|
if (isScale) {
|
|
target.set('scaleY', scaleY * sy);
|
|
if (isUniform) target.set('scaleX', scaleX * sy);
|
|
} else {
|
|
target.set('height', height * sy);
|
|
if (isUniform) target.set('width', width * sy);
|
|
}
|
|
if (isCenter) {
|
|
target.setRelativeXY(diagonalPoint, 'center', 'center');
|
|
} else {
|
|
const originArr = this.contraryOriginMap;
|
|
target.setRelativeXY(diagonalPoint, ...originArr[corner]);
|
|
}
|
|
target.setCoords();
|
|
return arr.map((target) => ({ origin: point, target }));
|
|
}
|