(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@cropper/element'), require('@cropper/utils')) : typeof define === 'function' && define.amd ? define(['exports', '@cropper/element', '@cropper/utils'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.CropperViewer = {}, global.CropperElement, global.CropperUtils)); })(this, (function (exports, CropperElement, utils) { 'use strict'; function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var CropperElement__default = /*#__PURE__*/_interopDefaultLegacy(CropperElement); var style = `:host{display:block;height:100%;overflow:hidden;position:relative;width:100%}`; const canvasCache = new WeakMap(); const imageCache = new WeakMap(); const selectionCache = new WeakMap(); const sourceImageCache = new WeakMap(); const RESIZE_BOTH = 'both'; const RESIZE_HORIZONTAL = 'horizontal'; const RESIZE_VERTICAL = 'vertical'; const RESIZE_NONE = 'none'; class CropperViewer extends CropperElement__default["default"] { constructor() { super(...arguments); this.$onSelectionChange = null; this.$onSourceImageLoad = null; this.$onSourceImageTransform = null; this.$scale = 1; this.$style = style; this.resize = RESIZE_VERTICAL; this.selection = ''; this.slottable = false; } set $image(element) { imageCache.set(this, element); } get $image() { return imageCache.get(this); } set $sourceImage(element) { sourceImageCache.set(this, element); } get $sourceImage() { return sourceImageCache.get(this); } set $canvas(element) { canvasCache.set(this, element); } get $canvas() { return canvasCache.get(this); } set $selection(element) { selectionCache.set(this, element); } get $selection() { return selectionCache.get(this); } static get observedAttributes() { return super.observedAttributes.concat([ 'resize', 'selection', ]); } connectedCallback() { super.connectedCallback(); let $selection = null; if (this.selection) { $selection = this.ownerDocument.querySelector(this.selection); } else { $selection = this.closest(this.$getTagNameOf(utils.CROPPER_SELECTION)); } if (utils.isElement($selection)) { this.$selection = $selection; this.$onSelectionChange = this.$handleSelectionChange.bind(this); utils.on($selection, utils.EVENT_CHANGE, this.$onSelectionChange); const $canvas = $selection.closest(this.$getTagNameOf(utils.CROPPER_CANVAS)); if ($canvas) { this.$canvas = $canvas; const $sourceImage = $canvas.querySelector(this.$getTagNameOf(utils.CROPPER_IMAGE)); if ($sourceImage) { this.$sourceImage = $sourceImage; this.$image = $sourceImage.cloneNode(true); this.$getShadowRoot().appendChild(this.$image); this.$onSourceImageLoad = this.$handleSourceImageLoad.bind(this); this.$onSourceImageTransform = this.$handleSourceImageTransform.bind(this); utils.on($sourceImage.$image, utils.EVENT_LOAD, this.$onSourceImageLoad); utils.on($sourceImage, utils.EVENT_TRANSFORM, this.$onSourceImageTransform); } } this.$render(); } } disconnectedCallback() { const { $selection, $sourceImage } = this; if ($selection && this.$onSelectionChange) { utils.off($selection, utils.EVENT_CHANGE, this.$onSelectionChange); this.$onSelectionChange = null; } if ($sourceImage && this.$onSourceImageLoad) { utils.off($sourceImage.$image, utils.EVENT_LOAD, this.$onSourceImageLoad); this.$onSourceImageLoad = null; } if ($sourceImage && this.$onSourceImageTransform) { utils.off($sourceImage, utils.EVENT_TRANSFORM, this.$onSourceImageTransform); this.$onSourceImageTransform = null; } super.disconnectedCallback(); } $handleSelectionChange(event) { this.$render(event.detail); } $handleSourceImageLoad() { const { $image, $sourceImage } = this; const oldSrc = $image.getAttribute('src'); const newSrc = $sourceImage.getAttribute('src'); if (newSrc && newSrc !== oldSrc) { $image.setAttribute('src', newSrc); $image.$ready(() => { setTimeout(() => { this.$render(); }, 50); }); } } $handleSourceImageTransform(event) { this.$render(undefined, event.detail.matrix); } $render(selection, matrix) { const { $canvas, $selection } = this; if (!selection && !$selection.hidden) { selection = $selection; } if (!selection || (selection.x === 0 && selection.y === 0 && selection.width === 0 && selection.height === 0)) { selection = { x: 0, y: 0, width: $canvas.offsetWidth, height: $canvas.offsetHeight, }; } const { x, y, width, height, } = selection; const styles = {}; const { clientWidth, clientHeight } = this; let newWidth = clientWidth; let newHeight = clientHeight; let scale = NaN; switch (this.resize) { case RESIZE_BOTH: scale = 1; newWidth = width; newHeight = height; styles.width = width; styles.height = height; break; case RESIZE_HORIZONTAL: scale = height > 0 ? clientHeight / height : 0; newWidth = width * scale; styles.width = newWidth; break; case RESIZE_VERTICAL: scale = width > 0 ? clientWidth / width : 0; newHeight = height * scale; styles.height = newHeight; break; case RESIZE_NONE: default: if (clientWidth > 0) { scale = width > 0 ? clientWidth / width : 0; } else if (clientHeight > 0) { scale = height > 0 ? clientHeight / height : 0; } } this.$scale = scale; this.$setStyles(styles); if (this.$sourceImage) { this.$transformImageByOffset(matrix !== null && matrix !== void 0 ? matrix : this.$sourceImage.$getTransform(), -x, -y); } } $transformImageByOffset(matrix, x, y) { const { $image, $scale, $sourceImage, } = this; if ($sourceImage && $image && $scale >= 0) { const [a, b, c, d, e, f] = matrix; const translateX = ((x * d) - (c * y)) / ((a * d) - (c * b)); const translateY = ((y * a) - (b * x)) / ((a * d) - (c * b)); const newE = a * translateX + c * translateY + e; const newF = b * translateX + d * translateY + f; $image.$ready((image) => { this.$setStyles.call($image, { width: image.naturalWidth * $scale, height: image.naturalHeight * $scale, }); }); $image.$setTransform(a, b, c, d, newE * $scale, newF * $scale); } } } CropperViewer.$name = utils.CROPPER_VIEWER; CropperViewer.$version = '2.0.0-rc.2'; exports.RESIZE_BOTH = RESIZE_BOTH; exports.RESIZE_HORIZONTAL = RESIZE_HORIZONTAL; exports.RESIZE_NONE = RESIZE_NONE; exports.RESIZE_VERTICAL = RESIZE_VERTICAL; exports["default"] = CropperViewer; Object.defineProperty(exports, '__esModule', { value: true }); }));