UNPKG

phx-react

Version:

PHX REACT

177 lines • 8.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ImageResizer; const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const react_1 = require("react"); function clamp(value, min, max) { return Math.min(Math.max(value, min), max); } const Direction = { east: 1 << 0, north: 1 << 3, south: 1 << 1, west: 1 << 2, }; function ImageResizer({ editor, imageRef, maxWidth, onResizeEnd, onResizeStart, }) { const controlWrapperRef = (0, react_1.useRef)(null); const userSelect = (0, react_1.useRef)({ priority: '', value: 'default', }); const positioningRef = (0, react_1.useRef)({ currentHeight: 0, currentWidth: 0, direction: 0, isResizing: false, ratio: 0, startHeight: 0, startWidth: 0, startX: 0, startY: 0, }); const editorRootElement = editor.getRootElement(); // Find max width, accounting for editor padding. const maxWidthContainer = maxWidth ? maxWidth : editorRootElement !== null ? editorRootElement.getBoundingClientRect().width - 20 : 100; const maxHeightContainer = editorRootElement !== null ? editorRootElement.getBoundingClientRect().height - 20 : 100; const minWidth = 100; const minHeight = 100; const setStartCursor = (direction) => { const ew = direction === Direction.east || direction === Direction.west; const ns = direction === Direction.north || direction === Direction.south; const nwse = (direction & Direction.north && direction & Direction.west) || (direction & Direction.south && direction & Direction.east); const cursorDir = ew ? 'ew' : ns ? 'ns' : nwse ? 'nwse' : 'nesw'; if (editorRootElement !== null) { editorRootElement.style.setProperty('cursor', `${cursorDir}-resize`, 'important'); } if (document.body !== null) { document.body.style.setProperty('cursor', `${cursorDir}-resize`, 'important'); userSelect.current.value = document.body.style.getPropertyValue('-webkit-user-select'); userSelect.current.priority = document.body.style.getPropertyPriority('-webkit-user-select'); document.body.style.setProperty('-webkit-user-select', `none`, 'important'); } }; const setEndCursor = () => { if (editorRootElement !== null) { editorRootElement.style.setProperty('cursor', 'text'); } if (document.body !== null) { document.body.style.setProperty('cursor', 'default'); document.body.style.setProperty('-webkit-user-select', userSelect.current.value, userSelect.current.priority); } }; const handlePointerMove = (event) => { const image = imageRef.current; const positioning = positioningRef.current; const isHorizontal = positioning.direction & (Direction.east | Direction.west); const isVertical = positioning.direction & (Direction.south | Direction.north); if (image !== null && positioning.isResizing) { // Corner cursor if (isHorizontal && isVertical) { let diff = Math.floor(positioning.startX - event.clientX); diff = positioning.direction & Direction.east ? -diff : diff; const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer); const height = width / positioning.ratio; image.style.width = `${width}px`; image.style.height = `${height}px`; positioning.currentHeight = height; positioning.currentWidth = width; } else if (isVertical) { let diff = Math.floor(positioning.startY - event.clientY); diff = positioning.direction & Direction.south ? -diff : diff; const height = clamp(positioning.startHeight + diff, minHeight, maxHeightContainer); image.style.height = `${height}px`; positioning.currentHeight = height; } else { let diff = Math.floor(positioning.startX - event.clientX); diff = positioning.direction & Direction.east ? -diff : diff; const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer); image.style.width = `${width}px`; positioning.currentWidth = width; } } }; const handlePointerUp = () => { const image = imageRef.current; const positioning = positioningRef.current; const controlWrapper = controlWrapperRef.current; if (image !== null && controlWrapper !== null && positioning.isResizing) { const width = positioning.currentWidth; const height = positioning.currentHeight; positioning.startWidth = 0; positioning.startHeight = 0; positioning.ratio = 0; positioning.startX = 0; positioning.startY = 0; positioning.currentWidth = 0; positioning.currentHeight = 0; positioning.isResizing = false; controlWrapper.classList.remove('image-control-wrapper--resizing'); setEndCursor(); onResizeEnd(width, height); document.removeEventListener('pointermove', handlePointerMove); document.removeEventListener('pointerup', handlePointerUp); } }; const handlePointerDown = (event, direction) => { if (!editor.isEditable()) { return; } const image = imageRef.current; const controlWrapper = controlWrapperRef.current; if (image !== null && controlWrapper !== null) { event.preventDefault(); const { height, width } = image.getBoundingClientRect(); const positioning = positioningRef.current; positioning.startWidth = width; positioning.startHeight = height; positioning.ratio = width / height; positioning.currentWidth = width; positioning.currentHeight = height; positioning.startX = event.clientX; positioning.startY = event.clientY; positioning.isResizing = true; positioning.direction = direction; setStartCursor(direction); onResizeStart(); controlWrapper.classList.add('image-control-wrapper--resizing'); image.style.height = `${height}px`; image.style.width = `${width}px`; document.addEventListener('pointermove', handlePointerMove); document.addEventListener('pointerup', handlePointerUp); } }; return (React.createElement("div", { className: 'image-resizer-wrapper', ref: controlWrapperRef }, React.createElement("div", { className: 'image-resizer image-resizer-n', onPointerDown: (event) => { handlePointerDown(event, Direction.north); } }), React.createElement("div", { className: 'image-resizer image-resizer-ne', onPointerDown: (event) => { handlePointerDown(event, Direction.north | Direction.east); } }), React.createElement("div", { className: 'image-resizer image-resizer-e', onPointerDown: (event) => { handlePointerDown(event, Direction.east); } }), React.createElement("div", { className: 'image-resizer image-resizer-se', onPointerDown: (event) => { handlePointerDown(event, Direction.south | Direction.east); } }), React.createElement("div", { className: 'image-resizer image-resizer-s', onPointerDown: (event) => { handlePointerDown(event, Direction.south); } }), React.createElement("div", { className: 'image-resizer image-resizer-sw', onPointerDown: (event) => { handlePointerDown(event, Direction.south | Direction.west); } }), React.createElement("div", { className: 'image-resizer image-resizer-w', onPointerDown: (event) => { handlePointerDown(event, Direction.west); } }), React.createElement("div", { className: 'image-resizer image-resizer-nw', onPointerDown: (event) => { handlePointerDown(event, Direction.north | Direction.west); } }))); } //# sourceMappingURL=ImageResizer.js.map