pixi-watchface-engine 0.1.11 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +29 -0
- package/dist/elements/TextElement.d.ts.map +1 -1
- package/dist/geometry/DisplayGeometry.d.ts +46 -0
- package/dist/geometry/DisplayGeometry.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +125 -0
- package/package.json +2 -1
package/API.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
5. [Plugins](#plugins)
|
|
10
10
|
6. [Events](#events)
|
|
11
11
|
7. [Types](#types)
|
|
12
|
+
8. [Display Geometry](#display-geometry)
|
|
12
13
|
|
|
13
14
|
---
|
|
14
15
|
|
|
@@ -734,6 +735,34 @@ interface Bounds {
|
|
|
734
735
|
|
|
735
736
|
---
|
|
736
737
|
|
|
738
|
+
## Display Geometry
|
|
739
|
+
|
|
740
|
+
Display geometry describes the face's logical shape and dimensions separately
|
|
741
|
+
from the editor's pixel dimensions. The geometry helpers are device-independent;
|
|
742
|
+
they accept circular and rectangular profiles without inferring a shape.
|
|
743
|
+
|
|
744
|
+
```typescript
|
|
745
|
+
const geometry = { shape: 'rectangle', width: 448, height: 486 } as const;
|
|
746
|
+
const fitted = fitDisplayGeometry(geometry, {
|
|
747
|
+
x: 0, y: 0, width: 600, height: 600, // editor bounds, not logical face size
|
|
748
|
+
});
|
|
749
|
+
const editorPoint = displayToViewportPoint(
|
|
750
|
+
{ x: 224, y: 243 }, geometry, fitted,
|
|
751
|
+
);
|
|
752
|
+
const hit = isPointInDisplay({ x: 0, y: 0 }, geometry); // true for rectangles
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
`fitDisplayGeometry` centers the logical display in editor bounds and uses one
|
|
756
|
+
uniform scale. `displayToViewportPoint` and `viewportToDisplayPoint` convert
|
|
757
|
+
coordinates while preserving either the default `top-left` or `center` origin.
|
|
758
|
+
`isPointInDisplay` uses rectangular bounds or the circular visible boundary.
|
|
759
|
+
`createDisplayMask` creates a Pixi `Graphics` mask for the same shape;
|
|
760
|
+
`applyDisplayMask` attaches one to a container and returns it for cleanup.
|
|
761
|
+
Circular profiles must have equal positive width and height. Invalid dimensions
|
|
762
|
+
and unknown shapes throw instead of silently selecting a default.
|
|
763
|
+
|
|
764
|
+
---
|
|
765
|
+
|
|
737
766
|
## Complete Example
|
|
738
767
|
|
|
739
768
|
```typescript
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextElement.d.ts","sourceRoot":"","sources":["../../src/elements/TextElement.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"TextElement.d.ts","sourceRoot":"","sources":["../../src/elements/TextElement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Container, Graphics } from 'pixi.js';
|
|
2
|
+
import type { Bounds, CoordinateOrigin } from '../types.ts';
|
|
3
|
+
/** Display shape supported by watch-face geometry. */
|
|
4
|
+
export type DisplayShape = 'circle' | 'rectangle';
|
|
5
|
+
/** Logical display dimensions, independent of an editor's pixel dimensions. */
|
|
6
|
+
export interface DisplayGeometry {
|
|
7
|
+
shape: DisplayShape;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
}
|
|
11
|
+
export interface DisplayPoint {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}
|
|
15
|
+
/** A display's fitted rectangle in the editor, plus its uniform scale. */
|
|
16
|
+
export interface DisplayViewport extends Bounds {
|
|
17
|
+
scale: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check and narrow geometry received from saved data or device integrations.
|
|
21
|
+
* Circular displays use a square logical coordinate space.
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateDisplayGeometry(value: unknown): asserts value is DisplayGeometry;
|
|
24
|
+
/** Return logical display bounds for the requested coordinate origin. */
|
|
25
|
+
export declare function getDisplayBounds(geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): Bounds;
|
|
26
|
+
/**
|
|
27
|
+
* Fit a logical display inside an editor-space rectangle without distortion.
|
|
28
|
+
* The returned bounds are centered in the editor rectangle; the editor
|
|
29
|
+
* rectangle is never interpreted as the face's logical dimensions.
|
|
30
|
+
*/
|
|
31
|
+
export declare function fitDisplayGeometry(geometry: DisplayGeometry, editorBounds: Bounds): DisplayViewport;
|
|
32
|
+
/** Convert a logical face coordinate to the fitted editor viewport. */
|
|
33
|
+
export declare function displayToViewportPoint(point: DisplayPoint, geometry: DisplayGeometry, viewport: DisplayViewport, coordinateOrigin?: CoordinateOrigin): DisplayPoint;
|
|
34
|
+
/** Convert a fitted editor-space point to logical face coordinates. */
|
|
35
|
+
export declare function viewportToDisplayPoint(point: DisplayPoint, geometry: DisplayGeometry, viewport: DisplayViewport, coordinateOrigin?: CoordinateOrigin): DisplayPoint;
|
|
36
|
+
/** Test whether a logical coordinate falls inside the visible display shape. */
|
|
37
|
+
export declare function isPointInDisplay(point: DisplayPoint, geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Create a Pixi mask matching the visible display shape. Add the returned
|
|
40
|
+
* Graphics to the masked container (or a sibling in the same coordinate
|
|
41
|
+
* space) and assign it as that container's mask.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createDisplayMask(geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): Graphics;
|
|
44
|
+
/** Attach a shape-aware Pixi mask and return it for later removal/destruction. */
|
|
45
|
+
export declare function applyDisplayMask(target: Container, geometry: DisplayGeometry, coordinateOrigin?: CoordinateOrigin): Graphics;
|
|
46
|
+
//# sourceMappingURL=DisplayGeometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DisplayGeometry.d.ts","sourceRoot":"","sources":["../../src/geometry/DisplayGeometry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5D,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAElD,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,0EAA0E;AAC1E,MAAM,WAAW,eAAgB,SAAQ,MAAM;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,eAAe,CAkBxF;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,MAAM,CASR;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,MAAM,GACnB,eAAe,CAcjB;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,YAAY,CASd;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,YAAY,CASd;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,OAAO,CAcT;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,QAAQ,CAUV;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,eAAe,EACzB,gBAAgB,GAAE,gBAA6B,GAC9C,QAAQ,CAKV"}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export { ZOrderManager } from "./managers/ZOrderManager.ts";
|
|
|
25
25
|
export { SelectionManager } from "./selection/SelectionManager.ts";
|
|
26
26
|
export { SerializationManager } from "./managers/SerializationManager.ts";
|
|
27
27
|
export type { FillDirection, ShapeType, LineCap, ArcPath, ElementType, CoordinateOrigin, SerializedElement, WatchfaceState, UndoableAction, HandleConfig, Bounds, } from "./types.ts";
|
|
28
|
+
export { applyDisplayMask, createDisplayMask, displayToViewportPoint, fitDisplayGeometry, getDisplayBounds, isPointInDisplay, validateDisplayGeometry, viewportToDisplayPoint, } from "./geometry/DisplayGeometry.ts";
|
|
29
|
+
export type { DisplayGeometry, DisplayPoint, DisplayShape, DisplayViewport, } from "./geometry/DisplayGeometry.ts";
|
|
28
30
|
export { EventBus } from "./EventBus.ts";
|
|
29
31
|
export type { EngineEventMap } from "./EventBus.ts";
|
|
30
32
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,YAAY,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAGvF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1E,YAAY,EACV,aAAa,EACb,SAAS,EACT,OAAO,EACP,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAGnE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGhE,YAAY,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,YAAY,EAAE,4BAA4B,EAAE,MAAM,oCAAoC,CAAC;AAGvF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1E,YAAY,EACV,aAAa,EACb,SAAS,EACT,OAAO,EACP,OAAO,EACP,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,MAAM,GACP,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -31266,6 +31266,7 @@ class TextElement extends BaseElement {
|
|
|
31266
31266
|
s2.wordWrap = value != null;
|
|
31267
31267
|
s2.wordWrapWidth = value ?? 100;
|
|
31268
31268
|
});
|
|
31269
|
+
this.redraw();
|
|
31269
31270
|
this.emitChange("boxWidth", old, value);
|
|
31270
31271
|
}
|
|
31271
31272
|
get breakWords() {
|
|
@@ -34796,7 +34797,131 @@ class AlignmentGuidesPlugin {
|
|
|
34796
34797
|
this.graphics.destroy();
|
|
34797
34798
|
}
|
|
34798
34799
|
}
|
|
34800
|
+
// src/geometry/DisplayGeometry.ts
|
|
34801
|
+
function validateDisplayGeometry(value) {
|
|
34802
|
+
if (typeof value !== "object" || value === null) {
|
|
34803
|
+
throw new TypeError("Display geometry must be an object.");
|
|
34804
|
+
}
|
|
34805
|
+
const geometry = value;
|
|
34806
|
+
if (geometry.shape !== "circle" && geometry.shape !== "rectangle") {
|
|
34807
|
+
throw new TypeError(`Unsupported display shape: ${String(geometry.shape)}.`);
|
|
34808
|
+
}
|
|
34809
|
+
if (typeof geometry.width !== "number" || !Number.isFinite(geometry.width) || geometry.width <= 0) {
|
|
34810
|
+
throw new RangeError("Display geometry width must be a positive finite number.");
|
|
34811
|
+
}
|
|
34812
|
+
if (typeof geometry.height !== "number" || !Number.isFinite(geometry.height) || geometry.height <= 0) {
|
|
34813
|
+
throw new RangeError("Display geometry height must be a positive finite number.");
|
|
34814
|
+
}
|
|
34815
|
+
if (geometry.shape === "circle" && geometry.width !== geometry.height) {
|
|
34816
|
+
throw new RangeError("Circular display geometry must have equal width and height.");
|
|
34817
|
+
}
|
|
34818
|
+
}
|
|
34819
|
+
function getDisplayBounds(geometry, coordinateOrigin = "top-left") {
|
|
34820
|
+
validateDisplayGeometry(geometry);
|
|
34821
|
+
validateCoordinateOrigin(coordinateOrigin);
|
|
34822
|
+
return {
|
|
34823
|
+
x: coordinateOrigin === "center" ? -geometry.width / 2 : 0,
|
|
34824
|
+
y: coordinateOrigin === "center" ? -geometry.height / 2 : 0,
|
|
34825
|
+
width: geometry.width,
|
|
34826
|
+
height: geometry.height
|
|
34827
|
+
};
|
|
34828
|
+
}
|
|
34829
|
+
function fitDisplayGeometry(geometry, editorBounds) {
|
|
34830
|
+
validateDisplayGeometry(geometry);
|
|
34831
|
+
validateBounds(editorBounds, "Editor bounds");
|
|
34832
|
+
const scale = Math.min(editorBounds.width / geometry.width, editorBounds.height / geometry.height);
|
|
34833
|
+
const width = geometry.width * scale;
|
|
34834
|
+
const height = geometry.height * scale;
|
|
34835
|
+
return {
|
|
34836
|
+
x: editorBounds.x + (editorBounds.width - width) / 2,
|
|
34837
|
+
y: editorBounds.y + (editorBounds.height - height) / 2,
|
|
34838
|
+
width,
|
|
34839
|
+
height,
|
|
34840
|
+
scale
|
|
34841
|
+
};
|
|
34842
|
+
}
|
|
34843
|
+
function displayToViewportPoint(point, geometry, viewport, coordinateOrigin = "top-left") {
|
|
34844
|
+
validateDisplayGeometry(geometry);
|
|
34845
|
+
validateViewport(viewport);
|
|
34846
|
+
validatePoint(point, "Display point");
|
|
34847
|
+
const bounds = getDisplayBounds(geometry, coordinateOrigin);
|
|
34848
|
+
return {
|
|
34849
|
+
x: viewport.x + (point.x - bounds.x) * viewport.scale,
|
|
34850
|
+
y: viewport.y + (point.y - bounds.y) * viewport.scale
|
|
34851
|
+
};
|
|
34852
|
+
}
|
|
34853
|
+
function viewportToDisplayPoint(point, geometry, viewport, coordinateOrigin = "top-left") {
|
|
34854
|
+
validateDisplayGeometry(geometry);
|
|
34855
|
+
validateViewport(viewport);
|
|
34856
|
+
validatePoint(point, "Viewport point");
|
|
34857
|
+
const bounds = getDisplayBounds(geometry, coordinateOrigin);
|
|
34858
|
+
return {
|
|
34859
|
+
x: bounds.x + (point.x - viewport.x) / viewport.scale,
|
|
34860
|
+
y: bounds.y + (point.y - viewport.y) / viewport.scale
|
|
34861
|
+
};
|
|
34862
|
+
}
|
|
34863
|
+
function isPointInDisplay(point, geometry, coordinateOrigin = "top-left") {
|
|
34864
|
+
validateDisplayGeometry(geometry);
|
|
34865
|
+
validatePoint(point, "Display point");
|
|
34866
|
+
const bounds = getDisplayBounds(geometry, coordinateOrigin);
|
|
34867
|
+
if (geometry.shape === "rectangle") {
|
|
34868
|
+
return point.x >= bounds.x && point.x <= bounds.x + bounds.width && point.y >= bounds.y && point.y <= bounds.y + bounds.height;
|
|
34869
|
+
}
|
|
34870
|
+
const centerX = bounds.x + bounds.width / 2;
|
|
34871
|
+
const centerY = bounds.y + bounds.height / 2;
|
|
34872
|
+
const radius = geometry.width / 2;
|
|
34873
|
+
return (point.x - centerX) ** 2 + (point.y - centerY) ** 2 <= radius ** 2;
|
|
34874
|
+
}
|
|
34875
|
+
function createDisplayMask(geometry, coordinateOrigin = "top-left") {
|
|
34876
|
+
const bounds = getDisplayBounds(geometry, coordinateOrigin);
|
|
34877
|
+
const mask = new Graphics;
|
|
34878
|
+
if (geometry.shape === "circle") {
|
|
34879
|
+
mask.circle(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2, bounds.width / 2);
|
|
34880
|
+
} else {
|
|
34881
|
+
mask.rect(bounds.x, bounds.y, bounds.width, bounds.height);
|
|
34882
|
+
}
|
|
34883
|
+
mask.fill({ color: 16777215 });
|
|
34884
|
+
return mask;
|
|
34885
|
+
}
|
|
34886
|
+
function applyDisplayMask(target, geometry, coordinateOrigin = "top-left") {
|
|
34887
|
+
const mask = createDisplayMask(geometry, coordinateOrigin);
|
|
34888
|
+
target.addChild(mask);
|
|
34889
|
+
target.mask = mask;
|
|
34890
|
+
return mask;
|
|
34891
|
+
}
|
|
34892
|
+
function validateCoordinateOrigin(value) {
|
|
34893
|
+
if (value !== "top-left" && value !== "center") {
|
|
34894
|
+
throw new TypeError(`Unsupported coordinate origin: ${String(value)}.`);
|
|
34895
|
+
}
|
|
34896
|
+
}
|
|
34897
|
+
function validatePoint(point, label) {
|
|
34898
|
+
if (!Number.isFinite(point.x) || !Number.isFinite(point.y)) {
|
|
34899
|
+
throw new RangeError(`${label} coordinates must be finite numbers.`);
|
|
34900
|
+
}
|
|
34901
|
+
}
|
|
34902
|
+
function validateBounds(bounds, label) {
|
|
34903
|
+
if (!Number.isFinite(bounds.x) || !Number.isFinite(bounds.y)) {
|
|
34904
|
+
throw new RangeError(`${label} position must use finite numbers.`);
|
|
34905
|
+
}
|
|
34906
|
+
if (!Number.isFinite(bounds.width) || bounds.width <= 0 || !Number.isFinite(bounds.height) || bounds.height <= 0) {
|
|
34907
|
+
throw new RangeError(`${label} width and height must be positive finite numbers.`);
|
|
34908
|
+
}
|
|
34909
|
+
}
|
|
34910
|
+
function validateViewport(viewport) {
|
|
34911
|
+
validateBounds(viewport, "Viewport bounds");
|
|
34912
|
+
if (!Number.isFinite(viewport.scale) || viewport.scale <= 0) {
|
|
34913
|
+
throw new RangeError("Viewport scale must be a positive finite number.");
|
|
34914
|
+
}
|
|
34915
|
+
}
|
|
34799
34916
|
export {
|
|
34917
|
+
viewportToDisplayPoint,
|
|
34918
|
+
validateDisplayGeometry,
|
|
34919
|
+
isPointInDisplay,
|
|
34920
|
+
getDisplayBounds,
|
|
34921
|
+
fitDisplayGeometry,
|
|
34922
|
+
displayToViewportPoint,
|
|
34923
|
+
createDisplayMask,
|
|
34924
|
+
applyDisplayMask,
|
|
34800
34925
|
ZOrderManager,
|
|
34801
34926
|
WatchfaceEngine,
|
|
34802
34927
|
ViewportPlugin,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pixi-watchface-engine",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A PixiJS v8 watchface editor engine with visual editor, plugin system, and intuitive API",
|
|
5
5
|
"author": "Eric Schmar (ericschmar@gmail.com)",
|
|
6
6
|
"type": "module",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"LICENSE"
|
|
21
21
|
],
|
|
22
22
|
"scripts": {
|
|
23
|
+
"test": "bun test",
|
|
23
24
|
"typecheck": "tsc --noEmit",
|
|
24
25
|
"build": "bun build src/index.ts --outdir dist --target browser && tsc --emitDeclarationOnly --declaration",
|
|
25
26
|
"prepublishOnly": "bun run typecheck && bun run build"
|