Added network sync to drawing
This commit is contained in:
parent
9f97cf3bb4
commit
ad236d6e6a
@ -22,6 +22,11 @@ function Map({
|
||||
onMapTokenChange,
|
||||
onMapTokenRemove,
|
||||
onMapChange,
|
||||
onMapDraw,
|
||||
onMapDrawUndo,
|
||||
onMapDrawRedo,
|
||||
drawActions,
|
||||
drawActionIndex,
|
||||
}) {
|
||||
function handleProxyDragEnd(isOnMap, token) {
|
||||
if (isOnMap && onMapTokenChange) {
|
||||
@ -40,30 +45,15 @@ function Map({
|
||||
const [selectedTool, setSelectedTool] = useState("pan");
|
||||
|
||||
const [drawnShapes, setDrawnShapes] = useState([]);
|
||||
const [drawActions, setDrawActions] = useState([]);
|
||||
const [drawActionIndex, setDrawActionIndex] = useState(-1);
|
||||
function handleShapeAdd(shape) {
|
||||
setDrawActions((prevActions) => {
|
||||
const newActions = [
|
||||
...prevActions.slice(0, drawActionIndex + 1),
|
||||
{ type: "add", shape },
|
||||
];
|
||||
setDrawActionIndex(newActions.length - 1);
|
||||
return newActions;
|
||||
});
|
||||
onMapDraw({ type: "add", shape });
|
||||
}
|
||||
|
||||
function handleShapeRemove(shapeId) {
|
||||
setDrawActions((prevActions) => {
|
||||
const newActions = [
|
||||
...prevActions.slice(0, drawActionIndex + 1),
|
||||
{ type: "remove", shapeId },
|
||||
];
|
||||
setDrawActionIndex(newActions.length - 1);
|
||||
return newActions;
|
||||
});
|
||||
onMapDraw({ type: "remove", shapeId });
|
||||
}
|
||||
|
||||
// Replay the draw actions and convert them to shapes for the map drawing
|
||||
useEffect(() => {
|
||||
let shapesById = {};
|
||||
for (let i = 0; i <= drawActionIndex; i++) {
|
||||
@ -78,16 +68,6 @@ function Map({
|
||||
setDrawnShapes(Object.values(shapesById));
|
||||
}, [drawActions, drawActionIndex]);
|
||||
|
||||
function handleDrawActionUndo() {
|
||||
setDrawActionIndex((prevIndex) => Math.max(prevIndex - 1, -1));
|
||||
}
|
||||
|
||||
function handleDrawActionRedo() {
|
||||
setDrawActionIndex((prevIndex) =>
|
||||
Math.min(prevIndex + 1, drawActions.length - 1)
|
||||
);
|
||||
}
|
||||
|
||||
const disabledTools = [];
|
||||
if (!mapData) {
|
||||
disabledTools.push("pan");
|
||||
@ -290,8 +270,8 @@ function Map({
|
||||
onToolChange={setSelectedTool}
|
||||
selectedTool={selectedTool}
|
||||
disabledTools={disabledTools}
|
||||
onUndo={handleDrawActionUndo}
|
||||
onRedo={handleDrawActionRedo}
|
||||
onUndo={onMapDrawUndo}
|
||||
onRedo={onMapDrawRedo}
|
||||
undoDisabled={drawActionIndex < 0}
|
||||
redoDisabled={drawActionIndex === drawActions.length - 1}
|
||||
/>
|
||||
|
@ -36,6 +36,10 @@ function Game() {
|
||||
handlePeerError
|
||||
);
|
||||
|
||||
/**
|
||||
* Map state
|
||||
*/
|
||||
|
||||
const [mapSource, setMapSource] = useState(null);
|
||||
const mapDataRef = useRef(null);
|
||||
|
||||
@ -74,6 +78,52 @@ function Game() {
|
||||
}
|
||||
}
|
||||
|
||||
const [mapDrawActions, setMapDrawActions] = useState([]);
|
||||
// An index into the draw actions array to which only actions before the
|
||||
// index will be performed (used in undo and redo)
|
||||
const [mapDrawActionIndex, setMapDrawActionIndex] = useState(-1);
|
||||
function addNewMapDrawActions(actions) {
|
||||
setMapDrawActions((prevActions) => {
|
||||
const newActions = [
|
||||
...prevActions.slice(0, mapDrawActionIndex + 1),
|
||||
...actions,
|
||||
];
|
||||
const newIndex = newActions.length - 1;
|
||||
setMapDrawActionIndex(newIndex);
|
||||
return newActions;
|
||||
});
|
||||
}
|
||||
|
||||
function handleMapDraw(action) {
|
||||
addNewMapDrawActions([action]);
|
||||
for (let peer of Object.values(peers)) {
|
||||
peer.connection.send({ id: "mapDraw", data: [action] });
|
||||
}
|
||||
}
|
||||
|
||||
function handleMapDrawUndo() {
|
||||
const newIndex = Math.max(mapDrawActionIndex - 1, -1);
|
||||
setMapDrawActionIndex(newIndex);
|
||||
for (let peer of Object.values(peers)) {
|
||||
peer.connection.send({ id: "mapDrawIndex", data: newIndex });
|
||||
}
|
||||
}
|
||||
|
||||
function handleMapDrawRedo() {
|
||||
const newIndex = Math.min(
|
||||
mapDrawActionIndex + 1,
|
||||
mapDrawActions.length - 1
|
||||
);
|
||||
setMapDrawActionIndex(newIndex);
|
||||
for (let peer of Object.values(peers)) {
|
||||
peer.connection.send({ id: "mapDrawIndex", data: newIndex });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Party state
|
||||
*/
|
||||
|
||||
const { nickname, setNickname } = useNickname();
|
||||
const [partyNicknames, setPartyNicknames] = useState({});
|
||||
|
||||
@ -94,6 +144,10 @@ function Game() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Peer handlers
|
||||
*/
|
||||
|
||||
function handlePeerData({ data, peer }) {
|
||||
if (data.id === "sync") {
|
||||
if (mapSource) {
|
||||
@ -102,6 +156,12 @@ function Game() {
|
||||
if (mapTokens) {
|
||||
peer.connection.send({ id: "tokenEdit", data: mapTokens });
|
||||
}
|
||||
if (mapDrawActions) {
|
||||
peer.connection.send({ id: "mapDraw", data: mapDrawActions });
|
||||
}
|
||||
if (mapDrawActionIndex != mapDrawActions.length - 1) {
|
||||
peer.connection.send({ id: "mapDrawIndex", data: mapDrawActionIndex });
|
||||
}
|
||||
}
|
||||
if (data.id === "map") {
|
||||
const blob = new Blob([data.data.file]);
|
||||
@ -125,6 +185,12 @@ function Game() {
|
||||
...data.data,
|
||||
}));
|
||||
}
|
||||
if (data.id === "mapDraw") {
|
||||
addNewMapDrawActions(data.data);
|
||||
}
|
||||
if (data.id === "mapDrawIndex") {
|
||||
setMapDrawActionIndex(data.data);
|
||||
}
|
||||
}
|
||||
|
||||
function handlePeerDisconnected(peer) {
|
||||
@ -169,6 +235,10 @@ function Game() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream handler
|
||||
*/
|
||||
|
||||
function handleStreamStart(localStream) {
|
||||
setStream(localStream);
|
||||
const tracks = localStream.getTracks();
|
||||
@ -238,6 +308,11 @@ function Game() {
|
||||
onMapTokenChange={handleMapTokenChange}
|
||||
onMapTokenRemove={handleMapTokenRemove}
|
||||
onMapChange={handleMapChange}
|
||||
onMapDraw={handleMapDraw}
|
||||
onMapDrawUndo={handleMapDrawUndo}
|
||||
onMapDrawRedo={handleMapDrawRedo}
|
||||
drawActions={mapDrawActions}
|
||||
drawActionIndex={mapDrawActionIndex}
|
||||
/>
|
||||
<Tokens onCreateMapToken={handleMapTokenChange} />
|
||||
</Flex>
|
||||
|
Loading…
Reference in New Issue
Block a user