Added token animations back, edited token change event to support multiple edits
This stopped mounted vehicle animations from lagging
This commit is contained in:
parent
ef1c875088
commit
09e423fd56
@ -237,7 +237,7 @@ function Map({
|
||||
<TokenMenu
|
||||
isOpen={isTokenMenuOpen}
|
||||
onRequestClose={() => setIsTokenMenuOpen(false)}
|
||||
onTokenChange={onMapTokenStateChange}
|
||||
onTokenStateChange={onMapTokenStateChange}
|
||||
tokenState={mapState && mapState.tokens[tokenMenuOptions.tokenStateId]}
|
||||
tokenImage={tokenMenuOptions.tokenImage}
|
||||
/>
|
||||
|
@ -1,9 +1,11 @@
|
||||
import React, { useContext, useState, useEffect, useRef } from "react";
|
||||
import { Image as KonvaImage, Group } from "react-konva";
|
||||
import Konva from "konva";
|
||||
import useImage from "use-image";
|
||||
|
||||
import useDataSource from "../../helpers/useDataSource";
|
||||
import useDebounce from "../../helpers/useDebounce";
|
||||
import usePrevious from "../../helpers/usePrevious";
|
||||
|
||||
import AuthContext from "../../contexts/AuthContext";
|
||||
import MapInteractionContext from "../../contexts/MapInteractionContext";
|
||||
@ -80,6 +82,7 @@ function MapToken({
|
||||
function handleDragEnd(event) {
|
||||
const tokenImage = event.target;
|
||||
|
||||
const mountChanges = {};
|
||||
if (token.isVehicle) {
|
||||
const layer = tokenImage.getLayer();
|
||||
const mountedTokens = tokenImage.find(".token");
|
||||
@ -88,21 +91,24 @@ function MapToken({
|
||||
const position = mountedToken.absolutePosition();
|
||||
mountedToken.moveTo(layer);
|
||||
mountedToken.absolutePosition(position);
|
||||
onTokenStateChange({
|
||||
mountChanges[mountedToken.id()] = {
|
||||
...mapState.tokens[mountedToken.id()],
|
||||
x: mountedToken.x() / mapWidth,
|
||||
y: mountedToken.y() / mapHeight,
|
||||
lastEditedBy: userId,
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
setPreventMapInteraction(false);
|
||||
onTokenStateChange({
|
||||
...mountChanges,
|
||||
[tokenState.id]: {
|
||||
...tokenState,
|
||||
x: tokenImage.x() / mapWidth,
|
||||
y: tokenImage.y() / mapHeight,
|
||||
lastEditedBy: userId,
|
||||
},
|
||||
});
|
||||
onTokenDragEnd(event);
|
||||
}
|
||||
@ -147,7 +153,12 @@ function MapToken({
|
||||
const imageRef = useRef();
|
||||
useEffect(() => {
|
||||
const image = imageRef.current;
|
||||
if (image && tokenSourceStatus === "loaded") {
|
||||
if (
|
||||
image &&
|
||||
tokenSourceStatus === "loaded" &&
|
||||
tokenWidth > 0 &&
|
||||
tokenHeight > 0
|
||||
) {
|
||||
image.cache({
|
||||
pixelRatio: debouncedStageScale * window.devicePixelRatio,
|
||||
});
|
||||
@ -157,16 +168,35 @@ function MapToken({
|
||||
}
|
||||
}, [debouncedStageScale, tokenWidth, tokenHeight, tokenSourceStatus]);
|
||||
|
||||
if (!tokenWidth || !tokenHeight || tokenSourceStatus === "loading") {
|
||||
return null;
|
||||
// Animate to new token positions if edited by others
|
||||
const containerRef = useRef();
|
||||
const tokenX = tokenState.x * mapWidth;
|
||||
const tokenY = tokenState.y * mapHeight;
|
||||
|
||||
const previousWidth = usePrevious(mapWidth);
|
||||
const previousHeight = usePrevious(mapHeight);
|
||||
const resized = mapWidth !== previousWidth || mapHeight !== previousHeight;
|
||||
useEffect(() => {
|
||||
const container = containerRef.current;
|
||||
if (container) {
|
||||
if (tokenState.lastEditedBy === userId || resized) {
|
||||
container.x(tokenX);
|
||||
container.y(tokenY);
|
||||
} else {
|
||||
container.to({
|
||||
x: tokenX,
|
||||
y: tokenY,
|
||||
duration: 0.3,
|
||||
easing: Konva.Easings.EaseInOut,
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [tokenX, tokenY, tokenState.lastEditedBy, userId, resized]);
|
||||
|
||||
return (
|
||||
<Group
|
||||
width={tokenWidth}
|
||||
height={tokenHeight}
|
||||
x={tokenState.x * mapWidth}
|
||||
y={tokenState.y * mapHeight}
|
||||
draggable={draggable}
|
||||
onMouseDown={handlePointerDown}
|
||||
onMouseUp={handlePointerUp}
|
||||
@ -180,6 +210,7 @@ function MapToken({
|
||||
opacity={tokenOpacity}
|
||||
name={token && token.isVehicle ? "vehicle" : "token"}
|
||||
id={tokenState.id}
|
||||
ref={containerRef}
|
||||
>
|
||||
<KonvaImage
|
||||
ref={imageRef}
|
||||
|
@ -30,10 +30,12 @@ function TokenDragOverlay({
|
||||
mountedToken.moveTo(layer);
|
||||
mountedToken.absolutePosition(position);
|
||||
onTokenStateChange({
|
||||
[mountedToken.id()]: {
|
||||
...mapState.tokens[mountedToken.id()],
|
||||
x: mountedToken.x() / mapWidth,
|
||||
y: mountedToken.y() / mapHeight,
|
||||
lastEditedBy: userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -8,25 +8,12 @@ import colors, { colorOptions } from "../../helpers/colors";
|
||||
import usePrevious from "../../helpers/usePrevious";
|
||||
|
||||
const defaultTokenMaxSize = 6;
|
||||
|
||||
/**
|
||||
* @callback onTokenChange
|
||||
* @param {Object} token the token that was changed
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} tokenClassName The class name to attach the interactjs handler to
|
||||
* @param {onProxyDragEnd} onTokenChange Called when the the token data is changed
|
||||
* @param {Object} tokens An mapping of tokens to use as a base when calling onTokenChange
|
||||
* @param {Object} disabledTokens An optional mapping of tokens that shouldn't allow interaction
|
||||
*/
|
||||
function TokenMenu({
|
||||
isOpen,
|
||||
onRequestClose,
|
||||
tokenState,
|
||||
tokenImage,
|
||||
onTokenChange,
|
||||
onTokenStateChange,
|
||||
}) {
|
||||
const wasOpen = usePrevious(isOpen);
|
||||
|
||||
@ -39,7 +26,7 @@ function TokenMenu({
|
||||
|
||||
function handleLabelChange(event) {
|
||||
const label = event.target.value;
|
||||
onTokenChange({ ...tokenState, label: label });
|
||||
onTokenStateChange({ [tokenState.id]: { ...tokenState, label: label } });
|
||||
}
|
||||
|
||||
const [menuLeft, setMenuLeft] = useState(0);
|
||||
@ -66,17 +53,21 @@ function TokenMenu({
|
||||
} else {
|
||||
newStatuses = [...statuses, status];
|
||||
}
|
||||
onTokenChange({ ...tokenState, statuses: newStatuses });
|
||||
onTokenStateChange({
|
||||
[tokenState.id]: { ...tokenState, statuses: newStatuses },
|
||||
});
|
||||
}
|
||||
|
||||
function handleSizeChange(event) {
|
||||
const newSize = parseInt(event.target.value);
|
||||
onTokenChange({ ...tokenState, size: newSize });
|
||||
onTokenStateChange({ [tokenState.id]: { ...tokenState, size: newSize } });
|
||||
}
|
||||
|
||||
function handleRotationChange(event) {
|
||||
const newRotation = parseInt(event.target.value);
|
||||
onTokenChange({ ...tokenState, rotation: newRotation });
|
||||
onTokenStateChange({
|
||||
[tokenState.id]: { ...tokenState, rotation: newRotation },
|
||||
});
|
||||
}
|
||||
|
||||
function handleModalContent(node) {
|
||||
|
@ -244,10 +244,11 @@ function Game() {
|
||||
peer.connection.send({ id: "token", data: rest });
|
||||
}
|
||||
}
|
||||
handleMapTokenStateChange(tokenState);
|
||||
handleMapTokenStateChange({ [tokenState.id]: tokenState });
|
||||
}
|
||||
|
||||
function handleMapTokenStateChange(tokenState) {
|
||||
function handleMapTokenStateChange(change) {
|
||||
console.log(change);
|
||||
if (currentMapState === null) {
|
||||
return;
|
||||
}
|
||||
@ -255,12 +256,11 @@ function Game() {
|
||||
...prevMapState,
|
||||
tokens: {
|
||||
...prevMapState.tokens,
|
||||
[tokenState.id]: tokenState,
|
||||
...change,
|
||||
},
|
||||
}));
|
||||
for (let peer of Object.values(peers)) {
|
||||
const data = { [tokenState.id]: tokenState };
|
||||
peer.connection.send({ id: "tokenStateEdit", data });
|
||||
peer.connection.send({ id: "tokenStateEdit", data: change });
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user