UNPKG

@cropper/element-shade

Version:
134 lines (130 loc) 4.83 kB
import CropperElement from '@cropper/element'; import { CROPPER_SHADE, CROPPER_CANVAS, CROPPER_SELECTION, ACTION_SELECT, on, EVENT_ACTION_START, EVENT_ACTION_END, EVENT_CHANGE, off, isNumber, WINDOW } from '@cropper/utils'; var style = `:host{display:block;height:0;left:0;outline:var(--theme-color) solid 1px;position:relative;top:0;width:0}:host([transparent]){outline-color:transparent}`; const canvasCache = new WeakMap(); class CropperShade extends CropperElement { constructor() { super(...arguments); this.$onCanvasChange = null; this.$onCanvasActionEnd = null; this.$onCanvasActionStart = null; this.$style = style; this.x = 0; this.y = 0; this.width = 0; this.height = 0; this.slottable = false; this.themeColor = 'rgba(0, 0, 0, 0.65)'; } set $canvas(element) { canvasCache.set(this, element); } get $canvas() { return canvasCache.get(this); } static get observedAttributes() { return super.observedAttributes.concat([ 'height', 'width', 'x', 'y', ]); } connectedCallback() { super.connectedCallback(); const $canvas = this.closest(this.$getTagNameOf(CROPPER_CANVAS)); if ($canvas) { this.$canvas = $canvas; this.style.position = 'absolute'; const $selection = $canvas.querySelector(this.$getTagNameOf(CROPPER_SELECTION)); if ($selection) { this.$onCanvasActionStart = (event) => { if ($selection.hidden && event.detail.action === ACTION_SELECT) { this.hidden = false; } }; this.$onCanvasActionEnd = (event) => { if ($selection.hidden && event.detail.action === ACTION_SELECT) { this.hidden = true; } }; this.$onCanvasChange = (event) => { const { x, y, width, height, } = event.detail; this.$change(x, y, width, height); if ($selection.hidden || (x === 0 && y === 0 && width === 0 && height === 0)) { this.hidden = true; } }; on($canvas, EVENT_ACTION_START, this.$onCanvasActionStart); on($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd); on($canvas, EVENT_CHANGE, this.$onCanvasChange); } } this.$render(); } disconnectedCallback() { const { $canvas } = this; if ($canvas) { if (this.$onCanvasActionStart) { off($canvas, EVENT_ACTION_START, this.$onCanvasActionStart); this.$onCanvasActionStart = null; } if (this.$onCanvasActionEnd) { off($canvas, EVENT_ACTION_END, this.$onCanvasActionEnd); this.$onCanvasActionEnd = null; } if (this.$onCanvasChange) { off($canvas, EVENT_CHANGE, this.$onCanvasChange); this.$onCanvasChange = null; } } super.disconnectedCallback(); } /** * Changes the position and/or size of the shade. * @param {number} x The new position in the horizontal direction. * @param {number} y The new position in the vertical direction. * @param {number} [width] The new width. * @param {number} [height] The new height. * @returns {CropperShade} Returns `this` for chaining. */ $change(x, y, width = this.width, height = this.height) { if (!isNumber(x) || !isNumber(y) || !isNumber(width) || !isNumber(height) || (x === this.x && y === this.y && width === this.width && height === this.height)) { return this; } if (this.hidden) { this.hidden = false; } this.x = x; this.y = y; this.width = width; this.height = height; return this.$render(); } /** * Resets the shade to its initial position and size. * @returns {CropperShade} Returns `this` for chaining. */ $reset() { return this.$change(0, 0, 0, 0); } /** * Refreshes the position or size of the shade. * @returns {CropperShade} Returns `this` for chaining. */ $render() { return this.$setStyles({ transform: `translate(${this.x}px, ${this.y}px)`, width: this.width, height: this.height, outlineWidth: WINDOW.innerWidth, }); } } CropperShade.$name = CROPPER_SHADE; CropperShade.$version = '2.0.0'; export { CropperShade as default };