UNPKG

@aurigma/design-atoms

Version:

Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.

324 lines 17.9 kB
import { BaseProductCommand } from "./BaseProductCommand"; import { maybe } from "tsmonad"; import { PlaceholderItemHandler, GroupItemHandler, BaseTextItemHandler } from "../../ItemHandlers"; import { fitRectangleToRectangle, getOriginCoordinate } from "../../Utils/Math"; import { Product, PrintArea, Surface } from "@aurigma/design-atoms-model/Product"; import { Item, ImageItem } from "@aurigma/design-atoms-model/Product/Items"; import { RectangleF, Matrix, EqualsOfFloatNumbers } from "@aurigma/design-atoms-model/Math"; import { Exception, ArgumentException, NotImplementedException } from "@aurigma/design-atoms-model/Exception"; import { ItemsCommand, OriginPointType, ResizeRectangleType } from "@aurigma/design-atoms-interfaces"; import { isEmpty } from "@aurigma/design-atoms-model"; export class ResizeCommand extends BaseProductCommand { constructor(historyArgs, product, args, _productHandler, _commandManager, _canvas) { super(product, historyArgs, args); this._productHandler = _productHandler; this._commandManager = _commandManager; this._canvas = _canvas; this._executeCommandBody = async () => { if (this._canvas != null) this._canvas.pauseRedraw(); try { const target = this._convertedArgs.target; const itemHandlers = this._items.map(this._productHandler.getHandler); if (this._canvas != null) { const canvasItemHandlers = this._canvas.getAllItemHandlers(); await Promise.all(itemHandlers.filter(handler => handler instanceof BaseTextItemHandler && !canvasItemHandlers.includes(handler)).map(h => { h.updateForExternalCanvas(this._canvas); return h.waitUpdate(); })); } itemHandlers.forEach((handler) => { handler.startTransform(); handler.beginUpdate(); }); if (target instanceof Product) { this._resizeProduct(target); if (this._canvas != null) { this._canvas.viewer._onResize(this, false); } } else if (target instanceof PrintArea) { this._resizePrintArea(target); } else if (Array.isArray(target)) { if (target[0] instanceof Surface) { target.forEach((s) => this._resizeSurface(s)); } else if (target[0] instanceof Item) { this._resizeItems(target); } } this._items.map(this._productHandler.getHandler).forEach((handler) => { handler.endTransform(true, true); handler.endUpdate(); }); } finally { if (this._canvas != null) { await this._canvas.waitUpdate(); this._canvas.updateSelection(); this._canvas.continueRedraw(); this._canvas.updateTexts(); } } }; this._resizeProduct = (product) => { product.surfaces.forEach(s => this._resizeSurface(s)); }; this._resizeSurface = (surface) => { var _a, _b; const surfaceRect = new RectangleF(0, 0, surface.width, surface.height); const originX = (_a = this._getResizeOptions().originX) !== null && _a !== void 0 ? _a : OriginPointType.Left; const originY = (_b = this._getResizeOptions().originY) !== null && _b !== void 0 ? _b : OriginPointType.Top; const matrix = this._getTransformMatrix(surfaceRect, originX, originY); surface.mockup.allContainers.forEach((c) => this._resizeMockupContainer(c, matrix, surface)); surface.printAreas.forEach((p) => this._resizePrintAreaBounds(p, matrix)); surface.containers.forEach((c) => this._resizeContainer(c, matrix, surface)); matrix.updateObjectByMatrix(surface, "width", "height"); }; this._resizeMockupContainer = (container, matrix, surface) => { if (container.size != null) container.size.updateByMatrix(matrix); this._resizeContainer(container, matrix, surface); }; /*send printArea argument for resize items within printArea only. Other items will moved*/ this._resizeContainer = (container, matrix, surface, printArea = null) => { if (container.region != null) container.region.updateByMatrix(matrix); const isItemInPrintArea = (item) => { return printArea.bounds.intersectsWith(this._productHandler.getHandler(item).bounds); }; const items = container.items.toArray().filter(i => printArea == null || isItemInPrintArea(i)); const resizeType = this._getResizeOptions(container).resize; const itemMatrix = this._getItemsMatrix(items, resizeType, matrix, surface); const resetPlaceholderContent = this._getResizeOptions(container).resetPlaceholderContent; container.items.forEach((i) => { let targetMatrix = printArea != null ? this._getTranslateMatrixRelativeToPrintArea(printArea.bounds, this._productHandler.getHandler(i).bounds, isItemInPrintArea(i) ? itemMatrix : matrix) : itemMatrix; this._resizeItem(i, targetMatrix, resetPlaceholderContent); }); }; this._resizeItems = (items) => { var _a, _b; const resize = this._getResizeOptions().resize; if (resize === ResizeRectangleType.Original) throw new Exception("Original type not supported when resizing items."); let overallBounds; if (items.length === 1) { var rect = this._productHandler.getHandler(items[0]).rectangle; rect.angle = 0; overallBounds = rect.bounds; } else { overallBounds = this._getItemsBounds(items); } const originX = (_a = this._getResizeOptions().originX) !== null && _a !== void 0 ? _a : OriginPointType.Center; const originY = (_b = this._getResizeOptions().originY) !== null && _b !== void 0 ? _b : OriginPointType.Center; const originMatrix = this._getTransformMatrix(overallBounds, originX, originY); const matrix = this._getItemsMatrix(items, this._getResizeOptions().resize, originMatrix, null); items.forEach((i) => { var _a; return this._resizeItem(i, matrix, (_a = this._defaultResizeOptions.resetPlaceholderContent) !== null && _a !== void 0 ? _a : true); }); }; this._resizeItem = (item, matrix, resetPlaceholderContent) => { const updateHandler = (handler) => { var _a; handler.transformByMatrix(matrix, false); const item = handler.item; if (item instanceof ImageItem) { (_a = item.values) === null || _a === void 0 ? void 0 : _a.filter(i => (i === null || i === void 0 ? void 0 : i.transformedRectangle) != null).forEach(v => { v.transformedRectangle = v.transformedRectangle.transformByMatrix(matrix); }); } }; const resetPlaceholderHandler = (handler) => { if (resetPlaceholderContent && handler.content != null) { handler.content.updateRectangle(false, handler.item.contentResizeMode, handler); } }; const itemHandler = this._productHandler.getHandler(item); updateHandler(itemHandler); if (itemHandler instanceof PlaceholderItemHandler) { itemHandler.updateContentAndFrames(updateHandler); resetPlaceholderHandler(itemHandler); } if (itemHandler instanceof GroupItemHandler) itemHandler.itemHandlers.toArray().filter(i => i instanceof PlaceholderItemHandler).forEach(resetPlaceholderHandler); }; this._resizePrintAreaBounds = (printArea, matrix) => { printArea.bounds = printArea.bounds.clone().updateByMatrix(matrix); }; this._resizePrintArea = (printArea) => { const surface = this._product.surfaces.toArray().find(s => s.printAreas.contains(printArea)); const matrix = this._getMatrixForPrintArea(printArea); surface.containers.forEach((c) => this._resizeContainer(c, matrix, surface, printArea)); surface.printAreas.forEach(p => { if (p !== printArea) this._resizePrintAreaBounds(p, this._getTranslateMatrixRelativeToPrintArea(printArea.bounds, p.bounds, matrix)); }); this._resizePrintAreaBounds(printArea, matrix); this._resizeSurfaceByPrintArea(surface); }; this._resizeSurfaceByPrintArea = (surface) => { const overallBounds = RectangleF.getOverallBounds(surface.printAreas.toArray().map(p => p.bounds)); const surfaceRect = new RectangleF(0, 0, surface.width, surface.height); if (surfaceRect.containsRectangle(overallBounds)) return; surface.width = Math.max(surface.width, overallBounds.right); surface.height = Math.max(surface.height, overallBounds.bottom); if (overallBounds.left >= 0 || overallBounds.top >= 0) return; this._commandManager.execute(ItemsCommand.translateItems, { items: surface.getAllItems().toArray(), translateX: -Math.min(0, overallBounds.left), translateY: -Math.min(0, overallBounds.top) }); }; this._getTransformMatrix = (initialRect, originX, originY) => { const origin = getOriginCoordinate(initialRect, originX, originY); const matrix = new Matrix(); matrix.scaleRelativeToPoint(this._getScaleMultiplier(this._args.width, initialRect.width), this._getScaleMultiplier(this._args.height, initialRect.height), origin); return matrix; }; this._getScaleMultiplier = (value, parentSize) => { if (typeof value === "string") { if (/%$/.test(value)) { const percent = Number(value.split(/%/)[0]); return percent / 100; } else { const parsedValue = parseFloat(value); if (isNaN(parsedValue)) throw new ArgumentException(`ResizeCommand: Wrong string format: ${value}`); else value = parsedValue; } } if (value <= 0) throw new ArgumentException(`ResizeCommand: Wrong value: ${value}`); if (parentSize <= 0) throw new ArgumentException(`ResizeCommand: Wrong parentSize: ${parentSize}`); return value / parentSize; }; this._convertedArgs = this._args.target != null ? this._args : this._convertExternalConfig(this._args); } get _items() { const target = this._convertedArgs.target; if (target instanceof Product) return target.getAllItems(); if (target instanceof PrintArea) { const surface = this._product.surfaces.firstOrDefault(s => s.printAreas.contains(target)); if (surface == null) return []; return surface.getAllItems().toArray(); } if (!Array.isArray(target)) return []; if (target[0] instanceof Item) return target; if (target[0] instanceof Surface) return target.map((s) => s.getAllItems().toArray()).flat(); return []; } _getTranslateMatrixRelativeToPrintArea(printAreaBounds, bounds, originalMatrix) { const result = new Matrix(); const isItemInLeftOrTopPart = bounds.bottom <= printAreaBounds.top || bounds.right <= printAreaBounds.left; if (isItemInLeftOrTopPart) return result; if (printAreaBounds.intersectsWith(bounds)) return originalMatrix; let newPrintAreaBounds = printAreaBounds.clone().updateByMatrix(originalMatrix); result.translate(bounds.left > printAreaBounds.right || EqualsOfFloatNumbers(printAreaBounds.right - bounds.left, 0) ? newPrintAreaBounds.right - printAreaBounds.right : 0, bounds.top > printAreaBounds.bottom || EqualsOfFloatNumbers(printAreaBounds.bottom - bounds.top, 0) ? newPrintAreaBounds.bottom - printAreaBounds.bottom : 0); return result; } _getItemsMatrix(items, resizeType, originMatrix, originSurface) { var _a, _b; let itemsRectMatrix; if (resizeType !== ResizeRectangleType.Original) { const initialItemsRect = this._getItemsBounds(items); const targetItemRect = initialItemsRect.clone().updateByMatrix(originMatrix); const forceFit = resizeType === ResizeRectangleType.Arbitrary && items.some(i => i.transform.angle % 90 !== 0); const targetFittedRect = fitRectangleToRectangle(initialItemsRect, targetItemRect, forceFit ? ResizeRectangleType.Fit : resizeType); itemsRectMatrix = RectangleF.getMatrix(initialItemsRect, targetFittedRect); } else { const originX = (_a = this._getResizeOptions().originX) !== null && _a !== void 0 ? _a : OriginPointType.Center; const originY = (_b = this._getResizeOptions().originY) !== null && _b !== void 0 ? _b : OriginPointType.Center; itemsRectMatrix = this._getTranslateMatrixForOriginalMode(originMatrix, originSurface, originX, originY); } return itemsRectMatrix; } _getTranslateMatrixForOriginalMode(originMatrix, originSurface, originX, originY) { const initialRect = new RectangleF(0, 0, originSurface.width, originSurface.height); const initialOrigin = getOriginCoordinate(initialRect, originX, originY); const finalRect = initialRect.updateByMatrix(originMatrix); const finalOrigin = getOriginCoordinate(finalRect, originX, originY); const matrix = new Matrix(); matrix.translate(finalOrigin.x - initialOrigin.x, finalOrigin.y - initialOrigin.y); return matrix; } _getResizeOptions(container) { return maybe(this._args.containerOptions) .bind(options => maybe(container).map(c => options[c.name])) .caseOf({ just: opt => (Object.assign(Object.assign({}, this._defaultResizeOptions), opt)), nothing: () => this._defaultResizeOptions }); } get _defaultResizeOptions() { return Object.assign({ resize: ResizeRectangleType.Fit, resetPlaceholderContent: true }, (this._args.defaultOptions || {})); } _getItemsBounds(items) { if (items.length === 0) return RectangleF.empty; return RectangleF.getOverallBounds(items.map((i) => this._productHandler.getHandler(i).bounds)); } _getMatrixForPrintArea(printArea) { var _a, _b; const originX = (_a = this._getResizeOptions().originX) !== null && _a !== void 0 ? _a : OriginPointType.Left; const originY = (_b = this._getResizeOptions().originY) !== null && _b !== void 0 ? _b : OriginPointType.Top; return this._getTransformMatrix(printArea.bounds, originX, originY); } _convertExternalConfig(externalConfig) { let target; switch (externalConfig.targetType) { case "surfaces": if (isEmpty(externalConfig.targetIds)) throw new ArgumentException("ResizeCommand: target Ids cannot be empty"); target = this._product.surfaces.toArray().filter(s => externalConfig.targetIds.includes(s.id)); break; case "items": if (isEmpty(externalConfig.targetIds)) throw new ArgumentException("ResizeCommand: target Ids cannot be empty"); target = this._productHandler.currentSurface .getAllItems({ ignoreMockups: false, flatGroupItems: true }) .toArray() .filter(s => externalConfig.targetIds.includes(s.id)); break; case "printArea": if (isEmpty(externalConfig.targetIds)) throw new ArgumentException("ResizeCommand: target Ids cannot be empty"); target = this._product.surfaces.toArray().map(s => s.printAreas.toArray()).flat().find(p => externalConfig.targetIds.includes(p.id)); break; default: target = this._product; break; } return { target: target, width: externalConfig.width, height: externalConfig.height, containerOptions: externalConfig.containerOptions, defaultOptions: externalConfig.defaultOptions }; } redo() { throw new NotImplementedException(); } undo() { throw new NotImplementedException(); } } //# sourceMappingURL=ResizeCommand.js.map