@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
JavaScript
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