UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

224 lines (223 loc) 7.34 kB
import { getContraryMap, getPointMap } from "./util/basic.mjs"; import { collectHorizontalPoint, collectVerticalPoint } from "./util/collect-point.mjs"; import { drawHorizontalLine, drawLine, drawPointList, drawVerticalLine, drawX } from "./util/draw.mjs"; import { collectLine } from "./util/collect-line.mjs"; import { getObjectsByTarget } from "./util/get-objects-by-target.mjs"; import { _defineProperty } from "../_virtual/_@oxc-project_runtime@0.122.0/helpers/defineProperty.mjs"; import { util } from "fabric"; //#region extensions/aligning_guidelines/index.ts var AligningGuidelines = class { constructor(canvas, options = {}) { _defineProperty(this, "canvas", void 0); _defineProperty(this, "horizontalLines", /* @__PURE__ */ new Set()); _defineProperty(this, "verticalLines", /* @__PURE__ */ new Set()); _defineProperty(this, "cacheMap", /* @__PURE__ */ new Map()); _defineProperty( this, /** * When we drag to resize using center points like mt, ml, mb, and mr, * we do not need to draw line segments; we only need to draw the target points. */ "onlyDrawPoint", false ); _defineProperty( this, /** Alignment method is required when customizing. */ "contraryOriginMap", { tl: ["right", "bottom"], tr: ["left", "bottom"], br: ["left", "top"], bl: ["right", "top"], mt: ["center", "bottom"], mr: ["left", "center"], mb: ["center", "top"], ml: ["right", "center"] } ); _defineProperty(this, "xSize", 2.4); _defineProperty(this, "lineDash", void 0); _defineProperty( this, /** At what distance from the shape does alignment begin? */ "margin", 4 ); _defineProperty( this, /** Aligning line dimensions */ "width", 1 ); _defineProperty( this, /** Aligning line color */ "color", "rgba(255,0,0,0.9)" ); _defineProperty( this, /** Close Vertical line, default false. */ "closeVLine", false ); _defineProperty( this, /** Close horizontal line, default false. */ "closeHLine", false ); this.canvas = canvas; Object.assign(this, options); this.mouseUp = this.mouseUp.bind(this); this.scalingOrResizing = this.scalingOrResizing.bind(this); this.moving = this.moving.bind(this); this.beforeRender = this.beforeRender.bind(this); this.afterRender = this.afterRender.bind(this); this.initBehavior(); } initBehavior() { this.canvas.on("mouse:up", this.mouseUp); this.canvas.on("object:resizing", this.scalingOrResizing); this.canvas.on("object:scaling", this.scalingOrResizing); this.canvas.on("object:moving", this.moving); this.canvas.on("before:render", this.beforeRender); this.canvas.on("after:render", this.afterRender); } /** Returns shapes that can draw aligning lines, default returns all shapes on the canvas excluding groups. */ getObjectsByTarget(target) { return getObjectsByTarget(target); } /** When the user customizes the controller, this property is set to enable or disable automatic alignment through point scaling/resizing. */ getPointMap(target) { return getPointMap(target); } /** When the user customizes the controller, this property is used to enable or disable alignment positioning through points. */ getContraryMap(target) { return getContraryMap(target); } /** Users can customize. */ getCaCheMapValue(object) { const cacheKey = [ object.calcTransformMatrix().toString(), object.width, object.height ].join(); const cacheValue = this.cacheMap.get(cacheKey); if (cacheValue) return cacheValue; const value = object.getCoords(); value.push(object.getCenterPoint()); this.cacheMap.set(cacheKey, value); return value; } drawLine(origin, target) { drawLine.call(this, origin, target); } drawX(point, dir) { drawX.call(this, point, dir); } mouseUp() { this.verticalLines.clear(); this.horizontalLines.clear(); this.cacheMap.clear(); this.canvas.requestRenderAll(); } scalingOrResizing(e) { const target = e.target; target.setCoords(); const isScale = String(e.transform.action).startsWith("scale"); this.verticalLines.clear(); this.horizontalLines.clear(); const objects = this.getObjectsByTarget(target); let corner = e.transform.corner; if (target.flipX) { if (corner.includes("l")) corner = corner.replace("l", "r"); else if (corner.includes("r")) corner = corner.replace("r", "l"); } if (target.flipY) { if (corner.includes("t")) corner = corner.replace("t", "b"); else if (corner.includes("b")) corner = corner.replace("b", "t"); } const pointMap = this.getPointMap(target); if (!(corner in pointMap)) return; this.onlyDrawPoint = corner.includes("m"); if (this.onlyDrawPoint) { if (target.getTotalAngle() % 90 != 0) return; } const contraryMap = this.getContraryMap(target); const point = pointMap[corner]; let diagonalPoint = contraryMap[corner]; const isCenter = e.transform.original.originX == "center" && e.transform.original.originY == "center"; if (isCenter) { const p = target.group ? point.transform(util.invertTransform(target.group.calcTransformMatrix())) : point; diagonalPoint = diagonalPoint.add(p).scalarDivide(2); } const uniformIsToggled = e.e[this.canvas.uniScaleKey]; let isUniform = this.canvas.uniformScaling && !uniformIsToggled || !this.canvas.uniformScaling && uniformIsToggled; if (this.onlyDrawPoint) isUniform = false; const list = []; for (const object of objects) { const d = this.getCaCheMapValue(object); list.push(...d); } const props = { target, point, diagonalPoint, corner, list, isScale, isUniform, isCenter }; const noNeedToCollectV = this.onlyDrawPoint && (corner.includes("t") || corner.includes("b")); const noNeedToCollectH = this.onlyDrawPoint && (corner.includes("l") || corner.includes("r")); const vList = noNeedToCollectV ? [] : collectVerticalPoint.call(this, props); const hList = noNeedToCollectH ? [] : collectHorizontalPoint.call(this, props); vList.forEach((o) => { this.verticalLines.add(JSON.stringify(o)); }); hList.forEach((o) => { this.horizontalLines.add(JSON.stringify(o)); }); } moving(e) { const target = e.target; target.setCoords(); this.onlyDrawPoint = false; this.verticalLines.clear(); this.horizontalLines.clear(); const objects = this.getObjectsByTarget(target); const points = []; for (const object of objects) points.push(...this.getCaCheMapValue(object)); const { vLines, hLines } = collectLine.call(this, target, points); vLines.forEach((o) => { this.verticalLines.add(JSON.stringify(o)); }); hLines.forEach((o) => { this.horizontalLines.add(JSON.stringify(o)); }); } beforeRender() { this.canvas.clearContext(this.canvas.contextTop); } afterRender() { if (this.onlyDrawPoint) drawPointList.call(this); else { drawVerticalLine.call(this); drawHorizontalLine.call(this); } } dispose() { this.canvas.off("mouse:up", this.mouseUp); this.canvas.off("object:resizing", this.scalingOrResizing); this.canvas.off("object:scaling", this.scalingOrResizing); this.canvas.off("object:moving", this.moving); this.canvas.off("before:render", this.beforeRender); this.canvas.off("after:render", this.afterRender); } }; //#endregion export { AligningGuidelines }; //# sourceMappingURL=index.mjs.map