diff --git a/src/GridDemo.jsx b/src/GridDemo.jsx index b920e86a..e6134be5 100644 --- a/src/GridDemo.jsx +++ b/src/GridDemo.jsx @@ -1,10 +1,25 @@ import React, { useCallback, useEffect, useRef, useState } from "react"; -import classNames from "classnames"; import { useDrag } from "react-use-gesture"; -import { useSprings, useTransition, animated } from "@react-spring/web"; +import { useSprings, animated } from "@react-spring/web"; import styles from "./GridDemo.module.css"; import useMeasure from "react-use-measure"; +function isInside([x, y], dragTile, targetTile) { + const cursorX = dragTile.x + x; + const cursorY = dragTile.y + y; + + const left = targetTile.x; + const top = targetTile.y; + const bottom = targetTile.y + targetTile.height; + const right = targetTile.x + targetTile.width; + + if (cursorX < left || cursorX > right || cursorY < top || cursorY > bottom) { + return false; + } + + return true; +} + export function GridDemo() { const tileKey = useRef(0); const [stream, setStream] = useState(); @@ -14,6 +29,10 @@ export function GridDemo() { }); const draggingTileRef = useRef(null); + // Contains tile indices + // Tiles are displayed in the order that they appear + const tileOrderRef = useRef([]); + const [gridRef, gridBounds] = useMeasure(); const getTilePositions = useCallback((tiles, gridBounds) => { @@ -111,6 +130,7 @@ export function GridDemo() { const startWebcam = useCallback(async () => { const stream = await navigator.mediaDevices.getUserMedia({ video: true }); setStream(stream); + tileOrderRef.current.push(tileOrderRef.current.length); setTileState(() => { const tiles = [{ stream, key: tileKey.current++ }]; const tilePositions = getTilePositions(tiles, gridBounds); @@ -121,6 +141,8 @@ export function GridDemo() { const addTile = useCallback(() => { const newStream = stream.clone(); + tileOrderRef.current.push(tileOrderRef.current.length); + setTileState(({ tiles }) => { const newTiles = [ ...tiles, @@ -132,6 +154,7 @@ export function GridDemo() { }, [stream, gridBounds]); const removeTile = useCallback(() => { + tileOrderRef.current.pop(); setTileState(({ tiles }) => { const newTiles = [...tiles]; newTiles.pop(); @@ -148,11 +171,12 @@ export function GridDemo() { }, [gridBounds]); const animate = useCallback( - (index) => { - const tilePosition = tilePositions[index]; + (order) => (index) => { + const tileIndex = order[index]; + const tilePosition = tilePositions[tileIndex]; const draggingTile = draggingTileRef.current; const dragging = - draggingTileRef.current && index === draggingTileRef.current.index; + draggingTileRef.current && tileIndex === draggingTileRef.current.index; if (dragging) { return { @@ -178,32 +202,65 @@ export function GridDemo() { [tilePositions] ); - const [springs, api] = useSprings(tiles.length, animate, [tilePositions]); + const [springs, api] = useSprings( + tiles.length, + animate(tileOrderRef.current), + [tilePositions] + ); + + const bind = useDrag(({ args: [index], active, movement }) => { + let order = tileOrderRef.current; + let dragIndex = index; + + // const tileIndex = tileOrderRef.current[index]; + // const tilePosition = tilePositions[tileIndex]; + + // for (let i = 0; i < tileOrderRef.current.length; i++) { + // if (i === index) { + // continue; + // } + + // const hoverTileIndex = tileOrderRef.current[i]; + // const hoverTilePosition = tilePositions[hoverTileIndex]; + + // if (isInside(movement, tilePosition, hoverTilePosition)) { + // order = [...tileOrderRef.current]; + // const [toBeMoved] = order.splice(i, 1); + // order.splice(index, 0, toBeMoved); + // dragIndex = i; + // break; + // } + // } - const bind = useDrag(({ args: [index], active, movement: [x, y] }) => { if (active) { draggingTileRef.current = { - index, - x, - y, + index: dragIndex, + x: movement[0], + y: movement[1], }; } else { draggingTileRef.current = null; + //tileOrderRef.current = order; } - api.start(animate); + api.start(animate(order)); }); return (