Added grid snapping to fog polygon, added center snapping and fixed fog magnet

This commit is contained in:
Mitchell McCaffrey 2020-06-21 14:55:17 +10:00
parent a300e6bd79
commit f85b379b15
2 changed files with 71 additions and 46 deletions

View File

@ -39,28 +39,6 @@ function BrushToolSettings({
<FogBrushIcon /> <FogBrushIcon />
</RadioIconButton> </RadioIconButton>
<Divider vertical /> <Divider vertical />
<RadioIconButton
title="Add Fog"
onClick={() => onSettingChange({ useFogSubtract: false })}
isSelected={!settings.useFogSubtract}
>
<FogAddIcon />
</RadioIconButton>
<RadioIconButton
title="Subtract Fog"
onClick={() => onSettingChange({ useFogSubtract: true })}
isSelected={settings.useFogSubtract}
>
<FogSubtractIcon />
</RadioIconButton>
{/* TODO: Re-enable edge snapping when holes are fixed */}
{/* <EdgeSnappingToggle
useEdgeSnapping={settings.useEdgeSnapping}
onEdgeSnappingChange={(useEdgeSnapping) =>
onSettingChange({ useEdgeSnapping })
}
/> */}
<Divider vertical />
<RadioIconButton <RadioIconButton
title="Toggle Fog" title="Toggle Fog"
onClick={() => onSettingChange({ type: "toggle" })} onClick={() => onSettingChange({ type: "toggle" })}
@ -76,6 +54,28 @@ function BrushToolSettings({
<FogRemoveIcon /> <FogRemoveIcon />
</RadioIconButton> </RadioIconButton>
<Divider vertical /> <Divider vertical />
<RadioIconButton
title="Add Fog"
onClick={() => onSettingChange({ useFogSubtract: false })}
isSelected={!settings.useFogSubtract}
>
<FogAddIcon />
</RadioIconButton>
<RadioIconButton
title="Subtract Fog"
onClick={() => onSettingChange({ useFogSubtract: true })}
isSelected={settings.useFogSubtract}
>
<FogSubtractIcon />
</RadioIconButton>
<Divider vertical />
<EdgeSnappingToggle
useEdgeSnapping={settings.useEdgeSnapping}
onEdgeSnappingChange={(useEdgeSnapping) =>
onSettingChange({ useEdgeSnapping })
}
/>
<Divider vertical />
<UndoButton <UndoButton
onClick={() => onToolAction("fogUndo")} onClick={() => onToolAction("fogUndo")}
disabled={disabledActions.includes("undo")} disabled={disabledActions.includes("undo")}

View File

@ -12,32 +12,57 @@ export function getBrushPositionForTool(
shapes shapes
) { ) {
let position = brushPosition; let position = brushPosition;
if ( const useGridSnappning =
tool === "drawing" && (tool === "drawing" &&
(toolSettings.type === "rectangle" || (toolSettings.type === "rectangle" ||
toolSettings.type === "circle" || toolSettings.type === "circle" ||
toolSettings.type === "triangle") toolSettings.type === "triangle")) ||
) { (tool === "fog" && toolSettings.type === "polygon");
const snapped = Vector2.roundTo(position, gridSize);
if (useGridSnappning) {
// Snap to corners of grid
const gridSnap = Vector2.roundTo(position, gridSize);
const gridDistance = Vector2.length(Vector2.subtract(gridSnap, position));
// Snap to center of grid
const centerSnap = Vector2.add(
Vector2.roundTo(position, gridSize),
Vector2.multiply(gridSize, 0.5)
);
const centerDistance = Vector2.length(
Vector2.subtract(centerSnap, position)
);
const minGrid = Vector2.min(gridSize); const minGrid = Vector2.min(gridSize);
const distance = Vector2.length(Vector2.subtract(snapped, position)); if (gridDistance < minGrid * snappingThreshold) {
if (distance < minGrid * snappingThreshold) { position = gridSnap;
position = snapped; } else if (centerDistance < minGrid * snappingThreshold) {
position = centerSnap;
} }
} }
if (tool === "fog" && toolSettings.type === "add") {
if (toolSettings.useGridSnapping) { const useEdgeSnapping = tool === "fog" && toolSettings.useEdgeSnapping;
position = Vector2.roundTo(position, gridSize);
} if (useEdgeSnapping) {
if (toolSettings.useEdgeSnapping) { const minGrid = Vector2.min(gridSize);
const minGrid = Vector2.min(gridSize); let closestDistance = Number.MAX_VALUE;
let closestDistance = Number.MAX_VALUE; let closestPosition = position;
let closestPosition = position; // Find the closest point on all fog shapes
// Find the closest point on all fog shapes for (let shape of shapes) {
for (let shape of shapes) { if (shape.type === "fog") {
if (shape.type === "fog") { // Include shape points and holes
const points = shape.data.points; let pointArray = [shape.data.points, ...shape.data.holes];
const isInShape = Vector2.pointInPolygon(position, points);
// Check whether the position is in the shape but not any holes
let isInShape = Vector2.pointInPolygon(position, shape.data.points);
if (shape.data.holes.length > 0) {
for (let hole of shape.data.holes) {
if (Vector2.pointInPolygon(position, hole)) {
isInShape = false;
}
}
}
for (let points of pointArray) {
// Find the closest point to each line of the shape // Find the closest point to each line of the shape
for (let i = 0; i < points.length; i++) { for (let i = 0; i < points.length; i++) {
const a = points[i]; const a = points[i];
@ -59,8 +84,8 @@ export function getBrushPositionForTool(
} }
} }
} }
position = closestPosition;
} }
position = closestPosition;
} }
return position; return position;