@aurigma/design-atoms
Version:
Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.
370 lines • 18.2 kB
JavaScript
import { EventWithSenderArg } from "@aurigma/design-atoms-model/EventObject";
import { ContentItemHandler } from "./ContentItemHandler";
import { ImageHandlerData } from "./ImageHandlerData";
import { ImageItem, ImageEffect, ResizeGripsPermissions } from "@aurigma/design-atoms-model/Product/Items";
import { ImageUtils } from "../Utils/ImageUtils";
import Environment from "@aurigma/design-atoms-model/Utils/Environment";
import { ColorLessContainer, RgbColors } from "@aurigma/design-atoms-model";
import { EffectHandler } from "./EffectHandler";
export { ImageEffect };
export class ImageItemHandler extends ContentItemHandler {
constructor(item, textWhizz = null, apiClient, colorPreviewService, options) {
super(item, textWhizz, apiClient, colorPreviewService, options);
this._maxImageSize = 2000 * 2000;
this._imageResizedEvent = new EventWithSenderArg();
this._qualityChangeContainer = null;
this._qualityChangeScaleBar = null;
this._qualityChangeInfoBar = null;
if (this.item.source.type === ImageItem.ImageSourceType.Url)
this.loadImage(null, { downloadToServerCache: true, actualSize: this.item.source.actualSize, saveAspectRatio: this.item.source.saveAspectRatio });
}
get item() {
return this._getItem();
}
set item(item) {
super._setItem(item);
}
get needToDownloadImage() {
return this._needToDownloadImage;
}
set needToDownloadImage(v) {
this._needToDownloadImage = v;
}
get takeIntoAccountImageDpi() {
return this._takeIntoAccountImageDpi;
}
set takeIntoAccountImageDpi(v) {
this._takeIntoAccountImageDpi = v;
}
get sourceImageHorizontalResolution() {
return this._sourceImageHorizontalResolution;
}
set sourceImageHorizontalResolution(value) {
this._sourceImageHorizontalResolution = value;
}
get sourceImageVerticalResolution() {
return this._sourceImageVerticalResolution;
}
set sourceImageVerticalResolution(value) {
this._sourceImageVerticalResolution = value;
}
get qualityChangeScaleBar() {
return this._qualityChangeScaleBar;
}
set qualityChangeScaleBar(v) {
this._qualityChangeScaleBar = v;
}
get qualityChangeInfoBar() {
return this._qualityChangeInfoBar;
}
set qualityChangeInfoBar(v) {
this._qualityChangeInfoBar = v;
}
get qualityChangeContainer() {
return this._qualityChangeContainer;
}
set qualityChangeContainer(v) {
this._qualityChangeContainer = v;
}
get isQualityChangeBarEmpty() {
const canvas = this.canvas;
if (this._qualityChangeScaleBar == null || canvas == null)
return true;
if (this._qualityChangeScaleBar.className === this.canvas.qualityChangeScaleBarCssClass)
return true;
return false;
}
/**
* Loads an image from the external source using the specified parameters.
* @param sourceUrl The URL to load image from.
* @param options.actualSize specifies whether a size of the image item should be same as a size of loaded image
* @param options.saveAspectRatio specifies whether to decrease width or height of the ImageItemHandler to save aspect ratio of loaded image.
* @param options.downloadToServerCache specifies whether the bitmap should be loaded to the private cache
* @returns storage id of loaded image
*/
async loadImage(sourceUrl, options = {}) {
if (typeof sourceUrl != "string" && this.item.source.type !== ImageItem.ImageSourceType.Url)
console.error("Invalid sourceUrl: " + sourceUrl);
if (options.downloadToServerCache) {
this._needToDownloadImage = true;
this._actualSize = options.actualSize != null ? options.actualSize : false;
this._saveAspectRatio = options.saveAspectRatio != null ? options.saveAspectRatio : true;
this._sourceUrl = sourceUrl;
if (sourceUrl == null) {
this._sourceUrl = this.item.source.url;
}
await new Promise(resolve => this.update(null, resolve));
}
else {
this._needToDownloadImage = false;
this._setSrc(sourceUrl);
}
return this.item.source.id;
}
async loadImageFromRemoteUrl(remoteUrl, appDomainUrl = undefined) {
const imageData = await this._apiClient.getImageMetaDataFromRemoteUrl(remoteUrl, appDomainUrl);
this.item.source.id = imageData.storageId;
this.item.source.width = imageData.size.width;
this.item.source.height = imageData.size.height;
this.item.source.isVector = imageData.isVector;
this.item.name = imageData.name;
this.item.sourceRectangle.width = this.item.source.width;
this.item.sourceRectangle.height = this.item.source.height;
}
showEditButton() {
const baseValue = super.showEditToolbarButton();
return baseValue && !this.item.source.isVector;
}
addImageResized(handler) {
this._imageResizedEvent.add(handler);
}
removeImageResized(handler) {
this._imageResizedEvent.remove(handler);
}
onResized() {
const r = this.rectangle;
this._imageResizedEvent.notify(this, { Width: r.width, Height: r.height });
this.update();
return super.onResized();
}
setQualityChangeScaleBarWidth(progress) {
if (this._qualityChangeScaleBar == null)
return;
progress = Math.max(0, progress);
progress = Math.min(100, progress);
this._qualityChangeScaleBar.style.width = `${progress}%`;
}
setQualityChangeInfoBarText(value) {
if (this._qualityChangeInfoBar == null)
return;
this._qualityChangeInfoBar.innerText = value;
}
setBadToWarningChangeScaleBarClass() {
const canvas = this.canvas;
if (this._qualityChangeScaleBar == null || canvas == null)
return;
const oldClass = this._qualityChangeScaleBar.getAttribute("class");
const btwClassName = canvas.qualityBadToWarningChangeScaleBarCssClass;
if (btwClassName != null && btwClassName !== "")
this._qualityChangeScaleBar.classList.toggle(btwClassName, true);
const wtgClassName = canvas.qualityWarningToGoodChangeScaleBarCssClass;
if (wtgClassName != null && wtgClassName !== "")
this._qualityChangeScaleBar.classList.toggle(wtgClassName, false);
const btgwtgClassName = canvas.qualityBadToGoodChangeScaleBarCssClass;
if (btgwtgClassName != null && btgwtgClassName !== "")
this._qualityChangeScaleBar.classList.toggle(btgwtgClassName, false);
const naClassName = canvas.qualityNoAnimationChangeScaleBarCssClass;
if (naClassName != null && naClassName !== "")
this._qualityChangeScaleBar.classList.toggle(naClassName, this._qualityChangeScaleBar.getAttribute("class") !== oldClass);
this.canvas.updateViolationContainer(this);
}
setWarningToGoodChangeScaleBarClass() {
const canvas = this.canvas;
if (this._qualityChangeScaleBar == null || canvas == null)
return;
const oldClass = this._qualityChangeScaleBar.getAttribute("class");
const wtgClassName = canvas.qualityWarningToGoodChangeScaleBarCssClass;
if (wtgClassName != null && wtgClassName !== "")
this._qualityChangeScaleBar.classList.toggle(wtgClassName, true);
const btwClassName = canvas.qualityBadToWarningChangeScaleBarCssClass;
if (btwClassName != null && btwClassName !== "")
this._qualityChangeScaleBar.classList.toggle(btwClassName, false);
const btgwtgClassName = canvas.qualityBadToGoodChangeScaleBarCssClass;
if (btgwtgClassName != null && btgwtgClassName !== "")
this._qualityChangeScaleBar.classList.toggle(btgwtgClassName, false);
const naClassName = canvas.qualityNoAnimationChangeScaleBarCssClass;
if (naClassName != null && naClassName !== "")
this._qualityChangeScaleBar.classList.toggle(naClassName, this._qualityChangeScaleBar.getAttribute("class") !== oldClass);
this.canvas.updateViolationContainer(this);
}
setBadToGoodChangeScaleBarClass() {
const canvas = this.canvas;
if (this._qualityChangeScaleBar == null || canvas == null)
return;
const oldClass = this._qualityChangeScaleBar.getAttribute("class");
const btgwtgClassName = canvas.qualityBadToGoodChangeScaleBarCssClass;
if (btgwtgClassName != null && btgwtgClassName !== "")
this._qualityChangeScaleBar.classList.toggle(btgwtgClassName, true);
const btwClassName = canvas.qualityBadToWarningChangeScaleBarCssClass;
if (btwClassName != null && btwClassName !== "")
this._qualityChangeScaleBar.classList.toggle(btwClassName, false);
const wtgClassName = canvas.qualityWarningToGoodChangeScaleBarCssClass;
if (wtgClassName != null && wtgClassName !== "")
this._qualityChangeScaleBar.classList.toggle(wtgClassName, false);
const naClassName = canvas.qualityNoAnimationChangeScaleBarCssClass;
if (naClassName != null && naClassName !== "")
this._qualityChangeScaleBar.classList.toggle(naClassName, this._qualityChangeScaleBar.getAttribute("class") !== oldClass);
this.canvas.updateViolationContainer(this);
}
updateRectangle(keepLocation, resizeMode, parentPlaceholder, hiResOutputDpi) {
super.updateRectangle(keepLocation, resizeMode, parentPlaceholder, this.item.source.width, this.item.source.height, hiResOutputDpi);
}
async _updateImpl(beforeUpdate, afterUpdate) {
if (this._sourceUrl != undefined && this._sourceUrl != null) {
this._update([this._actualSize, this._saveAspectRatio, this._sourceUrl], beforeUpdate, afterUpdate);
if (this.item.source.id == null && this.item.source.url != null) {
this.updateRectangle(false, this.item.parentPlaceholder != null ? this.item.parentPlaceholder.contentResizeMode : null, this.parentPlaceholder);
}
}
else if (this.item.source.type === ImageItem.ImageSourceType.Url) {
this.loadImage(null, { downloadToServerCache: true, actualSize: this.item.source.actualSize, saveAspectRatio: this.item.source.saveAspectRatio }).then(() => {
if (this.canvas != null)
this.canvas.updateSelection();
});
}
else {
this.quickUpdate();
const canvas = this.canvas;
if (canvas != null)
canvas.updateSelection();
}
}
_getDrawingFillColor() {
return this.item.effect === ImageEffect.Colorize
? RgbColors.transparent
: this.item.fillColor;
}
_setDataItem(item, itemHandlerData) {
super._setDataItem(item, itemHandlerData);
const needUpdateRectangle = this.item.source.id == null && this.item.source.url != null;
this.item.source.id = item.source.id;
this.item.source.width = item.source.width;
this.item.source.height = item.source.height;
this.item.source.isVector = item.source.isVector;
this.item.source.pageIndex = item.source.pageIndex;
this.item.source.url = item.source.url;
if (needUpdateRectangle) {
this.updateRectangle(false, this.item.parentPlaceholder != null ? this.item.parentPlaceholder.contentResizeMode : null, this.parentPlaceholder);
this.update();
}
}
_onItemPropertyChanged(sender, propertyName) {
switch (propertyName) {
case "source":
this._sourceUrl = null;
this.update();
if (this.item.source.id == null && this.item.source.url != null) {
this.updateRectangle(false, this.item.parentPlaceholder != null ? this.item.parentPlaceholder.contentResizeMode : null, this.parentPlaceholder);
}
break;
case "fillColor":
if (this.item.effect === ImageEffect.Colorize)
this.update();
break;
case "effect":
case "overlayEffect":
this.update();
break;
default:
}
super._onItemPropertyChanged(sender, propertyName);
}
_getDefaultPermissions() {
const permissions = super._getDefaultPermissions();
permissions.manipulation.resizeGrips = new ResizeGripsPermissions(true, false);
return permissions;
}
_createDataInstance(itemHandler) {
return new ImageHandlerData(itemHandler);
}
_updateImageUrl() {
const canvas = this.canvas;
if (canvas == null)
return;
if (this.isVisible()) {
if (this.item.source.id == null || (this.item.source.width != null && this.item.source.height != null)) {
super._updateImageUrl();
return;
}
const onImageSizeUpdated = (data) => {
this.item.source.width = data.width;
this.item.source.height = data.height;
if (this._saveAspectRatio) {
const imageRatioWtoH = this.item.source.width / this.item.source.height;
if (this.width < this.height)
this.height = this.width / imageRatioWtoH;
else
this.width = this.height * imageRatioWtoH;
}
super._updateImageUrl();
};
const onFailureImageSizeUpdate = (errData) => {
if (window.console) {
console.error("Unable GetimageSize of image with id " + this.item.source.id);
console.error(errData);
}
};
canvas.service.GetImageSize(this.item.source.id, this.item.source.pageIndex, onImageSizeUpdated, onFailureImageSizeUpdate);
}
}
_createImageUrl() {
const sourceId = this.item.source.id;
if (sourceId == null)
return null;
if (this.canvas == null)
return null;
let pixelWidth;
let pixelHeight;
const zoom = this.canvas.zoom;
const xDpi = Environment.screenDpi;
const yDpi = Environment.screenDpi;
const pttopxX = zoom * xDpi / 72;
const pttopxY = zoom * yDpi / 72;
const rect = this.rectangle;
pixelWidth = rect.width * pttopxX;
pixelHeight = rect.height * pttopxY;
const isUpscaleRequired = EffectHandler.isUpscaleRequired(this.item.effect);
const isBackendEffect = EffectHandler.isBackendEffect(this.item.effect);
// TODO: Temporary fix - Image source for PDF files can be small, the preview in viewer is of low quality
// TODO: If `isVectorFormat` check is removed, previews for small raster images will not be cached, leading to their re-generation each time
const isVectorFormat = this.item.source.id.includes(".pdf") || this.item.source.id.includes(".ai");
if (!this.item.source.isVector && !isVectorFormat) {
if (isUpscaleRequired) {
const hiresDpi = 300; // TODO: must use hires dpi from rendering config
const hiresW = rect.width * hiresDpi / 72;
const hiresH = rect.height * hiresDpi / 72;
if (pixelWidth > hiresW || pixelHeight > hiresH) {
pixelWidth = Math.min(pixelWidth, hiresW);
pixelHeight = Math.min(pixelHeight, hiresH);
}
}
else {
pixelWidth = Math.min(pixelWidth, this.item.source.width);
pixelHeight = Math.min(pixelHeight, this.item.source.height);
}
}
let f = this._maxImageSize / pixelWidth / pixelHeight;
if (f < 1) {
f = Math.sqrt(f);
pixelWidth = pixelWidth * f;
pixelHeight = pixelHeight * f;
}
pixelWidth = Math.max(1, Math.round(pixelWidth));
pixelHeight = Math.max(1, Math.round(pixelHeight));
this._pixelWidth = pixelWidth;
this._pixelHeight = pixelHeight;
const ditherSettings = this._getDitherSettings();
let ditherType = ditherSettings.ditherType;
let ditherAmount = ditherSettings.ditherAmount;
return ImageUtils.getImageUrl(this.canvas.renderingConfigProvider, this.canvas.designAtomsApiClient, sourceId, pixelWidth, pixelHeight, false, this.item.effect, false, this.item.overlayEffect, this.item.source.pageIndex, !this.isNormalRenderingType, this.item.fillColor, isBackendEffect, rect.width, rect.height, ditherType, ditherAmount);
}
_getColorLessContainer() {
var _a;
if (this.item.parentContainer instanceof ColorLessContainer)
return this.item.parentContainer;
if (((_a = this.item.parentPlaceholder) === null || _a === void 0 ? void 0 : _a.parentContainer) instanceof ColorLessContainer)
return this.item.parentPlaceholder.parentContainer;
return null;
}
_getDitherSettings() {
const container = this._getColorLessContainer();
if (!container)
return { ditherType: null, ditherAmount: null };
return {
ditherType: container.dither != null ? container.dither.toString() : null,
ditherAmount: container.amount != null ? container.amount : null
};
}
}
ImageItemHandler.typeName = "ImageItemHandler";
//# sourceMappingURL=ImageItemHandler.js.map