terra-draw
Advanced tools
Comparing version 1.0.0-beta.1 to 1.0.0-beta.3
@@ -25,3 +25,2 @@ import { TerraDrawChanges, SetCursor, TerraDrawStylingFunction, TerraDrawCallbacks } from "../common"; | ||
private _setGeoJSONLayerData; | ||
private getEmptyGeometries; | ||
private changedIds; | ||
@@ -28,0 +27,0 @@ private updateChangedIds; |
import { TerraDrawChanges, SetCursor, TerraDrawStylingFunction, TerraDrawCallbacks } from "../common"; | ||
import CircleGeom from "ol/geom/Circle"; | ||
import Feature from "ol/Feature"; | ||
@@ -7,2 +6,3 @@ import GeoJSON from "ol/format/GeoJSON"; | ||
import Circle from "ol/style/Circle"; | ||
import Fill from "ol/style/Fill"; | ||
import Stroke from "ol/style/Stroke"; | ||
@@ -12,14 +12,14 @@ import Style from "ol/style/Style"; | ||
import VectorLayer from "ol/layer/Vector"; | ||
import { toLonLat } from "ol/proj"; | ||
import { getUserProjection } from "ol/proj"; | ||
import { BaseAdapterConfig, TerraDrawBaseAdapter } from "./common/base.adapter"; | ||
type InjectableOL = { | ||
Circle: typeof CircleGeom; | ||
export type InjectableOL = { | ||
Fill: typeof Fill; | ||
Feature: typeof Feature; | ||
GeoJSON: typeof GeoJSON; | ||
Style: typeof Style; | ||
CircleStyle: typeof Circle; | ||
Circle: typeof Circle; | ||
VectorLayer: typeof VectorLayer; | ||
VectorSource: typeof VectorSource; | ||
Stroke: typeof Stroke; | ||
toLonLat: typeof toLonLat; | ||
getUserProjection: typeof getUserProjection; | ||
}; | ||
@@ -44,8 +44,2 @@ export declare class TerraDrawOpenLayersAdapter extends TerraDrawBaseAdapter { | ||
private hexToRGB; | ||
/** | ||
* Converts a hexideciaml color to RGB | ||
* @param feature | ||
* @param styling | ||
* @returns an object to red green and blue (RGB) color | ||
*/ | ||
private getStyles; | ||
@@ -123,2 +117,1 @@ /** | ||
} | ||
export {}; |
@@ -31,5 +31,2 @@ import { StoreChangeHandler, GeoJSONStore, GeoJSONStoreFeatures, FeatureId } from "./store/store"; | ||
} | ||
export type Required<T> = { | ||
[P in keyof T]-?: T[P]; | ||
}; | ||
export type Cursor = Parameters<SetCursor>[0]; | ||
@@ -36,0 +33,0 @@ export type SetCursor = (cursor: "unset" | "grab" | "grabbing" | "crosshair" | "pointer" | "wait" | "move") => void; |
@@ -10,1 +10,2 @@ import { Position } from "geojson"; | ||
}): number; | ||
export declare function normalizeBearing(bearing: number): number; |
import { TerraDrawMouseEvent, TerraDrawAdapterStyling, TerraDrawKeyboardEvent, HexColorStyling, NumericStyling, Cursor } from "../../common"; | ||
import { TerraDrawBaseDrawMode, BaseModeOptions, CustomStyling } from "../base.mode"; | ||
import { BehaviorConfig } from "../base.behavior"; | ||
import { GeoJSONStoreFeatures } from "../../store/store"; | ||
@@ -30,3 +29,2 @@ type TerraDrawPolygonModeKeyEvents = { | ||
private keyEvents; | ||
private pixelDistance; | ||
private cursors; | ||
@@ -37,4 +35,2 @@ private mouseMove; | ||
/** @internal */ | ||
registerBehaviors(config: BehaviorConfig): void; | ||
/** @internal */ | ||
start(): void; | ||
@@ -41,0 +37,0 @@ /** @internal */ |
@@ -11,3 +11,3 @@ import { Feature, Point, Polygon, LineString } from "geojson"; | ||
export type GeoJSONStoreFeatures = Feature<GeoJSONStoreGeometries, DefinedProperties>; | ||
export type StoreChangeEvents = "delete" | "create" | "update" | "styling"; | ||
type StoreChangeEvents = "delete" | "create" | "update" | "styling"; | ||
export type StoreChangeHandler = (ids: FeatureId[], change: StoreChangeEvents) => void; | ||
@@ -19,3 +19,3 @@ export type FeatureId = string | number; | ||
}; | ||
export type GeoJSONStoreConfig<Id extends FeatureId> = { | ||
type GeoJSONStoreConfig<Id extends FeatureId> = { | ||
idStrategy?: IdStrategy<Id>; | ||
@@ -22,0 +22,0 @@ tracked?: boolean; |
@@ -24,2 +24,3 @@ import { TerraDrawGoogleMapsAdapter } from "./adapters/google-maps.adapter"; | ||
import { TerraDrawAngledRectangleMode } from "./modes/angled-rectangle/angled-rectangle.mode"; | ||
import { TerraDrawSectorMode } from "./modes/sector/sector.mode"; | ||
type FinishListener = (id: FeatureId, context: OnFinishContext) => void; | ||
@@ -224,2 +225,2 @@ type ChangeListener = (ids: FeatureId[], type: string) => void; | ||
}; | ||
export { TerraDraw, TerraDrawSelectMode, TerraDrawPointMode, TerraDrawLineStringMode, TerraDrawPolygonMode, TerraDrawCircleMode, TerraDrawFreehandMode, TerraDrawRenderMode, TerraDrawRectangleMode, TerraDrawAngledRectangleMode, TerraDrawGoogleMapsAdapter, TerraDrawMapboxGLAdapter, TerraDrawLeafletAdapter, TerraDrawMapLibreGLAdapter, TerraDrawOpenLayersAdapter, TerraDrawArcGISMapsSDKAdapter, TerraDrawExtend, BehaviorConfig, GeoJSONStoreFeatures, HexColor, TerraDrawMouseEvent, TerraDrawAdapterStyling, TerraDrawKeyboardEvent, TerraDrawChanges, TerraDrawStylingFunction, Project, Unproject, SetCursor, GetLngLatFromEvent, ValidateMinAreaSquareMeters, ValidateMaxAreaSquareMeters, ValidateNotSelfIntersecting, }; | ||
export { TerraDraw, TerraDrawSelectMode, TerraDrawPointMode, TerraDrawLineStringMode, TerraDrawPolygonMode, TerraDrawCircleMode, TerraDrawFreehandMode, TerraDrawRenderMode, TerraDrawRectangleMode, TerraDrawAngledRectangleMode, TerraDrawSectorMode, TerraDrawGoogleMapsAdapter, TerraDrawMapboxGLAdapter, TerraDrawLeafletAdapter, TerraDrawMapLibreGLAdapter, TerraDrawOpenLayersAdapter, TerraDrawArcGISMapsSDKAdapter, TerraDrawExtend, BehaviorConfig, GeoJSONStoreFeatures, HexColor, TerraDrawMouseEvent, TerraDrawAdapterStyling, TerraDrawKeyboardEvent, TerraDrawChanges, TerraDrawStylingFunction, Project, Unproject, SetCursor, GetLngLatFromEvent, ValidateMinAreaSquareMeters, ValidateMaxAreaSquareMeters, ValidateNotSelfIntersecting, }; |
@@ -56,3 +56,3 @@ import { test, expect } from "@playwright/test"; | ||
test("mode can set and can be used to create a point", async ({ page }) => { | ||
test("mode can set and used to create a point", async ({ page }) => { | ||
const mapDiv = await setupMap({ page }); | ||
@@ -65,5 +65,3 @@ await changeMode({ page, mode }); | ||
test("mode can set and can be used to create multiple points", async ({ | ||
page, | ||
}) => { | ||
test("mode can set and used to create multiple points", async ({ page }) => { | ||
const mapDiv = await setupMap({ page }); | ||
@@ -96,3 +94,3 @@ await changeMode({ page, mode }); | ||
for (const { name, config } of options) { | ||
test(`mode can set and can be used to create a linestring${name}`, async ({ | ||
test(`mode can set and used to create a linestring${name}`, async ({ | ||
page, | ||
@@ -114,3 +112,3 @@ }) => { | ||
test(`mode can set and can be used to create a linestring with multiple points${name}`, async ({ | ||
test(`mode can set and used to create a linestring with multiple points${name}`, async ({ | ||
page, | ||
@@ -140,3 +138,3 @@ }) => { | ||
test(`mode can set and can be used to create a linestring with multiple clicked points${name}`, async ({ | ||
test(`mode can set and used to create a linestring with multiple clicked points${name}`, async ({ | ||
page, | ||
@@ -166,3 +164,3 @@ }) => { | ||
test(`mode can set and can be used to create multiple linestrings${name}`, async ({ | ||
test(`mode can set and used to create multiple linestrings${name}`, async ({ | ||
page, | ||
@@ -206,3 +204,3 @@ }) => { | ||
test("mode can set and can be used to create a polygon", async ({ page }) => { | ||
test("mode can set and used to create a polygon", async ({ page }) => { | ||
const mapDiv = await setupMap({ page }); | ||
@@ -322,5 +320,3 @@ await changeMode({ page, mode }); | ||
test("mode can set and can be used to create a rectangle", async ({ | ||
page, | ||
}) => { | ||
test("mode can set and used to create a rectangle", async ({ page }) => { | ||
const mapDiv = await setupMap({ page }); | ||
@@ -342,3 +338,3 @@ await changeMode({ page, mode }); | ||
test("mode can set and can be used to create an angled rectangle (horizontal up)", async ({ | ||
test("mode can set and used to create an angled rectangle (horizontal up)", async ({ | ||
page, | ||
@@ -362,3 +358,3 @@ }) => { | ||
test("mode can set and can be used to create an angled rectangle (horizontal down)", async ({ | ||
test("mode can set and used to create an angled rectangle (horizontal down)", async ({ | ||
page, | ||
@@ -382,3 +378,3 @@ }) => { | ||
test("mode can set and can be used to create an angled (diagonal)", async ({ | ||
test("mode can set and used to create an angled (diagonal)", async ({ | ||
page, | ||
@@ -402,3 +398,3 @@ }) => { | ||
test("mode can set and can be used to create an angled (diagonal 2)", async ({ | ||
test("mode can set and used to create an angled (diagonal 2)", async ({ | ||
page, | ||
@@ -425,6 +421,130 @@ }) => { | ||
test.describe("sector mode", () => { | ||
const mode = "sector"; | ||
test("mode can set and used to create a sector less than 90 degrees (clockwise)", async ({ | ||
page, | ||
}) => { | ||
const mapDiv = await setupMap({ page }); | ||
await changeMode({ page, mode }); | ||
await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width / 3, mapDiv.height / 2, { steps: 30 }); | ||
await page.mouse.click(mapDiv.width / 3, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width / 3, mapDiv.height / 3, { | ||
steps: 30, | ||
}); | ||
await page.mouse.click(mapDiv.width / 3, mapDiv.height / 3); | ||
await expectPaths({ page, count: 1 }); | ||
await expectPathDimensions({ page, width: 217, height: 109 }); | ||
}); | ||
test("mode can set and used to create a sector more than 90 degrees (clockwise)", async ({ | ||
page, | ||
}) => { | ||
const mapDiv = await setupMap({ page }); | ||
await changeMode({ page, mode }); | ||
await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width / 3, mapDiv.height / 2, { steps: 30 }); | ||
await page.mouse.click(mapDiv.width / 3, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width * 0.75, mapDiv.height / 3, { | ||
steps: 30, | ||
}); | ||
await page.mouse.click(mapDiv.width * 0.75, mapDiv.height / 3); | ||
await expectPaths({ page, count: 1 }); | ||
await expectPathDimensions({ page, width: 417, height: 217 }); | ||
}); | ||
test("mode can set and used to create a sector more than 180 degrees (clockwise)", async ({ | ||
page, | ||
}) => { | ||
const mapDiv = await setupMap({ page }); | ||
await changeMode({ page, mode }); | ||
await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width / 3, mapDiv.height / 2, { steps: 30 }); | ||
await page.mouse.click(mapDiv.width / 3, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width * 0.75, mapDiv.height / 3, { | ||
steps: 10, | ||
}); | ||
await page.mouse.move(mapDiv.width * 0.4, mapDiv.height / 1.5, { | ||
steps: 10, | ||
}); | ||
await page.mouse.click(mapDiv.width * 0.4, mapDiv.height / 1.5); | ||
await expectPaths({ page, count: 1 }); | ||
await expectPathDimensions({ page, width: 430, height: 430 }); | ||
}); | ||
test("mode can set and used to create a sector less than 90 degrees (anticlockwise)", async ({ | ||
page, | ||
}) => { | ||
const mapDiv = await setupMap({ page }); | ||
await changeMode({ page, mode }); | ||
await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width / 3, mapDiv.height / 2, { steps: 30 }); | ||
await page.mouse.click(mapDiv.width / 3, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width * 0.4, mapDiv.height / 1.5, { | ||
steps: 30, | ||
}); | ||
await page.mouse.click(mapDiv.width * 0.4, mapDiv.height / 1.5); | ||
await expectPaths({ page, count: 1 }); | ||
await expectPathDimensions({ page, width: 217, height: 150 }); | ||
}); | ||
test("mode can set and used to create a sector more than 90 degrees (anticlockwise)", async ({ | ||
page, | ||
}) => { | ||
const mapDiv = await setupMap({ page }); | ||
await changeMode({ page, mode }); | ||
await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width / 3, mapDiv.height / 2, { steps: 30 }); | ||
await page.mouse.click(mapDiv.width / 3, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width * 0.75, mapDiv.height / 1.5, { | ||
steps: 30, | ||
}); | ||
await page.mouse.click(mapDiv.width * 0.75, mapDiv.height / 1.5); | ||
await expectPaths({ page, count: 1 }); | ||
await expectPathDimensions({ page, width: 417, height: 217 }); | ||
}); | ||
test("mode can set and used to create a sector more than 180 degrees (anticlockwise)", async ({ | ||
page, | ||
}) => { | ||
const mapDiv = await setupMap({ page }); | ||
await changeMode({ page, mode }); | ||
await page.mouse.click(mapDiv.width / 2, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width / 3, mapDiv.height / 2, { steps: 30 }); | ||
await page.mouse.click(mapDiv.width / 3, mapDiv.height / 2); | ||
await page.mouse.move(mapDiv.width * 0.75, mapDiv.height / 1.5, { | ||
steps: 30, | ||
}); | ||
await page.mouse.move(mapDiv.width * 0.75, mapDiv.height / 3, { | ||
steps: 30, | ||
}); | ||
await page.mouse.click(mapDiv.width * 0.75, mapDiv.height / 3); | ||
await expectPaths({ page, count: 1 }); | ||
await expectPathDimensions({ page, width: 430, height: 292 }); | ||
}); | ||
}); | ||
test.describe("circle mode", () => { | ||
const mode = "circle"; | ||
test("mode can set and can be used to create a web mercator circle", async ({ | ||
test("mode can set and used to create a web mercator circle", async ({ | ||
page, | ||
@@ -444,3 +564,3 @@ }) => { | ||
test("mode can set and can be used to create a geodesic circle", async ({ | ||
test("mode can set and used to create a geodesic circle", async ({ | ||
page, | ||
@@ -447,0 +567,0 @@ }) => { |
@@ -63,3 +63,4 @@ import { Page, expect } from "@playwright/test"; | ||
| "circle" | ||
| "angled-rectangle"; | ||
| "angled-rectangle" | ||
| "sector"; | ||
}) => { | ||
@@ -87,3 +88,6 @@ let modeText = mode.charAt(0).toUpperCase() + mode.slice(1); | ||
); | ||
expect(color).toBe("rgb(39, 204, 255)"); // We set hex but it gets computed to rgb | ||
expect( | ||
color, | ||
"Text rgb color should match the expected selected button color", | ||
).toBe("rgb(39, 204, 255)"); // We set hex but it gets computed to rgb | ||
}; | ||
@@ -90,0 +94,0 @@ |
{ | ||
"name": "terra-draw", | ||
"version": "1.0.0-beta.1", | ||
"version": "1.0.0-beta.3", | ||
"description": "Frictionless map drawing across mapping provider", | ||
@@ -13,2 +13,3 @@ "scripts": { | ||
"watch": "microbundle --watch --format modern", | ||
"unused": "knip", | ||
"test": "jest --config jest.config.ts", | ||
@@ -74,2 +75,3 @@ "test:coverage": "jest --config jest.config.ts --coverage", | ||
"jest-environment-jsdom": "29.7.0", | ||
"knip": "^5.30.2", | ||
"leaflet": "^1.9.4", | ||
@@ -85,3 +87,3 @@ "mapbox-gl": "2.13.0", | ||
"tsx": "4.7.2", | ||
"typedoc": "^0.26.2", | ||
"typedoc": "^0.26.6", | ||
"typescript": "5.5.2" | ||
@@ -161,3 +163,16 @@ }, | ||
}, | ||
"sideEffects": false | ||
"sideEffects": false, | ||
"knip": { | ||
"$schema": "https://unpkg.com/knip@5/schema.json", | ||
"entry": [ | ||
"src/terra-draw.ts" | ||
], | ||
"project": [ | ||
"src/**/*.ts" | ||
], | ||
"include": [ | ||
"files", | ||
"types" | ||
] | ||
} | ||
} |
@@ -1,3 +0,9 @@ | ||
<img src="./logo.png" alt="Terra Draw Logo" width="400"/> | ||
<picture> | ||
<source media="(prefers-color-scheme: dark)" srcset="./assets/logo-dark-mode.png"> | ||
<source media="(prefers-color-scheme: light)" srcset="./assets/logo.png"> | ||
<img alt="Terra Draw logo" src="./assets/logo.png" width="400px"> | ||
</picture> | ||
<p></p> | ||
![Terra Draw CI Badge](https://github.com/JamesLMilner/terra-draw/actions/workflows/ci.yml/badge.svg) | ||
@@ -10,4 +16,5 @@ [![npm version](https://badge.fury.io/js/terra-draw.svg)](https://badge.fury.io/js/terra-draw) | ||
![An example of drawing geodesic lines using Terra Draw with Leaflet](./readme.gif) | ||
![An example of drawing geodesic lines using Terra Draw with Leaflet](./assets/readme.gif) | ||
### Library Support | ||
@@ -14,0 +21,0 @@ |
@@ -17,3 +17,4 @@ { | ||
"out": "docs", | ||
"skipErrorChecking": true | ||
"skipErrorChecking": true, | ||
"sourceLinkExternal": true | ||
}, | ||
@@ -20,0 +21,0 @@ "exclude": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
104
51
3276293
32
9607