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