UNPKG

devexpress-reporting

Version:

DevExpress Reporting provides the capability to develop a reporting application to create and customize reports.

86 lines (85 loc) 4.07 kB
/** * DevExpress HTML/JS Reporting (viewer\widgets\pictureEditor\_imagePainter.js) * Version: 24.2.6 * Build date: Mar 18, 2025 * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * License: https://www.devexpress.com/Support/EULAs/universal.xml */ import { ImageAlignment, ImageSizeMode } from '../../editing/editingField'; export class ImagePainter { _drawImage(imageSource, context, scale, contentSize) { return new Promise((resolve, reject) => { if (!imageSource) { resolve(); return; } const background = new Image(); let prefix = 'data:image/' + (this.format || 'png') + ';base64,'; if (this.format === 'svg') { prefix = 'data:image/svg+xml;charset=UTF-8;base64,'; } const imageBase64 = imageSource.indexOf('base64,') !== -1 ? imageSource : prefix + imageSource; background.src = imageBase64; background.onload = () => { if (imageSource !== this.image()) { reject(); return; } const size = this._getImageSize(background, scale, contentSize); const location = this._getImageCoordinate(size, contentSize); context.drawImage(background, location.x, location.y, size.width, size.height); resolve(); }; background.onerror = (error) => { reject(error); }; }); } _getImageSize(image, scale, contentSize) { const sizeMode = this.sizeMode(); let width = image.width * scale, height = image.height * scale; if (sizeMode === ImageSizeMode.StretchImage) { width = contentSize.width; height = contentSize.height; } else if (sizeMode === ImageSizeMode.Cover || sizeMode === ImageSizeMode.ZoomImage || (sizeMode === ImageSizeMode.Squeeze && (contentSize.width < width || contentSize.height < height))) { const ratio = (sizeMode === ImageSizeMode.Cover ? Math.max : Math.min)(contentSize.width / width, contentSize.height / height); width *= ratio; height *= ratio; } return { width: width, height: height }; } _getImageCoordinate(imageSize, contentSize) { let alignment = this.alignment(); let x = 0, y = 0; if (!(alignment in ImageAlignment) && (this.sizeMode() === ImageSizeMode.Cover || this.sizeMode() === ImageSizeMode.ZoomImage || this.sizeMode() === ImageSizeMode.Squeeze)) { alignment = ImageAlignment.MiddleCenter; } if (alignment === ImageAlignment.MiddleLeft || alignment === ImageAlignment.MiddleCenter || alignment === ImageAlignment.MiddleRight) { y = (contentSize.height - imageSize.height) / 2; } else if (alignment === ImageAlignment.BottomLeft || alignment === ImageAlignment.BottomCenter || alignment === ImageAlignment.BottomRight) { y = contentSize.height - imageSize.height; } if (alignment === ImageAlignment.TopCenter || alignment === ImageAlignment.MiddleCenter || alignment === ImageAlignment.BottomCenter) { x = (contentSize.width - imageSize.width) / 2; } else if (alignment === ImageAlignment.TopRight || alignment === ImageAlignment.MiddleRight || alignment === ImageAlignment.BottomRight) { x = contentSize.width - imageSize.width; } return { x: x, y: y }; } constructor(options) { this.image = options.imageSource; this.sizeMode = options.sizeMode; this.alignment = options.alignment; } refresh(context, scale = 1, contentSize) { contentSize = contentSize || { width: context.canvas.width, height: context.canvas.height }; return this._drawImage(this.image(), context, scale, contentSize) .catch((error) => { error?.message && console.warn(error.message); }); } }