X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;f=resources%2Fjs%2Fcomponents%2Ftracker%2FCanvas.js;h=fab194219c7d56ec9dee81d34c27b5cce9a2c340;hb=e0925d5b97ab0804222195eb4231c63b33703942;hp=392f2a7dc63f35ca27af8bfc71476e96d9eecae3;hpb=90922f8595a8d4fd7780a0b137eed66eaf7d6c49;p=alttp.git diff --git a/resources/js/components/tracker/Canvas.js b/resources/js/components/tracker/Canvas.js index 392f2a7..fab1942 100644 --- a/resources/js/components/tracker/Canvas.js +++ b/resources/js/components/tracker/Canvas.js @@ -1,8 +1,12 @@ +import { drag } from 'd3-drag'; +import { select } from 'd3-selection'; import React from 'react'; import Dungeons from './Dungeons'; import Items from './Items'; import Map from './Map'; +import ToggleIcon from './ToggleIcon'; +import ZeldaIcon from '../common/ZeldaIcon'; import { shouldShowDungeonItem } from '../../helpers/tracker'; import { useTracker } from '../../hooks/tracker'; @@ -34,7 +38,8 @@ const LAYOUTS = { }; const Canvas = () => { - const { config } = useTracker(); + const [dragging, setDragging] = React.useState(null); + const { addPin, config, pins, removePin } = useTracker(); const layout = React.useMemo(() => { if (config.mapLayout === 'vertical') { @@ -57,6 +62,62 @@ const Canvas = () => { } }, [config]); + React.useEffect(() => { + const canvas = select('.canvas'); + const bbox = canvas.select('.background'); + const start = { x: 0, y: 0 }; + const onStart = function (e) { + const bounds = bbox.node().getBoundingClientRect(); + start.x = e.x; + start.y = e.y; + setDragging({ + icon: this.dataset['icon'], + x: (e.x - bounds.x) / bounds.width, + y: (e.y - bounds.y) / bounds.height, + }); + }; + const onDrag = function (e) { + const bounds = bbox.node().getBoundingClientRect(); + setDragging({ + icon: this.dataset['icon'], + x: (e.x - bounds.x) / bounds.width, + y: (e.y - bounds.y) / bounds.height, + }); + }; + const onEnd = function (e) { + const bounds = bbox.node().getBoundingClientRect(); + setDragging(null); + const distance = Math.max(Math.abs(e.x - start.x), Math.abs(e.y - start.y)); + if (distance > 5) { + addPin({ + icon: this.dataset['icon'], + x: (e.x - bounds.x) / bounds.width, + y: (e.y - bounds.y) / bounds.height, + }); + if (this.classList.contains('map-pin')) { + let id = 0; + this.classList.forEach(name => { + if (name.startsWith('map-pin-')) { + id = parseInt(name.substr(8), 10); + } + }); + removePin({ id }); + } + } + }; + const selection = canvas.selectAll('.toggle-icon'); + const draggable = drag() + .container(bbox) + .clickDistance(5) + .on('start', onStart) + .on('drag', onDrag) + .on('end', onEnd); + selection.call(draggable); + return () => { + selection.on('.drag', null); + }; + }, [pins, removePin]); + return { e.stopPropagation(); }} > + @@ -77,6 +145,30 @@ const Canvas = () => { + + {pins.map(pin => + + + + )} + + {dragging ? + + + + : null} ; };