import {CenteredPanZoom} from './CenteredPanZoom'; import {createSignal, ParentProps} from "solid-js"; export interface PannerProps { width: number; height: number; scale: number; contentSize: { width: number; height: number; }; onScale?: (scale: number) => any; } export const Panner = (props: ParentProps) => { const panner = new CenteredPanZoom({ screenHeight: props.height, screenWidth: props.width, scale: props.scale, contentSize: props.contentSize }); const [scale, setScale] = createSignal(props.scale); const [translateX, setTranslateX] = createSignal(Math.floor(panner.viewport.x)); const [translateY, setTranslateY] = createSignal(Math.floor(panner.viewport.y)); let startX = 0; let startY = 0; const mouseMove = (event) => { const {pageX, pageY} = event; panner.panFrom( { x: startX, y: startY }, { x: pageX, y: pageY } ); startX = event.pageX; startY = event.pageY; setTranslateX(Math.floor(panner.viewport.x)); setTranslateY(Math.floor(panner.viewport.y)); setScale(panner.scale); } const mouseDown = (event) => { startX = event.pageX; startY = event.pageY; const mouseUp = () => { document.removeEventListener('mouseup', mouseUp, true); document.removeEventListener('mousemove', mouseMove, true); }; document.addEventListener('mouseup', mouseUp, true); document.addEventListener('mousemove', mouseMove, true); } const applyZoom = (factor: number, center) => { panner.zoom(factor, center); setTranslateX(panner.viewport.x); setTranslateY(panner.viewport.y); setScale(panner.scale); props.onScale(panner.scale); } const mouseWheel = (event) => { event.preventDefault(); const center = {x: event.pageX, y: event.pageY}; let zoomFactor = (event.deltaY < 0) ? 1.05 : 0.95; const factor = scale() * zoomFactor; applyZoom(factor, center); } const center = () => ({ x: Math.floor(panner.screen.width / 2), y: Math.floor(panner.screen.height / 2) }); const pannerStyle = () => { return {width: `${props.width}px`, height: `${props.height}px`} }; return (
{props.children}
{ applyZoom(1.10, center()) }}>+
{ applyZoom(0.90, center()) }}> -
); }