Changed map and fog erase to allow for multi item selection
This commit is contained in:
parent
55bf9e4d03
commit
337a769fe4
@ -97,8 +97,8 @@ function Map({
|
|||||||
onMapDraw({ type: "add", shapes: [shape] });
|
onMapDraw({ type: "add", shapes: [shape] });
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMapShapeRemove(shapeId) {
|
function handleMapShapesRemove(shapeIds) {
|
||||||
onMapDraw({ type: "remove", shapeIds: [shapeId] });
|
onMapDraw({ type: "remove", shapeIds });
|
||||||
}
|
}
|
||||||
|
|
||||||
const [fogShapes, setFogShapes] = useState([]);
|
const [fogShapes, setFogShapes] = useState([]);
|
||||||
@ -107,12 +107,12 @@ function Map({
|
|||||||
onFogDraw({ type: "add", shapes: [shape] });
|
onFogDraw({ type: "add", shapes: [shape] });
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFogShapeRemove(shapeId) {
|
function handleFogShapesRemove(shapeIds) {
|
||||||
onFogDraw({ type: "remove", shapeIds: [shapeId] });
|
onFogDraw({ type: "remove", shapeIds });
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFogShapeEdit(shape) {
|
function handleFogShapesEdit(shapes) {
|
||||||
onFogDraw({ type: "edit", shapes: [shape] });
|
onFogDraw({ type: "edit", shapes });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replay the draw actions and convert them to shapes for the map drawing
|
// Replay the draw actions and convert them to shapes for the map drawing
|
||||||
@ -275,7 +275,7 @@ function Map({
|
|||||||
<MapDrawing
|
<MapDrawing
|
||||||
shapes={mapShapes}
|
shapes={mapShapes}
|
||||||
onShapeAdd={handleMapShapeAdd}
|
onShapeAdd={handleMapShapeAdd}
|
||||||
onShapeRemove={handleMapShapeRemove}
|
onShapesRemove={handleMapShapesRemove}
|
||||||
selectedToolId={selectedToolId}
|
selectedToolId={selectedToolId}
|
||||||
selectedToolSettings={toolSettings[selectedToolId]}
|
selectedToolSettings={toolSettings[selectedToolId]}
|
||||||
gridSize={gridSizeNormalized}
|
gridSize={gridSizeNormalized}
|
||||||
@ -286,8 +286,8 @@ function Map({
|
|||||||
<MapFog
|
<MapFog
|
||||||
shapes={fogShapes}
|
shapes={fogShapes}
|
||||||
onShapeAdd={handleFogShapeAdd}
|
onShapeAdd={handleFogShapeAdd}
|
||||||
onShapeRemove={handleFogShapeRemove}
|
onShapesRemove={handleFogShapesRemove}
|
||||||
onShapeEdit={handleFogShapeEdit}
|
onShapesEdit={handleFogShapesEdit}
|
||||||
selectedToolId={selectedToolId}
|
selectedToolId={selectedToolId}
|
||||||
selectedToolSettings={toolSettings[selectedToolId]}
|
selectedToolSettings={toolSettings[selectedToolId]}
|
||||||
gridSize={gridSizeNormalized}
|
gridSize={gridSizeNormalized}
|
||||||
|
@ -19,13 +19,15 @@ import useMapBrush from "../../helpers/useMapBrush";
|
|||||||
function MapDrawing({
|
function MapDrawing({
|
||||||
shapes,
|
shapes,
|
||||||
onShapeAdd,
|
onShapeAdd,
|
||||||
onShapeRemove,
|
onShapesRemove,
|
||||||
selectedToolId,
|
selectedToolId,
|
||||||
selectedToolSettings,
|
selectedToolSettings,
|
||||||
gridSize,
|
gridSize,
|
||||||
}) {
|
}) {
|
||||||
const { stageScale, mapWidth, mapHeight } = useContext(MapInteractionContext);
|
const { stageScale, mapWidth, mapHeight } = useContext(MapInteractionContext);
|
||||||
const [drawingShape, setDrawingShape] = useState(null);
|
const [drawingShape, setDrawingShape] = useState(null);
|
||||||
|
const [isBrushDown, setIsBrushDown] = useState(false);
|
||||||
|
const [erasingShapes, setErasingShapes] = useState([]);
|
||||||
|
|
||||||
const shouldHover = selectedToolId === "erase";
|
const shouldHover = selectedToolId === "erase";
|
||||||
const isEditing =
|
const isEditing =
|
||||||
@ -33,6 +35,14 @@ function MapDrawing({
|
|||||||
selectedToolId === "shape" ||
|
selectedToolId === "shape" ||
|
||||||
selectedToolId === "erase";
|
selectedToolId === "erase";
|
||||||
|
|
||||||
|
const handleBrushUp = useCallback(() => {
|
||||||
|
setIsBrushDown(false);
|
||||||
|
if (erasingShapes.length > 0) {
|
||||||
|
onShapesRemove(erasingShapes.map((shape) => shape.id));
|
||||||
|
setErasingShapes([]);
|
||||||
|
}
|
||||||
|
}, [erasingShapes, onShapesRemove]);
|
||||||
|
|
||||||
const handleShapeDraw = useCallback(
|
const handleShapeDraw = useCallback(
|
||||||
(brushState, mapBrushPosition) => {
|
(brushState, mapBrushPosition) => {
|
||||||
function startShape() {
|
function startShape() {
|
||||||
@ -65,6 +75,7 @@ function MapDrawing({
|
|||||||
...commonShapeData,
|
...commonShapeData,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
setIsBrushDown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function continueShape() {
|
function continueShape() {
|
||||||
@ -119,6 +130,7 @@ function MapDrawing({
|
|||||||
onShapeAdd(drawingShape);
|
onShapeAdd(drawingShape);
|
||||||
}
|
}
|
||||||
setDrawingShape(null);
|
setDrawingShape(null);
|
||||||
|
handleBrushUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (brushState) {
|
switch (brushState) {
|
||||||
@ -143,48 +155,27 @@ function MapDrawing({
|
|||||||
onShapeAdd,
|
onShapeAdd,
|
||||||
shapes,
|
shapes,
|
||||||
drawingShape,
|
drawingShape,
|
||||||
|
handleBrushUp,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
useMapBrush(isEditing, handleShapeDraw);
|
useMapBrush(isEditing, handleShapeDraw);
|
||||||
|
|
||||||
function handleShapeClick(_, shape) {
|
function handleShapeOver(shape, isDown) {
|
||||||
if (selectedToolId === "erase") {
|
if (shouldHover && isDown) {
|
||||||
onShapeRemove(shape.id);
|
if (erasingShapes.findIndex((s) => s.id === shape.id) === -1) {
|
||||||
|
setErasingShapes((prevShapes) => [...prevShapes, shape]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleShapeMouseOver(event, shape) {
|
|
||||||
if (shouldHover) {
|
|
||||||
const path = event.target;
|
|
||||||
const hoverColor = "#BB99FF";
|
|
||||||
path.fill(hoverColor);
|
|
||||||
if (shape.type === "path") {
|
|
||||||
path.stroke(hoverColor);
|
|
||||||
}
|
|
||||||
path.getLayer().draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleShapeMouseOut(event, shape) {
|
|
||||||
if (shouldHover) {
|
|
||||||
const path = event.target;
|
|
||||||
const color = colors[shape.color] || shape.color;
|
|
||||||
path.fill(color);
|
|
||||||
if (shape.type === "path") {
|
|
||||||
path.stroke(color);
|
|
||||||
}
|
|
||||||
path.getLayer().draw();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderShape(shape) {
|
function renderShape(shape) {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
key: shape.id,
|
key: shape.id,
|
||||||
onMouseOver: (e) => handleShapeMouseOver(e, shape),
|
onMouseMove: () => handleShapeOver(shape, isBrushDown),
|
||||||
onMouseOut: (e) => handleShapeMouseOut(e, shape),
|
onTouchOver: () => handleShapeOver(shape, isBrushDown),
|
||||||
onClick: (e) => handleShapeClick(e, shape),
|
onMouseDown: () => handleShapeOver(shape, true),
|
||||||
onTap: (e) => handleShapeClick(e, shape),
|
onTouchStart: () => handleShapeOver(shape, true),
|
||||||
fill: colors[shape.color] || shape.color,
|
fill: colors[shape.color] || shape.color,
|
||||||
opacity: shape.blend ? 0.5 : 1,
|
opacity: shape.blend ? 0.5 : 1,
|
||||||
};
|
};
|
||||||
@ -245,10 +236,19 @@ function MapDrawing({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderErasingShape(shape) {
|
||||||
|
const eraseShape = {
|
||||||
|
...shape,
|
||||||
|
color: "#BB99FF",
|
||||||
|
};
|
||||||
|
return renderShape(eraseShape);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group>
|
<Group>
|
||||||
{shapes.map(renderShape)}
|
{shapes.map(renderShape)}
|
||||||
{drawingShape && renderShape(drawingShape)}
|
{drawingShape && renderShape(drawingShape)}
|
||||||
|
{erasingShapes.length > 0 && erasingShapes.map(renderErasingShape)}
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,16 @@ import useMapBrush from "../../helpers/useMapBrush";
|
|||||||
function MapFog({
|
function MapFog({
|
||||||
shapes,
|
shapes,
|
||||||
onShapeAdd,
|
onShapeAdd,
|
||||||
onShapeRemove,
|
onShapesRemove,
|
||||||
onShapeEdit,
|
onShapesEdit,
|
||||||
selectedToolId,
|
selectedToolId,
|
||||||
selectedToolSettings,
|
selectedToolSettings,
|
||||||
gridSize,
|
gridSize,
|
||||||
}) {
|
}) {
|
||||||
const { stageScale, mapWidth, mapHeight } = useContext(MapInteractionContext);
|
const { stageScale, mapWidth, mapHeight } = useContext(MapInteractionContext);
|
||||||
const [drawingShape, setDrawingShape] = useState(null);
|
const [drawingShape, setDrawingShape] = useState(null);
|
||||||
|
const [isBrushDown, setIsBrushDown] = useState(false);
|
||||||
|
const [editingShapes, setEditingShapes] = useState([]);
|
||||||
|
|
||||||
const isEditing = selectedToolId === "fog";
|
const isEditing = selectedToolId === "fog";
|
||||||
const shouldHover =
|
const shouldHover =
|
||||||
@ -37,6 +39,20 @@ function MapFog({
|
|||||||
|
|
||||||
const [patternImage] = useImage(diagonalPattern);
|
const [patternImage] = useImage(diagonalPattern);
|
||||||
|
|
||||||
|
const handleBrushUp = useCallback(() => {
|
||||||
|
setIsBrushDown(false);
|
||||||
|
if (editingShapes.length > 0) {
|
||||||
|
if (selectedToolSettings.type === "remove") {
|
||||||
|
onShapesRemove(editingShapes.map((shape) => shape.id));
|
||||||
|
} else if (selectedToolSettings.type === "toggle") {
|
||||||
|
onShapesEdit(
|
||||||
|
editingShapes.map((shape) => ({ ...shape, visible: !shape.visible }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setEditingShapes([]);
|
||||||
|
}
|
||||||
|
}, [editingShapes, onShapesRemove, onShapesEdit, selectedToolSettings]);
|
||||||
|
|
||||||
const handleShapeDraw = useCallback(
|
const handleShapeDraw = useCallback(
|
||||||
(brushState, mapBrushPosition) => {
|
(brushState, mapBrushPosition) => {
|
||||||
function startShape() {
|
function startShape() {
|
||||||
@ -58,6 +74,7 @@ function MapFog({
|
|||||||
visible: true,
|
visible: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
setIsBrushDown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function continueShape() {
|
function continueShape() {
|
||||||
@ -106,6 +123,7 @@ function MapFog({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setDrawingShape(null);
|
setDrawingShape(null);
|
||||||
|
handleBrushUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (brushState) {
|
switch (brushState) {
|
||||||
@ -130,46 +148,17 @@ function MapFog({
|
|||||||
onShapeAdd,
|
onShapeAdd,
|
||||||
shapes,
|
shapes,
|
||||||
drawingShape,
|
drawingShape,
|
||||||
|
handleBrushUp,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
useMapBrush(isEditing, handleShapeDraw);
|
useMapBrush(isEditing, handleShapeDraw);
|
||||||
|
|
||||||
function handleShapeClick(_, shape) {
|
function handleShapeOver(shape, isDown) {
|
||||||
if (!isEditing) {
|
if (shouldHover && isDown) {
|
||||||
return;
|
if (editingShapes.findIndex((s) => s.id === shape.id) === -1) {
|
||||||
|
setEditingShapes((prevShapes) => [...prevShapes, shape]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedToolSettings.type === "remove") {
|
|
||||||
onShapeRemove(shape.id);
|
|
||||||
} else if (selectedToolSettings.type === "toggle") {
|
|
||||||
onShapeEdit({ ...shape, visible: !shape.visible });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleShapeMouseOver(event, shape) {
|
|
||||||
if (shouldHover) {
|
|
||||||
const path = event.target;
|
|
||||||
if (shape.visible) {
|
|
||||||
const hoverColor = "#BB99FF";
|
|
||||||
path.fill(hoverColor);
|
|
||||||
} else {
|
|
||||||
path.opacity(1);
|
|
||||||
}
|
|
||||||
path.getLayer().draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleShapeMouseOut(event, shape) {
|
|
||||||
if (shouldHover) {
|
|
||||||
const path = event.target;
|
|
||||||
if (shape.visible) {
|
|
||||||
const color = colors[shape.color] || shape.color;
|
|
||||||
path.fill(color);
|
|
||||||
} else {
|
|
||||||
path.opacity(0.5);
|
|
||||||
}
|
|
||||||
path.getLayer().draw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,10 +166,10 @@ function MapFog({
|
|||||||
return (
|
return (
|
||||||
<Line
|
<Line
|
||||||
key={shape.id}
|
key={shape.id}
|
||||||
onMouseOver={(e) => handleShapeMouseOver(e, shape)}
|
onMouseMove={() => handleShapeOver(shape, isBrushDown)}
|
||||||
onMouseOut={(e) => handleShapeMouseOut(e, shape)}
|
onTouchOver={() => handleShapeOver(shape, isBrushDown)}
|
||||||
onClick={(e) => handleShapeClick(e, shape)}
|
onMouseDown={() => handleShapeOver(shape, true)}
|
||||||
onTap={(e) => handleShapeClick(e, shape)}
|
onTouchStart={() => handleShapeOver(shape, true)}
|
||||||
points={shape.data.points.reduce(
|
points={shape.data.points.reduce(
|
||||||
(acc, point) => [...acc, point.x * mapWidth, point.y * mapHeight],
|
(acc, point) => [...acc, point.x * mapWidth, point.y * mapHeight],
|
||||||
[]
|
[]
|
||||||
@ -203,10 +192,19 @@ function MapFog({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderEditingShape(shape) {
|
||||||
|
const editingShape = {
|
||||||
|
...shape,
|
||||||
|
color: "#BB99FF",
|
||||||
|
};
|
||||||
|
return renderShape(editingShape);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Group>
|
<Group>
|
||||||
{shapes.map(renderShape)}
|
{shapes.map(renderShape)}
|
||||||
{drawingShape && renderShape(drawingShape)}
|
{drawingShape && renderShape(drawingShape)}
|
||||||
|
{editingShapes.length > 0 && editingShapes.map(renderEditingShape)}
|
||||||
</Group>
|
</Group>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user