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.

370 lines 18.2 kB
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