Finished grid demo
This commit is contained in:
parent
e68c9bee4a
commit
f303cb345f
4 changed files with 88 additions and 30 deletions
27
package-lock.json
generated
27
package-lock.json
generated
|
@ -11,6 +11,7 @@
|
|||
"classnames": "^2.3.1",
|
||||
"color-hash": "^2.0.1",
|
||||
"events": "^3.3.0",
|
||||
"lodash-move": "^1.1.1",
|
||||
"matrix-js-sdk": "^12.0.1",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0",
|
||||
|
@ -1099,6 +1100,19 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lodash-move": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash-move/-/lodash-move-1.1.1.tgz",
|
||||
"integrity": "sha1-WfduDxrFfm2Gg/UxvsB8W26k40g=",
|
||||
"dependencies": {
|
||||
"lodash": "^4.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/loglevel": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz",
|
||||
|
@ -2530,6 +2544,19 @@
|
|||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"lodash-move": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash-move/-/lodash-move-1.1.1.tgz",
|
||||
"integrity": "sha1-WfduDxrFfm2Gg/UxvsB8W26k40g=",
|
||||
"requires": {
|
||||
"lodash": "^4.6.1"
|
||||
}
|
||||
},
|
||||
"loglevel": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz",
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"classnames": "^2.3.1",
|
||||
"color-hash": "^2.0.1",
|
||||
"events": "^3.3.0",
|
||||
"lodash-move": "^1.1.1",
|
||||
"matrix-js-sdk": "^12.0.1",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0",
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useDrag } from "react-use-gesture";
|
||||
import { useSprings, animated, useSpring } from "@react-spring/web";
|
||||
import { useSprings, animated } from "@react-spring/web";
|
||||
import styles from "./GridDemo.module.css";
|
||||
import useMeasure from "react-use-measure";
|
||||
import moveArrItem from "lodash-move";
|
||||
|
||||
function isInside([x, y], targetTile) {
|
||||
const left = targetTile.x;
|
||||
|
@ -128,7 +129,9 @@ export function GridDemo() {
|
|||
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
||||
setStream(stream);
|
||||
tileOrderRef.current.push(tileOrderRef.current.length);
|
||||
|
||||
setTileState(() => {
|
||||
console.log("startWebcam");
|
||||
const tiles = [{ stream, key: tileKey.current++, remove: false }];
|
||||
const tilePositions = getTilePositions(tiles, gridBounds);
|
||||
return { tiles, tilePositions };
|
||||
|
@ -141,6 +144,7 @@ export function GridDemo() {
|
|||
tileOrderRef.current.push(tileOrderRef.current.length);
|
||||
|
||||
setTileState(({ tiles }) => {
|
||||
console.log("addTile");
|
||||
const newTiles = [
|
||||
...tiles,
|
||||
{ stream: newStream, key: tileKey.current++, remove: false },
|
||||
|
@ -193,10 +197,11 @@ export function GridDemo() {
|
|||
}, [gridBounds]);
|
||||
|
||||
const animate = useCallback(
|
||||
(order) => (index) => {
|
||||
const tileIndex = order[index];
|
||||
(tileIndex) => {
|
||||
const tileOrder = tileOrderRef.current;
|
||||
const order = tileOrder.indexOf(tileIndex);
|
||||
const tile = tiles[tileIndex];
|
||||
const tilePosition = tilePositions[tileIndex];
|
||||
const tilePosition = tilePositions[order];
|
||||
const draggingTile = draggingTileRef.current;
|
||||
const dragging = draggingTile && tile.key === draggingTile.key;
|
||||
const remove = tile.remove;
|
||||
|
@ -205,8 +210,8 @@ export function GridDemo() {
|
|||
return {
|
||||
width: tilePosition.width,
|
||||
height: tilePosition.height,
|
||||
x: tilePosition.x + draggingTile.x,
|
||||
y: tilePosition.y + draggingTile.y,
|
||||
x: draggingTile.offsetX + draggingTile.x,
|
||||
y: draggingTile.offsetY + draggingTile.y,
|
||||
scale: 1.1,
|
||||
opacity: 1,
|
||||
zIndex: 1,
|
||||
|
@ -237,47 +242,62 @@ export function GridDemo() {
|
|||
[tiles, tilePositions]
|
||||
);
|
||||
|
||||
const [springs, api] = useSprings(
|
||||
tiles.length,
|
||||
animate(tileOrderRef.current),
|
||||
[tilePositions, tiles]
|
||||
);
|
||||
const [springs, api] = useSprings(tiles.length, animate, [
|
||||
tilePositions,
|
||||
tiles,
|
||||
]);
|
||||
|
||||
const bind = useDrag(({ args: [index], active, xy, movement }) => {
|
||||
let order = tileOrderRef.current;
|
||||
const bind = useDrag(({ args: [key], active, xy, movement }) => {
|
||||
const tileOrder = tileOrderRef.current;
|
||||
|
||||
const tileIndex = tileOrderRef.current[index];
|
||||
const tile = tiles[tileIndex];
|
||||
const dragTileIndex = tiles.findIndex((tile) => tile.key === key);
|
||||
const dragTile = tiles[dragTileIndex];
|
||||
|
||||
const dragTileOrder = tileOrder.indexOf(dragTileIndex);
|
||||
|
||||
const cursorPosition = [xy[0] - gridBounds.left, xy[1] - gridBounds.top];
|
||||
|
||||
for (let i = 0; i < tileOrderRef.current.length; i++) {
|
||||
if (i === index) {
|
||||
for (
|
||||
let hoverTileIndex = 0;
|
||||
hoverTileIndex < tiles.length;
|
||||
hoverTileIndex++
|
||||
) {
|
||||
const hoverTile = tiles[hoverTileIndex];
|
||||
const hoverTileOrder = tileOrder.indexOf(hoverTileIndex);
|
||||
const hoverTilePosition = tilePositions[hoverTileOrder];
|
||||
|
||||
if (hoverTile.key === key) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const hoverTileIndex = tileOrderRef.current[i];
|
||||
const hoverTilePosition = tilePositions[hoverTileIndex];
|
||||
|
||||
if (isInside(cursorPosition, hoverTilePosition)) {
|
||||
// TODO: Figure out swapping
|
||||
// order[i] = tileIndex;
|
||||
// order[index] = i;
|
||||
tileOrderRef.current = moveArrItem(
|
||||
tileOrder,
|
||||
dragTileOrder,
|
||||
hoverTileOrder
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (active) {
|
||||
draggingTileRef.current = {
|
||||
key: tile.key,
|
||||
x: movement[0],
|
||||
y: movement[1],
|
||||
};
|
||||
if (!draggingTileRef.current) {
|
||||
const tilePosition = tilePositions[dragTileOrder];
|
||||
|
||||
draggingTileRef.current = {
|
||||
key: dragTile.key,
|
||||
offsetX: tilePosition.x,
|
||||
offsetY: tilePosition.y,
|
||||
};
|
||||
}
|
||||
|
||||
draggingTileRef.current.x = movement[0];
|
||||
draggingTileRef.current.y = movement[1];
|
||||
} else {
|
||||
draggingTileRef.current = null;
|
||||
}
|
||||
|
||||
api.start(animate(order));
|
||||
api.start(animate);
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -300,7 +320,7 @@ export function GridDemo() {
|
|||
|
||||
return (
|
||||
<ParticipantTile
|
||||
{...bind(i)}
|
||||
{...bind(tile.key)}
|
||||
key={tile.key}
|
||||
style={{
|
||||
boxShadow: shadow.to(
|
||||
|
@ -308,6 +328,7 @@ export function GridDemo() {
|
|||
),
|
||||
...style,
|
||||
}}
|
||||
tileKey={tile.key}
|
||||
{...tile}
|
||||
/>
|
||||
);
|
||||
|
@ -331,6 +352,7 @@ function ParticipantTile({ style, stream, remove, tileKey, ...rest }) {
|
|||
|
||||
return (
|
||||
<animated.div className={styles.participantTile} style={style} {...rest}>
|
||||
<div className={styles.participantName}>{tileKey}</div>
|
||||
<video ref={videoRef} playsInline />
|
||||
</animated.div>
|
||||
);
|
||||
|
|
|
@ -26,4 +26,12 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.participantName {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
padding: 8px 24px;
|
||||
}
|
Loading…
Reference in a new issue