Skip to content

Commit

Permalink
feat: visualise snapping point and allow it to be styled
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesLMilner committed Dec 23, 2024
1 parent 4b61c82 commit 56955a3
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 57 deletions.
4 changes: 4 additions & 0 deletions development/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ const getModes = () => {
// },
}),
new TerraDrawPolygonMode({
pointerDistance: 20,
snapping: {
toLine: true,
toCoordinate: true,
Expand All @@ -188,6 +189,9 @@ const getModes = () => {
}
return { valid: true };
},
styles: {
snappingPointColor: "#3fc8e0",
},
}),
new TerraDrawRectangleMode(),
new TerraDrawCircleMode(),
Expand Down
3 changes: 2 additions & 1 deletion src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export const SELECT_PROPERTIES = {
SELECTION_POINT: "selectionPoint",
} as const;

export const POLYGON_PROPERTIES = {
export const COMMON_PROPERTIES = {
CLOSING_POINT: "closingPoint",
SNAPPING_POINT: "snappingPoint",
};
4 changes: 2 additions & 2 deletions src/modes/freehand/freehand.mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
NumericStyling,
Cursor,
UpdateTypes,
POLYGON_PROPERTIES,
COMMON_PROPERTIES,
} from "../../common";
import { Polygon } from "geojson";

Expand Down Expand Up @@ -300,7 +300,7 @@ export class TerraDrawFreehandMode extends TerraDrawBaseDrawMode<FreehandPolygon
},
properties: {
mode: this.mode,
[POLYGON_PROPERTIES.CLOSING_POINT]: true,
[COMMON_PROPERTIES.CLOSING_POINT]: true,
},
},
]);
Expand Down
32 changes: 29 additions & 3 deletions src/modes/linestring/linestring.mode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ describe("TerraDrawLineStringMode", () => {
});

describe("styleFeature", () => {
it("returns the correct styles for point", () => {
it("returns the correct styles for closing point", () => {
const lineStringMode = new TerraDrawLineStringMode({
styles: {
lineStringColor: "#ffffff",
Expand All @@ -719,7 +719,33 @@ describe("TerraDrawLineStringMode", () => {
lineStringMode.styleFeature({
type: "Feature",
geometry: { type: "Point", coordinates: [] },
properties: { mode: "linestring" },
properties: { mode: "linestring", closingPoint: true },
}),
).toMatchObject({
pointColor: "#111111",
pointWidth: 3,
pointOutlineColor: "#222222",
pointOutlineWidth: 2,
});
});

it("returns the correct styles for snapping point", () => {
const lineStringMode = new TerraDrawLineStringMode({
styles: {
lineStringColor: "#ffffff",
lineStringWidth: 4,
snappingPointColor: "#111111",
snappingPointWidth: 3,
snappingPointOutlineColor: "#222222",
snappingPointOutlineWidth: 2,
},
});

expect(
lineStringMode.styleFeature({
type: "Feature",
geometry: { type: "Point", coordinates: [] },
properties: { mode: "linestring", snappingPoint: true },
}),
).toMatchObject({
pointColor: "#111111",
Expand All @@ -745,7 +771,7 @@ describe("TerraDrawLineStringMode", () => {
lineStringMode.styleFeature({
type: "Feature",
geometry: { type: "Point", coordinates: [] },
properties: { mode: "linestring" },
properties: { mode: "linestring", closingPoint: true },
}),
).toMatchObject({
pointColor: "#111111",
Expand Down
84 changes: 78 additions & 6 deletions src/modes/linestring/linestring.mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Cursor,
UpdateTypes,
CartesianPoint,
COMMON_PROPERTIES,
} from "../../common";
import { LineString, Point, Position } from "geojson";
import {
Expand Down Expand Up @@ -43,6 +44,10 @@ type LineStringStyling = {
closingPointWidth: NumericStyling;
closingPointOutlineColor: HexColorStyling;
closingPointOutlineWidth: NumericStyling;
snappingPointColor: HexColorStyling;
snappingPointWidth: NumericStyling;
snappingPointOutlineColor: HexColorStyling;
snappingPointOutlineWidth: NumericStyling;
};

interface Cursors {
Expand Down Expand Up @@ -78,6 +83,7 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
private mouseMove = false;
private insertCoordinates: InertCoordinates | undefined;
private lastCommitedCoordinates: Position[] | undefined;
private snappedPointId: FeatureId | undefined;

// Behaviors
private coordinateSnapping!: CoordinateSnappingBehavior;
Expand Down Expand Up @@ -141,9 +147,15 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
if (this.closingPointId) {
this.store.delete([this.closingPointId]);
}

if (this.snappedPointId) {
this.store.delete([this.snappedPointId]);
}

this.currentCoordinate = 0;
this.currentId = undefined;
this.closingPointId = undefined;
this.snappedPointId = undefined;
this.lastCommitedCoordinates = undefined;

// Go back to started state
Expand Down Expand Up @@ -387,10 +399,48 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
// Remove the 'live' point that changes on mouse move
currentCoordinates.pop();

const snappedCoord =
const snappedCoordinate =
this.snappingEnabled &&
this.coordinateSnapping.getSnappableCoordinate(event, this.currentId);
const updatedCoord = snappedCoord ? snappedCoord : [event.lng, event.lat];

if (snappedCoordinate) {
if (this.snappedPointId) {
this.store.updateGeometry([
{
id: this.snappedPointId,
geometry: {
type: "Point",
coordinates: snappedCoordinate,
},
},
]);
} else {
const [snappedPointId] = this.store.create([
{
geometry: {
type: "Point",
coordinates: snappedCoordinate,
},
properties: {
mode: this.mode,
[COMMON_PROPERTIES.SNAPPING_POINT]: true,
},
},
]);

this.snappedPointId = snappedPointId;
}

event.lng = snappedCoordinate[0];
event.lat = snappedCoordinate[1];
} else if (this.snappedPointId) {
this.store.delete([this.snappedPointId]);
this.snappedPointId = undefined;
}

const updatedCoord = snappedCoordinate
? snappedCoordinate
: [event.lng, event.lat];

// We want to ensure that when we are hovering over
// the closing point that the pointer cursor is shown
Expand Down Expand Up @@ -448,6 +498,12 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
}
this.mouseMove = false;

// Reset the snapping point
if (this.snappedPointId) {
this.store.delete([this.snappedPointId]);
this.snappedPointId = undefined;
}

if (this.currentCoordinate === 0) {
const snappedCoord =
this.snappingEnabled &&
Expand Down Expand Up @@ -502,8 +558,10 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
cleanUp() {
const cleanUpId = this.currentId;
const cleanupClosingPointId = this.closingPointId;
const snappedPointId = this.snappedPointId;

this.closingPointId = undefined;
this.snappedPointId = undefined;
this.currentId = undefined;
this.currentCoordinate = 0;
if (this.state === "drawing") {
Expand All @@ -514,6 +572,9 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
if (cleanUpId !== undefined) {
this.store.delete([cleanUpId]);
}
if (snappedPointId !== undefined) {
this.store.delete([snappedPointId]);
}
if (cleanupClosingPointId !== undefined) {
this.store.delete([cleanupClosingPointId]);
}
Expand Down Expand Up @@ -549,26 +610,37 @@ export class TerraDrawLineStringMode extends TerraDrawBaseDrawMode<LineStringSty
feature.geometry.type === "Point" &&
feature.properties.mode === this.mode
) {
const isClosingPoint =
feature.properties[COMMON_PROPERTIES.CLOSING_POINT];

styles.pointColor = this.getHexColorStylingValue(
this.styles.closingPointColor,
isClosingPoint
? this.styles.closingPointColor
: this.styles.snappingPointColor,
styles.pointColor,
feature,
);

styles.pointWidth = this.getNumericStylingValue(
this.styles.closingPointWidth,
isClosingPoint
? this.styles.closingPointWidth
: this.styles.snappingPointWidth,
styles.pointWidth,
feature,
);

styles.pointOutlineColor = this.getHexColorStylingValue(
this.styles.closingPointOutlineColor,
isClosingPoint
? this.styles.closingPointOutlineColor
: this.styles.snappingPointOutlineColor,
"#ffffff",
feature,
);

styles.pointOutlineWidth = this.getNumericStylingValue(
this.styles.closingPointOutlineWidth,
isClosingPoint
? this.styles.closingPointOutlineWidth
: this.styles.snappingPointOutlineWidth,
2,
feature,
);
Expand Down
6 changes: 3 additions & 3 deletions src/modes/polygon/behaviors/closing-points.behavior.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Point, Position } from "geojson";
import { BehaviorConfig, TerraDrawModeBehavior } from "../../base.behavior";
import { POLYGON_PROPERTIES, TerraDrawMouseEvent } from "../../../common";
import { COMMON_PROPERTIES, TerraDrawMouseEvent } from "../../../common";
import { PixelDistanceBehavior } from "../../pixel-distance.behavior";

export class ClosingPointsBehavior extends TerraDrawModeBehavior {
Expand Down Expand Up @@ -38,7 +38,7 @@ export class ClosingPointsBehavior extends TerraDrawModeBehavior {
} as Point,
properties: {
mode,
[POLYGON_PROPERTIES.CLOSING_POINT]: true,
[COMMON_PROPERTIES.CLOSING_POINT]: true,
},
},
// Final coordinate
Expand All @@ -49,7 +49,7 @@ export class ClosingPointsBehavior extends TerraDrawModeBehavior {
} as Point,
properties: {
mode,
[POLYGON_PROPERTIES.CLOSING_POINT]: true,
[COMMON_PROPERTIES.CLOSING_POINT]: true,
},
},
],
Expand Down
32 changes: 30 additions & 2 deletions src/modes/polygon/polygon.mode.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ describe("styleFeature", () => {
});
});

it("returns the correct styles for point", () => {
it("returns the correct styles for closing point", () => {
const polygonMode = new TerraDrawPolygonMode({
styles: {
fillColor: "#ffffff",
Expand All @@ -881,7 +881,35 @@ describe("styleFeature", () => {
polygonMode.styleFeature({
type: "Feature",
geometry: { type: "Point", coordinates: [] },
properties: { mode: "polygon" },
properties: { mode: "polygon", closingPoint: true },
}),
).toMatchObject({
pointWidth: 2,
pointColor: "#dddddd",
pointOutlineColor: "#222222",
pointOutlineWidth: 1,
});
});

it("returns the correct styles for snapping point", () => {
const polygonMode = new TerraDrawPolygonMode({
styles: {
fillColor: "#ffffff",
outlineColor: "#111111",
outlineWidth: 2,
fillOpacity: 0.5,
snappingPointWidth: 2,
snappingPointColor: "#dddddd",
snappingPointOutlineWidth: 1,
snappingPointOutlineColor: "#222222",
},
});

expect(
polygonMode.styleFeature({
type: "Feature",
geometry: { type: "Point", coordinates: [] },
properties: { mode: "polygon", snappingPoint: true },
}),
).toMatchObject({
pointWidth: 2,
Expand Down
Loading

0 comments on commit 56955a3

Please sign in to comment.