WIP reordering tiles
This commit is contained in:
parent
e5d31b70f0
commit
d763b4a83c
1 changed files with 71 additions and 14 deletions
|
|
@ -1,10 +1,25 @@
|
||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import classNames from "classnames";
|
|
||||||
import { useDrag } from "react-use-gesture";
|
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 styles from "./GridDemo.module.css";
|
||||||
import useMeasure from "react-use-measure";
|
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() {
|
export function GridDemo() {
|
||||||
const tileKey = useRef(0);
|
const tileKey = useRef(0);
|
||||||
const [stream, setStream] = useState();
|
const [stream, setStream] = useState();
|
||||||
|
|
@ -14,6 +29,10 @@ export function GridDemo() {
|
||||||
});
|
});
|
||||||
const draggingTileRef = useRef(null);
|
const draggingTileRef = useRef(null);
|
||||||
|
|
||||||
|
// Contains tile indices
|
||||||
|
// Tiles are displayed in the order that they appear
|
||||||
|
const tileOrderRef = useRef([]);
|
||||||
|
|
||||||
const [gridRef, gridBounds] = useMeasure();
|
const [gridRef, gridBounds] = useMeasure();
|
||||||
|
|
||||||
const getTilePositions = useCallback((tiles, gridBounds) => {
|
const getTilePositions = useCallback((tiles, gridBounds) => {
|
||||||
|
|
@ -111,6 +130,7 @@ export function GridDemo() {
|
||||||
const startWebcam = useCallback(async () => {
|
const startWebcam = useCallback(async () => {
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
||||||
setStream(stream);
|
setStream(stream);
|
||||||
|
tileOrderRef.current.push(tileOrderRef.current.length);
|
||||||
setTileState(() => {
|
setTileState(() => {
|
||||||
const tiles = [{ stream, key: tileKey.current++ }];
|
const tiles = [{ stream, key: tileKey.current++ }];
|
||||||
const tilePositions = getTilePositions(tiles, gridBounds);
|
const tilePositions = getTilePositions(tiles, gridBounds);
|
||||||
|
|
@ -121,6 +141,8 @@ export function GridDemo() {
|
||||||
const addTile = useCallback(() => {
|
const addTile = useCallback(() => {
|
||||||
const newStream = stream.clone();
|
const newStream = stream.clone();
|
||||||
|
|
||||||
|
tileOrderRef.current.push(tileOrderRef.current.length);
|
||||||
|
|
||||||
setTileState(({ tiles }) => {
|
setTileState(({ tiles }) => {
|
||||||
const newTiles = [
|
const newTiles = [
|
||||||
...tiles,
|
...tiles,
|
||||||
|
|
@ -132,6 +154,7 @@ export function GridDemo() {
|
||||||
}, [stream, gridBounds]);
|
}, [stream, gridBounds]);
|
||||||
|
|
||||||
const removeTile = useCallback(() => {
|
const removeTile = useCallback(() => {
|
||||||
|
tileOrderRef.current.pop();
|
||||||
setTileState(({ tiles }) => {
|
setTileState(({ tiles }) => {
|
||||||
const newTiles = [...tiles];
|
const newTiles = [...tiles];
|
||||||
newTiles.pop();
|
newTiles.pop();
|
||||||
|
|
@ -148,11 +171,12 @@ export function GridDemo() {
|
||||||
}, [gridBounds]);
|
}, [gridBounds]);
|
||||||
|
|
||||||
const animate = useCallback(
|
const animate = useCallback(
|
||||||
(index) => {
|
(order) => (index) => {
|
||||||
const tilePosition = tilePositions[index];
|
const tileIndex = order[index];
|
||||||
|
const tilePosition = tilePositions[tileIndex];
|
||||||
const draggingTile = draggingTileRef.current;
|
const draggingTile = draggingTileRef.current;
|
||||||
const dragging =
|
const dragging =
|
||||||
draggingTileRef.current && index === draggingTileRef.current.index;
|
draggingTileRef.current && tileIndex === draggingTileRef.current.index;
|
||||||
|
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
return {
|
return {
|
||||||
|
|
@ -178,32 +202,65 @@ export function GridDemo() {
|
||||||
[tilePositions]
|
[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) {
|
if (active) {
|
||||||
draggingTileRef.current = {
|
draggingTileRef.current = {
|
||||||
index,
|
index: dragIndex,
|
||||||
x,
|
x: movement[0],
|
||||||
y,
|
y: movement[1],
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
draggingTileRef.current = null;
|
draggingTileRef.current = null;
|
||||||
|
//tileOrderRef.current = order;
|
||||||
}
|
}
|
||||||
|
|
||||||
api.start(animate);
|
api.start(animate(order));
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.gridDemo}>
|
<div className={styles.gridDemo}>
|
||||||
<div className={styles.buttons}>
|
<div className={styles.buttons}>
|
||||||
{!stream && <button onClick={startWebcam}>Start Webcam</button>}
|
{!stream && <button onClick={startWebcam}>Start Webcam</button>}
|
||||||
{stream && <button onClick={addTile}>Add Tile</button>}
|
{stream && tiles.length < 12 && (
|
||||||
{stream && <button onClick={removeTile}>Remove Tile</button>}
|
<button onClick={addTile}>Add Tile</button>
|
||||||
|
)}
|
||||||
|
{stream && tiles.length > 0 && (
|
||||||
|
<button onClick={removeTile}>Remove Tile</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.grid} ref={gridRef}>
|
<div className={styles.grid} ref={gridRef}>
|
||||||
{springs.map(({ shadow, ...style }, i) => {
|
{springs.map(({ shadow, ...style }, i) => {
|
||||||
const tile = tiles[i];
|
const tileIndex = tileOrderRef.current[i];
|
||||||
|
const tile = tiles[tileIndex];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ParticipantTile
|
<ParticipantTile
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue