import React, {createRef, useCallback, useEffect, useState} from 'react'; import {PreviewButtonStyle, PreviewStyle} from "./design-preview.style.js"; let startDragPosition = {x: 0, y: 0}; export function DesignPreview({previewOption = {widthDimension: 0}}) { const reference = createRef(); const [active, setActive] = useState(false); const [position, setPosition] = useState({x: getInitialXPosition(previewOption), y: 0}); const [opacity, setOpacity] = useState(85); const keyDownHandler = useCallback( function (e) { if (!active) { return; } const step = e.shiftKey ? 10 : 1; if (e.key === 'ArrowUp') { updatePosition({y: step * -1}, true) } else if (e.key === 'ArrowDown') { updatePosition({y: step}, true) } else if (e.key === 'ArrowLeft') { updatePosition({x: step * -1}, true) } else if (e.key === 'ArrowRight') { updatePosition({x: step}, true) } }, [position, active]); useEffect(() => { document.addEventListener('keydown', keyDownHandler); return () => { document.removeEventListener('keydown', keyDownHandler) } }, [keyDownHandler]); useEffect(() => { updatePosition({x: getInitialXPosition(previewOption), y: 0}); window.addEventListener('message', responsiveModeChangesHandler); return () => window.removeEventListener('message', responsiveModeChangesHandler); }, [previewOption.widthDimension]); if (!previewOption) { return; } const disabled = !previewOption.url; const classNames = []; if (!disabled && active) { classNames.push('active'); } if (disabled) { classNames.push('disabled'); } const handleOpacityChange = (e) => { setOpacity(e.target.value); } return <> toggle()} className={classNames.join(' ')} disabled={disabled}/> {active && !disabled && <> stop(e)} style={{opacity: opacity / 100}}> start(e)} draggable={false} style={{top: position.y + 'px', left: position.x + 'px'}} /> } // // Functions // function start(e) { startDragPosition.x = e.clientX; startDragPosition.y = e.clientY; document.body.addEventListener('mousemove', handler); } function stop(e) { const target = reference.current; updatePosition({x: target.offsetLeft, y: target.offsetTop}); document.body.removeEventListener('mousemove', handler); } function handler(e) { const target = reference.current; if (target) { const updatedPosition = { x: target.offsetLeft - (startDragPosition.x - e.clientX), y: target.offsetTop - (startDragPosition.y - e.clientY), }; target.style.left = updatedPosition.x + 'px'; target.style.top = updatedPosition.y + 'px'; startDragPosition.x = e.clientX; startDragPosition.y = e.clientY; } } function toggle() { setActive(!active); } function updatePosition({x, y}, relative = false) { x = typeof x === 'undefined' ? position.x : relative ? position.x + x : x; y = typeof y === 'undefined' ? position.y : relative ? position.y + y : y; setPosition({x, y}) } function getInitialXPosition(previewOption) { if (!previewOption) { return 0; } // const scrollbarOffset = 7; // Looks like browser scrollbar is not included in the width calculation anymore. const scrollbarOffset = 0; return window.innerWidth / 2 - previewOption.widthDimension / 2 - scrollbarOffset; } function responsiveModeChangesHandler(e) { if (e.data !== 'responsiveUpdate') { return; } if (window.responsiveState.breakpoint === '100%') { updatePosition({x: getInitialXPosition(previewOption), y: 0}); } } }