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.

431 lines 23.4 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { RectangleItemHandler } from "./RectangleItemHandler"; import { ContentType } from "./ContentType"; import { PointF, EqualsOfFloatNumbers, normalizeAngle, Path, Transform } from "@aurigma/design-atoms-model/Math"; import { Graphics } from "../Graphics"; import { ImageContainer } from "./ImageContainer"; import * as Utils from "@aurigma/design-atoms-model/Utils/Utils"; import { VerticalContentAlignment, HorizontalContentAlignment, ResizeMode, ImageItem } from "@aurigma/design-atoms-model/Product/Items"; import Environment from "@aurigma/design-atoms-model/Utils/Environment"; import { RgbColors } from "@aurigma/design-atoms-model/Colors"; // ReSharper disable once InconsistentNaming var ContentItemHandler = /** @class */ (function (_super) { __extends(ContentItemHandler, _super); function ContentItemHandler(item, textWhizz, apiClient, colorPreviewService) { if (textWhizz === void 0) { textWhizz = null; } var _this = _super.call(this, item, textWhizz, apiClient, colorPreviewService) || this; _this._onCanvasChangedDelegate = null; _this._contentType = ContentType.NotContent; _this._parentPlaceholder = null; _this._pixelWidth = 0; _this._pixelHeight = 0; _this._needToDownloadImage = false; _this._imageContainer = new ImageContainer(_this._onImageLoaded.bind(_this)); return _this; } Object.defineProperty(ContentItemHandler.prototype, "item", { get: function () { return this._getItem(); }, enumerable: true, configurable: true }); Object.defineProperty(ContentItemHandler.prototype, "parentPlaceholder", { get: function () { return this._parentPlaceholder; }, set: function (value) { this._parentPlaceholder = value; }, enumerable: true, configurable: true }); ContentItemHandler.prototype._getLayer = function () { if (this.parentPlaceholder != null) { return this.parentPlaceholder.layer; } return _super.prototype._getLayer.call(this); }; Object.defineProperty(ContentItemHandler.prototype, "contentType", { get: function () { return this._contentType; }, set: function (value) { this._contentType = value; }, enumerable: true, configurable: true }); ContentItemHandler.prototype.isVisible = function () { if (this._parentPlaceholder != null) return this._parentPlaceholder.isVisible(); return _super.prototype.isVisible.call(this); }; ContentItemHandler.prototype.quickUpdate = function () { this._updateImageUrl(); }; ContentItemHandler.prototype._getScaleMultiplier = function () { var parentPlaceholder = this._parentPlaceholder; var placeholderRectangle = parentPlaceholder.rectangle; var oldRect = this.rectangle; var oldPlaceholderRatio = parentPlaceholder.previousRectangle.width / parentPlaceholder.previousRectangle.height; var placeholderRatio = placeholderRectangle.width / placeholderRectangle.height; var placeholderContentRatio = oldRect.width / oldRect.height; var ratioChanged = (placeholderRatio > placeholderContentRatio) !== (oldPlaceholderRatio > placeholderContentRatio); if (placeholderRatio > placeholderContentRatio) { if (ratioChanged) { var ratioHeight = (placeholderRectangle.width / placeholderContentRatio); return ratioHeight / parentPlaceholder.previousRectangle.height; } else { return placeholderRectangle.width / parentPlaceholder.previousRectangle.width; } } else { if (ratioChanged) { var ratioWidth = (placeholderRectangle.height * placeholderContentRatio); return ratioWidth / parentPlaceholder.previousRectangle.width; } else { return placeholderRectangle.height / parentPlaceholder.previousRectangle.height; } } }; ContentItemHandler.prototype.setRectangle = function (rectangle, suppressOnChanged) { var parentPlaceholder = this._parentPlaceholder; var contentTypeIsFrame = this._contentType === ContentType.TopFrame || this._contentType === ContentType.BottomFrame; var diff; if (parentPlaceholder != null && parentPlaceholder.item.isCoverMode && !parentPlaceholder.item.isStubContent && !contentTypeIsFrame) { var placeholderRectangle = parentPlaceholder.rectangle; var targetRectangle = rectangle.clone(); var widthAndHeightReplace = EqualsOfFloatNumbers(normalizeAngle(targetRectangle.angle - placeholderRectangle.angle) % 180, 90); var oldRect = this.rectangle; if (oldRect != null) { if (parentPlaceholder.previousRectangle != null && !parentPlaceholder.editing) { var scaleMultiplier = this._getScaleMultiplier(); targetRectangle.width = oldRect.width * scaleMultiplier; targetRectangle.height = oldRect.height * scaleMultiplier; // When resizing a placeholder, it is necessary to position the content correctly: // The content point that was in the center of the placeholder before transformation should be in the center of the new placeholder. // But if empty areas appear, the content shifts and this condition will not be met. targetRectangle.center = placeholderRectangle.center; var targetRectangleAngle = targetRectangle.angle; targetRectangle.angle = 0; var diffX = (parentPlaceholder.previousRectangle.centerX - oldRect.centerX + (oldRect.width / 2)) * scaleMultiplier - targetRectangle.width / 2; var diffY = (parentPlaceholder.previousRectangle.centerY - oldRect.centerY + (oldRect.height / 2)) * scaleMultiplier - targetRectangle.height / 2; diff = new PointF(-diffX, -diffY); diff.rotateAt(placeholderRectangle.angle - parentPlaceholder.previousRectangle.angle); targetRectangle.centerX = placeholderRectangle.centerX + diff.x; targetRectangle.centerY = placeholderRectangle.centerY + diff.y; targetRectangle.rotateAt(targetRectangleAngle, targetRectangle.center); } } //The positioning algorithm, which prevents the appearance of empty areas inside the placeholder. //It is needed in case of disproportional resizing. Also, TopToolbar allows for resizing the content without grips. var rectWidth = (widthAndHeightReplace ? targetRectangle.height : targetRectangle.width); var rectHeight = (widthAndHeightReplace ? targetRectangle.width : targetRectangle.height); //First, check that the content is the right size to fit correctly into the placeholder. //If not, increase the scale to the required size. if (rectWidth < placeholderRectangle.width || rectHeight < placeholderRectangle.height) { var multiplier = Math.max(placeholderRectangle.width / rectWidth, placeholderRectangle.height / rectHeight); targetRectangle.width *= multiplier; targetRectangle.height *= multiplier; } //Rotate the placeholder to zero angle. var angle = placeholderRectangle.angle; placeholderRectangle.angle = 0; var placeholderBounds = placeholderRectangle.bounds; //Rotate the content to zero angle. At the same time, the content can remain its own angle, which is a multiple of 90 degrees. var contentRectangleWithoutAngle = targetRectangle.clone(); contentRectangleWithoutAngle.rotateAt(-angle, placeholderRectangle.center); var bounds = contentRectangleWithoutAngle.bounds; //Calculate whether the content should be moved (i.e. for transparent areas). //Move the content if needed. diff = new PointF(0, 0); diff.x = placeholderBounds.left < bounds.left ? placeholderBounds.left - bounds.left : 0; diff.x = placeholderBounds.right > bounds.right ? placeholderBounds.right - bounds.right : diff.x; diff.y = placeholderBounds.top < bounds.top ? placeholderBounds.top - bounds.top : 0; diff.y = placeholderBounds.bottom > bounds.bottom ? placeholderBounds.bottom - bounds.bottom : diff.y; diff.rotate(angle); targetRectangle.centerX += diff.x; targetRectangle.centerY += diff.y; _super.prototype.setRectangle.call(this, targetRectangle, suppressOnChanged); return; } if ((parentPlaceholder === null || parentPlaceholder === void 0 ? void 0 : parentPlaceholder.item.contentResizeMode) === ResizeMode.Fit && !parentPlaceholder.editing) { var container = parentPlaceholder.rectangle; var rectangle_1 = this.rectangle.clone().rotateAt(-this.rectangle.angle, container.center); var scaleX = container.width / rectangle_1.width; var scaleY = container.height / rectangle_1.height; var scaleFactor = Math.min(scaleX, scaleY); rectangle_1.width = rectangle_1.width * scaleFactor; rectangle_1.height = rectangle_1.height * scaleFactor; rectangle_1.bounds.left = (container.width - rectangle_1.width) / 2 + container.bounds.left; rectangle_1.bounds.top = (container.height - rectangle_1.height) / 2 + container.bounds.top; this._updatePosition(rectangle_1, parentPlaceholder); _super.prototype.setRectangle.call(this, rectangle_1, suppressOnChanged); return; } _super.prototype.setRectangle.call(this, rectangle, suppressOnChanged); }; ContentItemHandler.prototype.updateRectangle = function (keepLocation, resizeMode, parentPlaceholder, sourceWidth, sourceHeight, hiResOutputDpi) { if (resizeMode == null) resizeMode = ResizeMode.Fit; if (keepLocation == null) keepLocation = false; var rectangle = this.getTransformedRectangle(false); sourceWidth = sourceWidth != null ? sourceWidth : this.bounds.width; sourceHeight = sourceHeight != null ? sourceHeight : this.bounds.height; if (keepLocation) { var ratio = sourceWidth / sourceHeight; var location_1 = rectangle.location; rectangle.width = rectangle.height * ratio; rectangle.location = location_1; } else { if (this.parentPlaceholder != null) rectangle = this.parentPlaceholder.getTransformedRectangle(false); if (resizeMode === ResizeMode.Original && this.item instanceof ImageItem) { var originalSize = this.item.getOriginalImageSize(); var scale = hiResOutputDpi != null ? this.item.source.dpiX / hiResOutputDpi : 1; rectangle.width = originalSize.width * scale; rectangle.height = originalSize.height * scale; } else { var scale = 1; if (resizeMode === ResizeMode.Fit) { scale = Math.min(rectangle.width / sourceWidth, rectangle.height / sourceHeight); } else if (resizeMode === ResizeMode.Fill) { scale = Math.max(rectangle.width / sourceWidth, rectangle.height / sourceHeight); } rectangle.width = sourceWidth * scale; rectangle.height = sourceHeight * scale; } } // Do not use this.parentPlaceholder because alignment is needed only when inserting an image. this._updatePosition(rectangle, parentPlaceholder); this.setTransformedRectangle(rectangle); }; ContentItemHandler.prototype._updatePosition = function (rectangle, parentPlaceholder) { if (parentPlaceholder == null) return; var phRect = parentPlaceholder.getTransformedRectangle(false); switch (parentPlaceholder.item.contentVerticalAlignment) { case VerticalContentAlignment.Top: rectangle.centerY = phRect.centerY - (phRect.height - rectangle.height) / 2; break; case VerticalContentAlignment.Center: case VerticalContentAlignment.None: rectangle.centerY = phRect.centerY; break; case VerticalContentAlignment.Bottom: rectangle.centerY = phRect.centerY + (phRect.height - rectangle.height) / 2; break; } switch (parentPlaceholder.item.contentHorizontalAlignment) { case HorizontalContentAlignment.Left: rectangle.centerX = phRect.centerX - (phRect.width - rectangle.width) / 2; break; case HorizontalContentAlignment.Center: case HorizontalContentAlignment.None: rectangle.centerX = phRect.centerX; break; case HorizontalContentAlignment.Right: rectangle.centerX = phRect.centerX + (phRect.width - rectangle.width) / 2; break; } }; ContentItemHandler.prototype.drawItemHandler = function (itemHandlerCtx, originalCtx) { if (itemHandlerCtx == null || this.canvas == null) { return; } if (!this._isReadyToDraw) { this.canvas.drawWaitClock(itemHandlerCtx, this.rectangle.center); return; } var placeholder = this._parentPlaceholder != null ? this._parentPlaceholder.rectangle : this.rectangle; var content = this.rectangle; var _a = this._getItemColorPreviews(), fillColorPreview = _a.fillColorPreview, borderColorPreview = _a.borderColorPreview, altBorderColorPreview = _a.altBorderColorPreview; if (this._hasVectorMask()) { itemHandlerCtx.save(); this._clip(itemHandlerCtx); } var opacity = this.isNormalRenderingType ? this.item.opacity : 1; Graphics.fillRectangle(itemHandlerCtx, content, fillColorPreview === null || fillColorPreview === void 0 ? void 0 : fillColorPreview.toString(), opacity); if (this._imageContainer.isLoaded) { this._drawImage(itemHandlerCtx, this.canvas.disableSmoothing); } else if (this._imageContainer.isLoading) { this.canvas.drawWaitClock(originalCtx != null ? originalCtx : itemHandlerCtx, new PointF(placeholder.centerX, placeholder.centerY)); } var borderWidth = this._getActualBorderWidth(); content.width += borderWidth; content.height += borderWidth; Graphics.drawStroke(itemHandlerCtx, Path.rotatedRectangle(content), content.center, new Transform(), borderWidth, borderColorPreview === null || borderColorPreview === void 0 ? void 0 : borderColorPreview.toString(), altBorderColorPreview === null || altBorderColorPreview === void 0 ? void 0 : altBorderColorPreview.toString(), this.item.opacity, this.item.dash); if (this._hasVectorMask()) itemHandlerCtx.restore(); }; ContentItemHandler.prototype.drawMaskedContent = function (ctx) { this._drawImage(ctx, this.canvas.disableSmoothing, this.item.maskOpacity); if (this._parentPlaceholder == null) return; ctx.globalCompositeOperation = "destination-out"; var placeholder = this._parentPlaceholder; Graphics.fillPath(ctx, placeholder.originalPath, placeholder.getControlCenter(), placeholder.item.transform, "#fff"); ctx.globalCompositeOperation = "source-over"; }; ContentItemHandler.prototype.transformByMatrix = function (matrix, finished, newAngle) { if (newAngle === void 0) { newAngle = null; } var _a; if ((_a = this.parentPlaceholder) === null || _a === void 0 ? void 0 : _a.editing) { this.parentPlaceholder.setContentUpdating(!finished); } _super.prototype.transformByMatrix.call(this, matrix, finished, newAngle); }; ContentItemHandler.prototype.dispose = function () { this._imageContainer.dispose(); if (this._onCanvasChangedDelegate) { var cv = this.canvas; if (cv) cv.remove_zoomChanged(this._onCanvasChangedDelegate); delete this._onCanvasChangedDelegate; } _super.prototype.dispose.call(this); }; ContentItemHandler.prototype._isReady = function () { return _super.prototype._isReady.call(this) && (Utils.isNullOrEmptyOrWhiteSpace(this._imageContainer.source) || this._imageContainer.isLoaded); }; ContentItemHandler.prototype._getDrawingFillColor = function () { return this.item.fillColor; }; ContentItemHandler.prototype._isLoadingImage = function () { return this._imageContainer.isLoading; }; ContentItemHandler.prototype._setIsLoadingImage = function (value) { this._imageContainer.isLoading = value; }; ContentItemHandler.prototype._onItemPropertyChanged = function (sender, propertyName) { var _a; switch (propertyName) { case "maskOpacity": break; case "parentPlaceholder": this.parentPlaceholder = sender.parentPlaceholder != null ? (_a = this.canvas) === null || _a === void 0 ? void 0 : _a.getItemHandler(sender.parentPlaceholder) : null; break; default: } _super.prototype._onItemPropertyChanged.call(this, sender, propertyName); }; ContentItemHandler.prototype._getSrc = function () { var src = this._imageContainer.source; return !Utils.isNullOrEmptyOrWhiteSpace(src) ? src : this._createImageUrl(); }; ContentItemHandler.prototype._setSrc = function (value) { this._imageContainer.source = value; }; ContentItemHandler.prototype._onImageLoaded = function (e, target) { try { if (this.canvas != null) this.canvas.redraw(); this.isLoadingImage = false; this._dispatchReadyEvent(); } catch (ex) { console.error("Exception in [" + this.getTypeName() + "#" + this.name + "]._onImageLoaded", ex); throw ex; } }; ContentItemHandler.prototype._createImageUrl = function () { return null; }; ContentItemHandler.prototype._updateImageUrl = function () { if (!this.isVisible()) return; var cv = this.canvas; if (cv == null || !cv.isInitialized) return; var url = this._createImageUrl(); if (url === this._imageContainer.source) return; if (url == null) { this._imageContainer.clear(); cv.redraw(); } else { this._imageContainer.updateUrl(url); } }; ContentItemHandler.prototype._onCanvasChanged = function (args) { if (args.fullUpdate) this._updateImageUrl(); }; ContentItemHandler.prototype._getItemColorPreviews = function () { var _a = _super.prototype._getItemColorPreviews.call(this), borderColorPreview = _a.borderColorPreview, altBorderColorPreview = _a.altBorderColorPreview; var fillColorPreview = this._getFillColorPreview(); return { fillColorPreview: fillColorPreview, borderColorPreview: borderColorPreview, altBorderColorPreview: altBorderColorPreview }; }; ContentItemHandler.prototype._drawImage = function (ctx, disableSmoothing, opacity, image) { var canvas = this.canvas; var scaleX = Environment.screenDpi * canvas.zoom / 72; var scaleY = Environment.screenDpi * canvas.zoom / 72; var objectOpacity = this.isNormalRenderingType ? this.item.opacity : 1; var targetOpacity = opacity != null ? objectOpacity * opacity : objectOpacity; Graphics.drawImage(ctx, image != null ? image : this._imageContainer.image, this.rectangle, scaleX, scaleY, disableSmoothing, null, targetOpacity); }; ContentItemHandler.prototype._getBoundsMargin = function () { return this._getActualBorderWidth() * 2; }; ContentItemHandler.prototype._onAddedOnCanvas = function (canvas, supressUpdate) { _super.prototype._onAddedOnCanvas.call(this, canvas, supressUpdate || this.parentPlaceholder != null); this._updateImageUrl(); if (!this._onCanvasChangedDelegate) { var cv = this.canvas; if (cv) { this._onCanvasChangedDelegate = this._onCanvasChanged.bind(this); cv.add_zoomChanged(this._onCanvasChangedDelegate); if (this._needToDownloadImage) this.update(); } } }; ContentItemHandler.prototype._onRemovedFromCanvas = function (canvas) { _super.prototype._onRemovedFromCanvas.call(this, canvas); if (canvas && this._onCanvasChangedDelegate != null) { canvas.remove_zoomChanged(this._onCanvasChangedDelegate); delete this._onCanvasChangedDelegate; } }; ContentItemHandler.prototype._getFillColorPreview = function () { var drawingFillColor = this._getDrawingFillColor(); var fillColor = (this.isNormalRenderingType || (drawingFillColor === null || drawingFillColor === void 0 ? void 0 : drawingFillColor.isTransparent)) ? drawingFillColor : RgbColors.black; var fillColorPreview = this._colorPreviewService.getPreviews([fillColor])[0]; if (this.item.fillColor != null && fillColorPreview == null) { this._colorPreviewService.subscribeToPreviewLoaded(fillColor, this._onColorPreviewLoaded); } return fillColorPreview; }; ContentItemHandler.typeName = "ContentItemHandler"; return ContentItemHandler; }(RectangleItemHandler)); export { ContentItemHandler }; //# sourceMappingURL=ContentItemHandler.js.map