@flighthq/path 0.3.0-next.1566.dcdf1d3 → 0.3.0-next.1584.a68fe91

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.
@@ -13,9 +13,11 @@ export * from './getPathPointAtDistance';
13
13
  export * from './getPathSegmentAtParameter';
14
14
  export * from './getPathSignedArea';
15
15
  export * from './path';
16
+ export * from './pathMorph';
16
17
  export * from './pathMeshPool';
17
18
  export * from './reversePath';
18
19
  export * from './decimatePath';
20
+ export * from './explainPathMorphCreation';
19
21
  export * from './explainStrokePathTessellation';
20
22
  export * from './strokePath';
21
23
  export * from './tessellatePath';
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iCAAiC,CAAC;AAChD,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC"}
package/dist/contract.js CHANGED
@@ -13,9 +13,11 @@ export * from './getPathPointAtDistance';
13
13
  export * from './getPathSegmentAtParameter';
14
14
  export * from './getPathSignedArea';
15
15
  export * from './path';
16
+ export * from './pathMorph';
16
17
  export * from './pathMeshPool';
17
18
  export * from './reversePath';
18
19
  export * from './decimatePath';
20
+ export * from './explainPathMorphCreation';
19
21
  export * from './explainStrokePathTessellation';
20
22
  export * from './strokePath';
21
23
  export * from './tessellatePath';
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,QAAQ,CAAC;AACvB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iCAAiC,CAAC;AAChD,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Path, PathMorphCreationExplanation } from '@flighthq/types/contract';
2
+ export type { PathMorphCreationExplanation, PathMorphCreationReason } from '@flighthq/types/contract';
3
+ export declare function explainPathMorphCreation(start: Readonly<Path>, end: Readonly<Path>): PathMorphCreationExplanation;
4
+ //# sourceMappingURL=explainPathMorphCreation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainPathMorphCreation.d.ts","sourceRoot":"","sources":["../src/explainPathMorphCreation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,4BAA4B,EAA2B,MAAM,0BAA0B,CAAC;AAE5G,YAAY,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AActG,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,4BAA4B,CAOjH"}
@@ -0,0 +1,24 @@
1
+ import { buildPathMorph, PathMorphIssueContourClosednessMismatch, PathMorphIssueContourCountMismatch, PathMorphIssueContourOrientationMismatch, PathMorphIssueNone, PathMorphIssueWindingMismatch, } from './pathMorphGeometry';
2
+ // Pure diagnostic twin of createPathMorph. Re-runs preparation, retains and mutates nothing, and
3
+ // returns detached data explaining whether the two paths have compatible morph topology. Kept in its
4
+ // own module so users importing only the morph constructor do not ship diagnostic reason strings.
5
+ export function explainPathMorphCreation(start, end) {
6
+ const result = buildPathMorph(start, end);
7
+ return {
8
+ contour: result.contour,
9
+ reason: getReason(result.issue),
10
+ supported: result.issue === PathMorphIssueNone,
11
+ };
12
+ }
13
+ function getReason(issue) {
14
+ if (issue === PathMorphIssueWindingMismatch)
15
+ return 'winding-mismatch';
16
+ if (issue === PathMorphIssueContourCountMismatch)
17
+ return 'contour-count-mismatch';
18
+ if (issue === PathMorphIssueContourClosednessMismatch)
19
+ return 'contour-closedness-mismatch';
20
+ if (issue === PathMorphIssueContourOrientationMismatch)
21
+ return 'contour-orientation-mismatch';
22
+ return 'ok';
23
+ }
24
+ //# sourceMappingURL=explainPathMorphCreation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explainPathMorphCreation.js","sourceRoot":"","sources":["../src/explainPathMorphCreation.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,cAAc,EACd,uCAAuC,EACvC,kCAAkC,EAClC,wCAAwC,EACxC,kBAAkB,EAClB,6BAA6B,GAC9B,MAAM,qBAAqB,CAAC;AAE7B,iGAAiG;AACjG,qGAAqG;AACrG,kGAAkG;AAClG,MAAM,UAAU,wBAAwB,CAAC,KAAqB,EAAE,GAAmB;IACjF,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC1C,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC,KAAK,KAAK,kBAAkB;KAC/C,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,KAAK,KAAK,6BAA6B;QAAE,OAAO,kBAAkB,CAAC;IACvE,IAAI,KAAK,KAAK,kCAAkC;QAAE,OAAO,wBAAwB,CAAC;IAClF,IAAI,KAAK,KAAK,uCAAuC;QAAE,OAAO,6BAA6B,CAAC;IAC5F,IAAI,KAAK,KAAK,wCAAwC;QAAE,OAAO,8BAA8B,CAAC;IAC9F,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { StrokeStyle, acquirePathMesh, acquirePathMeshTyped, appendPathArc, appendPathArcTo, appendPathCircle, appendPathClose, appendPathCubicCurveTo, appendPathCurveTo, appendPathEllipse, appendPathLineTo, appendPathMoveTo, appendPathPolygon, appendPathPolyline, appendPathRectangle, appendPathRoundRectangle, cleanPath, clonePath, containsPathPoint, copyPath, createPath, dashPath, decimatePath, explainStrokePathTessellation, fitPathCurves, flattenPath, forEachPathSegment, getCubicBezierPoint, getCubicBezierTangent, getPathBounds, getPathContourLengths, getPathContourOrientation, getPathLastPoint, getPathLength, getPathNearestPoint, getPathPointAtDistance, getPathPositionAtDistance, getPathSegmentPointAtParameter, getPathSegmentTangentAtParameter, getPathSignedArea, getPathTangentAtDistance, getQuadraticBezierPoint, getQuadraticBezierTangent, releasePathMesh, releasePathMeshTyped, reversePath, strokePath, tessellatePath, tessellatePathTyped, tessellateStrokePath, transformPath, translatePath, } from './contract';
2
- export type { StrokePathTessellationExplanation, StrokePathTessellationReason } from './contract';
1
+ export { StrokeStyle, acquirePathMesh, acquirePathMeshTyped, appendPathArc, appendPathArcTo, appendPathCircle, appendPathClose, appendPathCubicCurveTo, appendPathCurveTo, appendPathEllipse, appendPathLineTo, appendPathMoveTo, appendPathPolygon, appendPathPolyline, appendPathRectangle, appendPathRoundRectangle, cleanPath, clonePath, containsPathPoint, copyPath, createPath, createPathMorph, dashPath, decimatePath, explainPathMorphCreation, explainStrokePathTessellation, fitPathCurves, flattenPath, forEachPathSegment, getCubicBezierPoint, getCubicBezierTangent, getPathBounds, getPathContourLengths, getPathContourOrientation, getPathLastPoint, getPathLength, getPathNearestPoint, getPathPointAtDistance, getPathPositionAtDistance, getPathSegmentPointAtParameter, getPathSegmentTangentAtParameter, getPathSignedArea, getPathTangentAtDistance, getQuadraticBezierPoint, getQuadraticBezierTangent, releasePathMesh, releasePathMeshTyped, reversePath, samplePathMorph, strokePath, tessellatePath, tessellatePathTyped, tessellateStrokePath, transformPath, translatePath, } from './contract';
2
+ export type { PathMorph, PathMorphCreationExplanation, PathMorphCreationReason, StrokePathTessellationExplanation, StrokePathTessellationReason, } from './contract';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,8BAA8B,EAC9B,gCAAgC,EAChC,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,iCAAiC,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,wBAAwB,EACxB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,8BAA8B,EAC9B,gCAAgC,EAChC,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,SAAS,EACT,4BAA4B,EAC5B,uBAAuB,EACvB,iCAAiC,EACjC,4BAA4B,GAC7B,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { acquirePathMesh, acquirePathMeshTyped, appendPathArc, appendPathArcTo, appendPathCircle, appendPathClose, appendPathCubicCurveTo, appendPathCurveTo, appendPathEllipse, appendPathLineTo, appendPathMoveTo, appendPathPolygon, appendPathPolyline, appendPathRectangle, appendPathRoundRectangle, cleanPath, clonePath, containsPathPoint, copyPath, createPath, dashPath, decimatePath, explainStrokePathTessellation, fitPathCurves, flattenPath, forEachPathSegment, getCubicBezierPoint, getCubicBezierTangent, getPathBounds, getPathContourLengths, getPathContourOrientation, getPathLastPoint, getPathLength, getPathNearestPoint, getPathPointAtDistance, getPathPositionAtDistance, getPathSegmentPointAtParameter, getPathSegmentTangentAtParameter, getPathSignedArea, getPathTangentAtDistance, getQuadraticBezierPoint, getQuadraticBezierTangent, releasePathMesh, releasePathMeshTyped, reversePath, strokePath, tessellatePath, tessellatePathTyped, tessellateStrokePath, transformPath, translatePath, } from './contract';
1
+ export { acquirePathMesh, acquirePathMeshTyped, appendPathArc, appendPathArcTo, appendPathCircle, appendPathClose, appendPathCubicCurveTo, appendPathCurveTo, appendPathEllipse, appendPathLineTo, appendPathMoveTo, appendPathPolygon, appendPathPolyline, appendPathRectangle, appendPathRoundRectangle, cleanPath, clonePath, containsPathPoint, copyPath, createPath, createPathMorph, dashPath, decimatePath, explainPathMorphCreation, explainStrokePathTessellation, fitPathCurves, flattenPath, forEachPathSegment, getCubicBezierPoint, getCubicBezierTangent, getPathBounds, getPathContourLengths, getPathContourOrientation, getPathLastPoint, getPathLength, getPathNearestPoint, getPathPointAtDistance, getPathPositionAtDistance, getPathSegmentPointAtParameter, getPathSegmentTangentAtParameter, getPathSignedArea, getPathTangentAtDistance, getQuadraticBezierPoint, getQuadraticBezierTangent, releasePathMesh, releasePathMeshTyped, reversePath, samplePathMorph, strokePath, tessellatePath, tessellatePathTyped, tessellateStrokePath, transformPath, translatePath, } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,8BAA8B,EAC9B,gCAAgC,EAChC,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,wBAAwB,EACxB,6BAA6B,EAC7B,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,aAAa,EACb,qBAAqB,EACrB,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,8BAA8B,EAC9B,gCAAgC,EAChC,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Path, PathMorph } from '@flighthq/types/contract';
2
+ export type { PathMorph } from '@flighthq/types/contract';
3
+ export declare function createPathMorph(start: Readonly<Path>, end: Readonly<Path>): PathMorph | null;
4
+ export declare function samplePathMorph(out: Path, morph: Readonly<PathMorph>, progress: number): void;
5
+ //# sourceMappingURL=pathMorph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathMorph.d.ts","sourceRoot":"","sources":["../src/pathMorph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAEhE,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAS1D,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAE5F;AAKD,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAoB7F"}
@@ -0,0 +1,35 @@
1
+ import { buildPathMorph } from './pathMorphGeometry';
2
+ // Allocates a prepared interpolation between two paths. The paths may use different line, quadratic,
3
+ // and cubic verbs and may contain different segment counts; preparation converts them to exact cubic
4
+ // equivalents and subdivides the smaller side. Corresponding contours must have the same ordering,
5
+ // winding, count, and open/closed topology. Closed traversal direction is normalized when doing so
6
+ // preserves the fill; returns null when a non-zero path reverses only a subset of its contours.
7
+ export function createPathMorph(start, end) {
8
+ return buildPathMorph(start, end).morph;
9
+ }
10
+ // Samples a prepared morph into `out`. Reuses the existing command and coordinate arrays, making
11
+ // repeated calls allocation-free once they have sufficient capacity. Progress is not clamped: 0 and
12
+ // 1 are the endpoints, while values outside that range permit deliberate easing overshoot.
13
+ export function samplePathMorph(out, morph, progress) {
14
+ const commands = morph.commands;
15
+ out.commands.length = commands.length;
16
+ for (let i = 0; i < commands.length; i++)
17
+ out.commands[i] = commands[i];
18
+ const startData = morph.startData;
19
+ const endData = morph.endData;
20
+ out.data.length = startData.length;
21
+ if (progress === 0 || progress === 1) {
22
+ const endpoint = progress === 0 ? startData : endData;
23
+ for (let i = 0; i < endpoint.length; i++)
24
+ out.data[i] = endpoint[i];
25
+ out.winding = morph.winding;
26
+ return;
27
+ }
28
+ for (let i = 0; i < startData.length; i++) {
29
+ const start = startData[i];
30
+ const end = endData[i];
31
+ out.data[i] = start + (end - start) * progress;
32
+ }
33
+ out.winding = morph.winding;
34
+ }
35
+ //# sourceMappingURL=pathMorph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathMorph.js","sourceRoot":"","sources":["../src/pathMorph.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,qGAAqG;AACrG,qGAAqG;AACrG,mGAAmG;AACnG,mGAAmG;AACnG,gGAAgG;AAChG,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,GAAmB;IACxE,OAAO,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC;AAED,iGAAiG;AACjG,oGAAoG;AACpG,2FAA2F;AAC3F,MAAM,UAAU,eAAe,CAAC,GAAS,EAAE,KAA0B,EAAE,QAAgB;IACrF,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAExE,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IACnC,IAAI,QAAQ,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,QAAQ,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;QACtD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACpE,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC5B,OAAO;IACT,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,QAAQ,CAAC;IACjD,CAAC;IACD,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Path, PathMorph } from '@flighthq/types/contract';
2
+ export declare const PathMorphIssueNone = 0;
3
+ export declare const PathMorphIssueWindingMismatch = 1;
4
+ export declare const PathMorphIssueContourCountMismatch = 2;
5
+ export declare const PathMorphIssueContourClosednessMismatch = 3;
6
+ export declare const PathMorphIssueContourOrientationMismatch = 4;
7
+ interface PathMorphBuildResult {
8
+ contour: number | null;
9
+ issue: number;
10
+ morph: PathMorph | null;
11
+ }
12
+ export declare function buildPathMorph(start: Readonly<Path>, end: Readonly<Path>): PathMorphBuildResult;
13
+ export {};
14
+ //# sourceMappingURL=pathMorphGeometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathMorphGeometry.d.ts","sourceRoot":"","sources":["../src/pathMorphGeometry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAKhE,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,kCAAkC,IAAI,CAAC;AACpD,eAAO,MAAM,uCAAuC,IAAI,CAAC;AACzD,eAAO,MAAM,wCAAwC,IAAI,CAAC;AAE1D,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;CACzB;AAMD,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAwC/F"}
@@ -0,0 +1,347 @@
1
+ import { PathCommand } from '@flighthq/types/contract';
2
+ import { forEachPathSegment } from './forEachPathSegment';
3
+ export const PathMorphIssueNone = 0;
4
+ export const PathMorphIssueWindingMismatch = 1;
5
+ export const PathMorphIssueContourCountMismatch = 2;
6
+ export const PathMorphIssueContourClosednessMismatch = 3;
7
+ export const PathMorphIssueContourOrientationMismatch = 4;
8
+ // Shared preparation used by the production constructor and its separately importable diagnostic.
9
+ // Lines and quadratics are converted exactly to cubics, then the lower-segment endpoint is subdivided
10
+ // without changing its geometry. This is deliberately a one-time allocating step; sampling stays a
11
+ // flat coordinate loop.
12
+ export function buildPathMorph(start, end) {
13
+ if (start.winding !== end.winding) {
14
+ return { contour: null, issue: PathMorphIssueWindingMismatch, morph: null };
15
+ }
16
+ const startContours = decodeCubicContours(start);
17
+ const endContours = decodeCubicContours(end);
18
+ if (startContours.length !== endContours.length) {
19
+ return { contour: null, issue: PathMorphIssueContourCountMismatch, morph: null };
20
+ }
21
+ for (let i = 0; i < startContours.length; i++) {
22
+ if (startContours[i].closed !== endContours[i].closed) {
23
+ return { contour: i, issue: PathMorphIssueContourClosednessMismatch, morph: null };
24
+ }
25
+ }
26
+ const orientationMismatch = normalizeCubicContourOrientations(startContours, endContours, start.winding);
27
+ if (orientationMismatch !== null) {
28
+ return { contour: orientationMismatch, issue: PathMorphIssueContourOrientationMismatch, morph: null };
29
+ }
30
+ for (let i = 0; i < startContours.length; i++) {
31
+ const startContour = startContours[i];
32
+ const endContour = endContours[i];
33
+ equalizeCubicContourSegments(startContour, endContour);
34
+ alignClosedCubicContour(startContour, endContour);
35
+ }
36
+ const commands = [];
37
+ const startData = [];
38
+ const endData = [];
39
+ for (let i = 0; i < startContours.length; i++) {
40
+ appendCubicContourPair(commands, startData, endData, startContours[i], endContours[i]);
41
+ }
42
+ return {
43
+ contour: null,
44
+ issue: PathMorphIssueNone,
45
+ morph: { commands, endData, startData, winding: start.winding },
46
+ };
47
+ }
48
+ // Opposite traversal makes equally-authored closed shapes fold through themselves during coordinate
49
+ // interpolation. Even-odd paths may reverse each contour independently because direction has no fill
50
+ // meaning. Non-zero paths may only reverse the entire endpoint consistently: that negates every
51
+ // winding number without changing what is filled, while reversing a subset could turn a hole into a
52
+ // solid ring. Returns the first contour whose relationship prevents that safe normalization.
53
+ function normalizeCubicContourOrientations(start, end, winding) {
54
+ if (winding === 'evenOdd') {
55
+ for (let i = 0; i < start.length; i++) {
56
+ const startOrientation = getCubicContourOrientation(start[i]);
57
+ const endOrientation = getCubicContourOrientation(end[i]);
58
+ if (startOrientation !== 0 && endOrientation !== 0 && startOrientation !== endOrientation) {
59
+ reverseClosedCubicContour(end[i]);
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ let reverseEnd = null;
65
+ for (let i = 0; i < start.length; i++) {
66
+ const startOrientation = getCubicContourOrientation(start[i]);
67
+ const endOrientation = getCubicContourOrientation(end[i]);
68
+ if (startOrientation === 0 || endOrientation === 0)
69
+ continue;
70
+ const reversed = startOrientation !== endOrientation;
71
+ if (reverseEnd === null)
72
+ reverseEnd = reversed;
73
+ else if (reverseEnd !== reversed)
74
+ return i;
75
+ }
76
+ if (reverseEnd === true) {
77
+ for (let i = 0; i < end.length; i++) {
78
+ if (getCubicContourOrientation(end[i]) !== 0)
79
+ reverseClosedCubicContour(end[i]);
80
+ }
81
+ }
82
+ return null;
83
+ }
84
+ function getCubicContourOrientation(contour) {
85
+ if (!contour.closed)
86
+ return 0;
87
+ const area = getCubicContourSignedArea(contour);
88
+ return area < 0 ? -1 : area > 0 ? 1 : 0;
89
+ }
90
+ function reverseClosedCubicContour(contour) {
91
+ const reversed = [];
92
+ for (let i = contour.segments.length - 1; i >= 0; i--) {
93
+ const segment = contour.segments[i];
94
+ reversed.push({
95
+ control1X: segment.control2X,
96
+ control1Y: segment.control2Y,
97
+ control2X: segment.control1X,
98
+ control2Y: segment.control1Y,
99
+ x0: segment.x1,
100
+ x1: segment.x0,
101
+ y0: segment.y1,
102
+ y1: segment.y0,
103
+ });
104
+ }
105
+ contour.segments = reversed;
106
+ if (reversed.length > 0) {
107
+ contour.x = reversed[0].x0;
108
+ contour.y = reversed[0].y0;
109
+ }
110
+ contour.currentX = contour.x;
111
+ contour.currentY = contour.y;
112
+ }
113
+ // Exact Green's-theorem area integral over cubic power-basis coefficients. This avoids introducing a
114
+ // flattening tolerance into morph compatibility and handles curved contours as deterministically as
115
+ // polygonal ones.
116
+ function getCubicContourSignedArea(contour) {
117
+ let twiceArea = 0;
118
+ let extent = 0;
119
+ for (let i = 0; i < contour.segments.length; i++) {
120
+ const segment = contour.segments[i];
121
+ const x0 = segment.x0 - contour.x;
122
+ const control1X = segment.control1X - contour.x;
123
+ const control2X = segment.control2X - contour.x;
124
+ const x1 = segment.x1 - contour.x;
125
+ const y0 = segment.y0 - contour.y;
126
+ const control1Y = segment.control1Y - contour.y;
127
+ const control2Y = segment.control2Y - contour.y;
128
+ const y1 = segment.y1 - contour.y;
129
+ extent = Math.max(extent, Math.abs(x0), Math.abs(control1X), Math.abs(control2X), Math.abs(x1), Math.abs(y0), Math.abs(control1Y), Math.abs(control2Y), Math.abs(y1));
130
+ const x = getCubicPowerCoefficients(x0, control1X, control2X, x1);
131
+ const y = getCubicPowerCoefficients(y0, control1Y, control2Y, y1);
132
+ for (let xi = 0; xi < 4; xi++) {
133
+ for (let yi = 1; yi < 4; yi++) {
134
+ twiceArea += (x[xi] * yi * y[yi] - y[xi] * yi * x[yi]) / (xi + yi);
135
+ }
136
+ }
137
+ }
138
+ const area = twiceArea / 2;
139
+ const areaEpsilon = Math.max(1, extent * extent) * Number.EPSILON * 64;
140
+ return Math.abs(area) <= areaEpsilon ? 0 : area;
141
+ }
142
+ function getCubicPowerCoefficients(p0, p1, p2, p3) {
143
+ return [p0, 3 * (p1 - p0), 3 * (p0 - 2 * p1 + p2), -p0 + 3 * p1 - 3 * p2 + p3];
144
+ }
145
+ function alignClosedCubicContour(start, end) {
146
+ const count = start.segments.length;
147
+ if (!start.closed || count < 2)
148
+ return;
149
+ let bestOffset = 0;
150
+ let bestDistance = Infinity;
151
+ for (let offset = 0; offset < count; offset++) {
152
+ let distance = 0;
153
+ for (let i = 0; i < count; i++) {
154
+ const a = start.segments[i];
155
+ const b = end.segments[(i + offset) % count];
156
+ const dx = a.x0 - b.x0;
157
+ const dy = a.y0 - b.y0;
158
+ distance += dx * dx + dy * dy;
159
+ }
160
+ if (distance < bestDistance) {
161
+ bestDistance = distance;
162
+ bestOffset = offset;
163
+ }
164
+ }
165
+ if (bestOffset === 0)
166
+ return;
167
+ end.segments = end.segments.slice(bestOffset).concat(end.segments.slice(0, bestOffset));
168
+ end.x = end.segments[0].x0;
169
+ end.y = end.segments[0].y0;
170
+ }
171
+ function appendCubicContourPair(commands, startData, endData, start, end) {
172
+ commands.push(PathCommand.MOVE_TO);
173
+ startData.push(start.x, start.y);
174
+ endData.push(end.x, end.y);
175
+ for (let i = 0; i < start.segments.length; i++) {
176
+ const a = start.segments[i];
177
+ const b = end.segments[i];
178
+ commands.push(PathCommand.CUBIC_CURVE_TO);
179
+ startData.push(a.control1X, a.control1Y, a.control2X, a.control2Y, a.x1, a.y1);
180
+ endData.push(b.control1X, b.control1Y, b.control2X, b.control2Y, b.x1, b.y1);
181
+ }
182
+ if (start.closed)
183
+ commands.push(PathCommand.CLOSE);
184
+ }
185
+ function appendCubicSegment(contour, control1X, control1Y, control2X, control2Y, x, y) {
186
+ contour.segments.push({
187
+ control1X,
188
+ control1Y,
189
+ control2X,
190
+ control2Y,
191
+ x0: contour.currentX,
192
+ x1: x,
193
+ y0: contour.currentY,
194
+ y1: y,
195
+ });
196
+ contour.currentX = x;
197
+ contour.currentY = y;
198
+ }
199
+ function appendLineAsCubic(contour, x, y) {
200
+ const x0 = contour.currentX;
201
+ const y0 = contour.currentY;
202
+ appendCubicSegment(contour, x0 + (x - x0) / 3, y0 + (y - y0) / 3, x0 + ((x - x0) * 2) / 3, y0 + ((y - y0) * 2) / 3, x, y);
203
+ }
204
+ function appendQuadraticAsCubic(contour, controlX, controlY, x, y) {
205
+ const x0 = contour.currentX;
206
+ const y0 = contour.currentY;
207
+ appendCubicSegment(contour, x0 + ((controlX - x0) * 2) / 3, y0 + ((controlY - y0) * 2) / 3, x + ((controlX - x) * 2) / 3, y + ((controlY - y) * 2) / 3, x, y);
208
+ }
209
+ function closeCubicContour(contour) {
210
+ if (contour.currentX !== contour.x || contour.currentY !== contour.y) {
211
+ appendLineAsCubic(contour, contour.x, contour.y);
212
+ }
213
+ contour.closed = true;
214
+ }
215
+ function createCubicContour(x, y) {
216
+ return { closed: false, currentX: x, currentY: y, segments: [], x, y };
217
+ }
218
+ function cubicControlPolygonLength(segment) {
219
+ return (pointDistance(segment.x0, segment.y0, segment.control1X, segment.control1Y) +
220
+ pointDistance(segment.control1X, segment.control1Y, segment.control2X, segment.control2Y) +
221
+ pointDistance(segment.control2X, segment.control2Y, segment.x1, segment.y1));
222
+ }
223
+ function decodeCubicContours(path) {
224
+ const contours = [];
225
+ let contour = null;
226
+ const ensureContour = () => {
227
+ if (contour !== null)
228
+ return contour;
229
+ contour = createCubicContour(0, 0);
230
+ contours.push(contour);
231
+ return contour;
232
+ };
233
+ forEachPathSegment(path, (segment) => {
234
+ if (segment.kind === 'moveTo') {
235
+ contour = createCubicContour(segment.x, segment.y);
236
+ contours.push(contour);
237
+ }
238
+ else if (segment.kind === 'lineTo') {
239
+ appendLineAsCubic(ensureContour(), segment.x, segment.y);
240
+ }
241
+ else if (segment.kind === 'curveTo') {
242
+ appendQuadraticAsCubic(ensureContour(), segment.controlX, segment.controlY, segment.x, segment.y);
243
+ }
244
+ else if (segment.kind === 'cubicCurveTo') {
245
+ appendCubicSegment(ensureContour(), segment.control1X, segment.control1Y, segment.control2X, segment.control2Y, segment.x, segment.y);
246
+ }
247
+ else if (segment.kind === 'close' && contour !== null) {
248
+ closeCubicContour(contour);
249
+ contour = null;
250
+ }
251
+ });
252
+ return contours;
253
+ }
254
+ function equalizeCubicContourSegments(start, end) {
255
+ const targetCount = Math.max(start.segments.length, end.segments.length);
256
+ if (targetCount === 0)
257
+ return;
258
+ start.segments = subdivideCubicSegments(start.segments, targetCount, start.x, start.y);
259
+ end.segments = subdivideCubicSegments(end.segments, targetCount, end.x, end.y);
260
+ }
261
+ function pointDistance(x0, y0, x1, y1) {
262
+ const dx = x1 - x0;
263
+ const dy = y1 - y0;
264
+ return Math.sqrt(dx * dx + dy * dy);
265
+ }
266
+ function splitCubicSegment(segment, t) {
267
+ const x01 = segment.x0 + (segment.control1X - segment.x0) * t;
268
+ const y01 = segment.y0 + (segment.control1Y - segment.y0) * t;
269
+ const x12 = segment.control1X + (segment.control2X - segment.control1X) * t;
270
+ const y12 = segment.control1Y + (segment.control2Y - segment.control1Y) * t;
271
+ const x23 = segment.control2X + (segment.x1 - segment.control2X) * t;
272
+ const y23 = segment.control2Y + (segment.y1 - segment.control2Y) * t;
273
+ const x012 = x01 + (x12 - x01) * t;
274
+ const y012 = y01 + (y12 - y01) * t;
275
+ const x123 = x12 + (x23 - x12) * t;
276
+ const y123 = y12 + (y23 - y12) * t;
277
+ const x = x012 + (x123 - x012) * t;
278
+ const y = y012 + (y123 - y012) * t;
279
+ return [
280
+ {
281
+ control1X: x01,
282
+ control1Y: y01,
283
+ control2X: x012,
284
+ control2Y: y012,
285
+ x0: segment.x0,
286
+ x1: x,
287
+ y0: segment.y0,
288
+ y1: y,
289
+ },
290
+ {
291
+ control1X: x123,
292
+ control1Y: y123,
293
+ control2X: x23,
294
+ control2Y: y23,
295
+ x0: x,
296
+ x1: segment.x1,
297
+ y0: y,
298
+ y1: segment.y1,
299
+ },
300
+ ];
301
+ }
302
+ function subdivideCubicSegments(source, targetCount, pointX, pointY) {
303
+ if (source.length === targetCount)
304
+ return source.slice();
305
+ if (source.length === 0) {
306
+ const segments = [];
307
+ for (let i = 0; i < targetCount; i++) {
308
+ segments.push({
309
+ control1X: pointX,
310
+ control1Y: pointY,
311
+ control2X: pointX,
312
+ control2Y: pointY,
313
+ x0: pointX,
314
+ x1: pointX,
315
+ y0: pointY,
316
+ y1: pointY,
317
+ });
318
+ }
319
+ return segments;
320
+ }
321
+ const partCounts = new Array(source.length).fill(1);
322
+ const lengths = source.map(cubicControlPolygonLength);
323
+ for (let total = source.length; total < targetCount; total++) {
324
+ let best = 0;
325
+ let bestLength = -1;
326
+ for (let i = 0; i < source.length; i++) {
327
+ const partLength = lengths[i] / partCounts[i];
328
+ if (partLength > bestLength) {
329
+ best = i;
330
+ bestLength = partLength;
331
+ }
332
+ }
333
+ partCounts[best]++;
334
+ }
335
+ const segments = [];
336
+ for (let i = 0; i < source.length; i++) {
337
+ let remainder = source[i];
338
+ for (let parts = partCounts[i]; parts > 1; parts--) {
339
+ const split = splitCubicSegment(remainder, 1 / parts);
340
+ segments.push(split[0]);
341
+ remainder = split[1];
342
+ }
343
+ segments.push(remainder);
344
+ }
345
+ return segments;
346
+ }
347
+ //# sourceMappingURL=pathMorphGeometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathMorphGeometry.js","sourceRoot":"","sources":["../src/pathMorphGeometry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/path",
3
- "version": "0.3.0-next.1566.dcdf1d3",
3
+ "version": "0.3.0-next.1584.a68fe91",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -36,7 +36,7 @@
36
36
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@flighthq/types": "0.3.0-next.1566.dcdf1d3"
39
+ "@flighthq/types": "0.3.0-next.1584.a68fe91"
40
40
  },
41
41
  "devDependencies": {
42
42
  "typescript": "^5.3.0"
@@ -0,0 +1,81 @@
1
+ import { explainPathMorphCreation } from './explainPathMorphCreation';
2
+ import { appendPathClose, appendPathLineTo, appendPathMoveTo, createPath } from './path';
3
+
4
+ describe('explainPathMorphCreation', () => {
5
+ it('reports a compatible pair', () => {
6
+ expect(explainPathMorphCreation(createPath(), createPath())).toStrictEqual({
7
+ contour: null,
8
+ reason: 'ok',
9
+ supported: true,
10
+ });
11
+ });
12
+
13
+ it('reports a winding mismatch', () => {
14
+ expect(explainPathMorphCreation(createPath('nonZero'), createPath('evenOdd'))).toStrictEqual({
15
+ contour: null,
16
+ reason: 'winding-mismatch',
17
+ supported: false,
18
+ });
19
+ });
20
+
21
+ it('reports a contour-count mismatch', () => {
22
+ const start = createPath();
23
+ appendPathMoveTo(start, 0, 0);
24
+ expect(explainPathMorphCreation(start, createPath())).toStrictEqual({
25
+ contour: null,
26
+ reason: 'contour-count-mismatch',
27
+ supported: false,
28
+ });
29
+ });
30
+
31
+ it('reports the first contour with different closedness', () => {
32
+ const start = createPath();
33
+ appendPathMoveTo(start, 0, 0);
34
+ appendPathLineTo(start, 1, 0);
35
+ appendPathMoveTo(start, 10, 10);
36
+ appendPathLineTo(start, 11, 10);
37
+ appendPathClose(start);
38
+ const end = createPath();
39
+ appendPathMoveTo(end, 0, 0);
40
+ appendPathLineTo(end, 1, 0);
41
+ appendPathMoveTo(end, 10, 10);
42
+ appendPathLineTo(end, 11, 10);
43
+
44
+ expect(explainPathMorphCreation(start, end)).toStrictEqual({
45
+ contour: 1,
46
+ reason: 'contour-closedness-mismatch',
47
+ supported: false,
48
+ });
49
+ });
50
+
51
+ it('reports a non-zero path that reverses only a subset of its contours', () => {
52
+ const start = createPath();
53
+ appendPathMoveTo(start, 0, 0);
54
+ appendPathLineTo(start, 20, 0);
55
+ appendPathLineTo(start, 20, 20);
56
+ appendPathLineTo(start, 0, 20);
57
+ appendPathClose(start);
58
+ appendPathMoveTo(start, 5, 5);
59
+ appendPathLineTo(start, 15, 5);
60
+ appendPathLineTo(start, 15, 15);
61
+ appendPathLineTo(start, 5, 15);
62
+ appendPathClose(start);
63
+ const end = createPath();
64
+ appendPathMoveTo(end, 0, 0);
65
+ appendPathLineTo(end, 20, 0);
66
+ appendPathLineTo(end, 20, 20);
67
+ appendPathLineTo(end, 0, 20);
68
+ appendPathClose(end);
69
+ appendPathMoveTo(end, 5, 5);
70
+ appendPathLineTo(end, 5, 15);
71
+ appendPathLineTo(end, 15, 15);
72
+ appendPathLineTo(end, 15, 5);
73
+ appendPathClose(end);
74
+
75
+ expect(explainPathMorphCreation(start, end)).toStrictEqual({
76
+ contour: 1,
77
+ reason: 'contour-orientation-mismatch',
78
+ supported: false,
79
+ });
80
+ });
81
+ });
@@ -0,0 +1,290 @@
1
+ import { PathCommand } from '@flighthq/types/contract';
2
+
3
+ import {
4
+ appendPathClose,
5
+ appendPathCircle,
6
+ appendPathCubicCurveTo,
7
+ appendPathCurveTo,
8
+ appendPathLineTo,
9
+ appendPathMoveTo,
10
+ appendPathRectangle,
11
+ createPath,
12
+ } from './path';
13
+ import { createPathMorph, samplePathMorph } from './pathMorph';
14
+
15
+ describe('createPathMorph', () => {
16
+ it('normalizes different line and quadratic verbs to one cubic command stream', () => {
17
+ const start = createPath();
18
+ appendPathMoveTo(start, 0, 0);
19
+ appendPathLineTo(start, 6, 0);
20
+ const end = createPath();
21
+ appendPathMoveTo(end, 2, 2);
22
+ appendPathCurveTo(end, 5, 8, 8, 2);
23
+
24
+ const morph = createPathMorph(start, end)!;
25
+
26
+ expect(morph.commands).toStrictEqual([PathCommand.MOVE_TO, PathCommand.CUBIC_CURVE_TO]);
27
+ expect(morph.startData).toStrictEqual([0, 0, 2, 0, 4, 0, 6, 0]);
28
+ expect(morph.endData).toStrictEqual([2, 2, 4, 6, 6, 6, 8, 2]);
29
+ });
30
+
31
+ it('preserves authored cubic control points', () => {
32
+ const start = createPath();
33
+ appendPathMoveTo(start, 0, 0);
34
+ appendPathLineTo(start, 9, 0);
35
+ const end = createPath();
36
+ appendPathMoveTo(end, 1, 2);
37
+ appendPathCubicCurveTo(end, 3, 4, 6, 8, 10, 12);
38
+
39
+ const morph = createPathMorph(start, end)!;
40
+
41
+ expect(morph.endData).toStrictEqual([1, 2, 3, 4, 6, 8, 10, 12]);
42
+ });
43
+
44
+ it('subdivides the lower segment count without changing its endpoint geometry', () => {
45
+ const start = createPath();
46
+ appendPathMoveTo(start, 0, 0);
47
+ appendPathLineTo(start, 10, 0);
48
+ const end = createPath();
49
+ appendPathMoveTo(end, 0, 0);
50
+ appendPathLineTo(end, 5, 0);
51
+ appendPathLineTo(end, 10, 0);
52
+
53
+ const morph = createPathMorph(start, end)!;
54
+
55
+ expect(morph.commands).toStrictEqual([PathCommand.MOVE_TO, PathCommand.CUBIC_CURVE_TO, PathCommand.CUBIC_CURVE_TO]);
56
+ for (let i = 0; i < morph.startData.length; i++) {
57
+ expect(morph.startData[i]).toBeCloseTo(morph.endData[i]);
58
+ }
59
+ expect(morph.startData.slice(-2)).toStrictEqual([10, 0]);
60
+ });
61
+
62
+ it('aligns equivalent closed contours authored from different starting vertices', () => {
63
+ const start = createPath();
64
+ appendPathRectangle(start, 0, 0, 10, 10);
65
+ const end = createPath();
66
+ appendPathMoveTo(end, 10, 0);
67
+ appendPathLineTo(end, 10, 10);
68
+ appendPathLineTo(end, 0, 10);
69
+ appendPathLineTo(end, 0, 0);
70
+ appendPathClose(end);
71
+
72
+ const morph = createPathMorph(start, end)!;
73
+
74
+ expect(morph.startData).toEqual(morph.endData);
75
+ expect(morph.commands[morph.commands.length - 1]).toBe(PathCommand.CLOSE);
76
+ });
77
+
78
+ it('prepares a closed line rectangle against a closed cubic circle', () => {
79
+ const start = createPath();
80
+ appendPathRectangle(start, -10, -10, 20, 20);
81
+ const end = createPath();
82
+ appendPathCircle(end, 0, 0, 10);
83
+
84
+ const morph = createPathMorph(start, end)!;
85
+
86
+ expect(morph.commands).toStrictEqual([
87
+ PathCommand.MOVE_TO,
88
+ PathCommand.CUBIC_CURVE_TO,
89
+ PathCommand.CUBIC_CURVE_TO,
90
+ PathCommand.CUBIC_CURVE_TO,
91
+ PathCommand.CUBIC_CURVE_TO,
92
+ PathCommand.CLOSE,
93
+ ]);
94
+ });
95
+
96
+ it('normalizes wide move and line commands without retaining their dummy coordinates', () => {
97
+ const start = createPath();
98
+ start.commands.push(PathCommand.WIDE_MOVE_TO, PathCommand.WIDE_LINE_TO);
99
+ start.data.push(99, 98, 1, 2, 97, 96, 7, 8);
100
+ const end = createPath();
101
+ appendPathMoveTo(end, 1, 2);
102
+ appendPathLineTo(end, 7, 8);
103
+
104
+ const morph = createPathMorph(start, end)!;
105
+
106
+ expect(morph.startData).toEqual(morph.endData);
107
+ expect(morph.startData).toStrictEqual([1, 2, 3, 4, 5, 6, 7, 8]);
108
+ });
109
+
110
+ it('expands a point contour into degenerate cubics when the other endpoint has segments', () => {
111
+ const start = createPath();
112
+ appendPathMoveTo(start, 3, 4);
113
+ const end = createPath();
114
+ appendPathMoveTo(end, 0, 0);
115
+ appendPathLineTo(end, 10, 0);
116
+
117
+ const morph = createPathMorph(start, end)!;
118
+
119
+ expect(morph.startData).toStrictEqual([3, 4, 3, 4, 3, 4, 3, 4]);
120
+ });
121
+
122
+ it('expands a closed point contour without inventing an orientation', () => {
123
+ const start = createPath();
124
+ appendPathMoveTo(start, 3, 4);
125
+ appendPathClose(start);
126
+ const end = createPath();
127
+ appendPathRectangle(end, 0, 0, 10, 10);
128
+
129
+ const morph = createPathMorph(start, end)!;
130
+
131
+ expect(morph.commands).toStrictEqual([
132
+ PathCommand.MOVE_TO,
133
+ PathCommand.CUBIC_CURVE_TO,
134
+ PathCommand.CUBIC_CURVE_TO,
135
+ PathCommand.CUBIC_CURVE_TO,
136
+ PathCommand.CUBIC_CURVE_TO,
137
+ PathCommand.CLOSE,
138
+ ]);
139
+ expect(morph.startData.every((value, index) => value === (index % 2 === 0 ? 3 : 4))).toBe(true);
140
+ });
141
+
142
+ it('does not mutate either endpoint', () => {
143
+ const start = createPath();
144
+ appendPathMoveTo(start, 0, 0);
145
+ appendPathLineTo(start, 10, 0);
146
+ const end = createPath();
147
+ appendPathMoveTo(end, 0, 0);
148
+ appendPathLineTo(end, 5, 5);
149
+ appendPathLineTo(end, 10, 0);
150
+ const startCommands = start.commands.slice();
151
+ const startData = start.data.slice();
152
+ const endCommands = end.commands.slice();
153
+ const endData = end.data.slice();
154
+
155
+ createPathMorph(start, end);
156
+
157
+ expect(start.commands).toStrictEqual(startCommands);
158
+ expect(start.data).toStrictEqual(startData);
159
+ expect(end.commands).toStrictEqual(endCommands);
160
+ expect(end.data).toStrictEqual(endData);
161
+ });
162
+
163
+ it('returns null for paths with incompatible topology', () => {
164
+ const start = createPath('nonZero');
165
+ const end = createPath('evenOdd');
166
+ expect(createPathMorph(start, end)).toBeNull();
167
+ });
168
+
169
+ it('normalizes a consistently reversed closed endpoint', () => {
170
+ const start = createPath();
171
+ appendPathRectangle(start, 0, 0, 10, 10);
172
+ const end = createPath();
173
+ appendPathMoveTo(end, 0, 0);
174
+ appendPathLineTo(end, 0, 10);
175
+ appendPathLineTo(end, 10, 10);
176
+ appendPathLineTo(end, 10, 0);
177
+ appendPathClose(end);
178
+
179
+ const morph = createPathMorph(start, end)!;
180
+
181
+ for (let i = 0; i < morph.startData.length; i++) {
182
+ expect(morph.startData[i]).toBeCloseTo(morph.endData[i]);
183
+ }
184
+ });
185
+
186
+ it('normalizes opposing contours independently under even-odd winding', () => {
187
+ const start = createPath('evenOdd');
188
+ appendPathRectangle(start, 0, 0, 20, 20);
189
+ appendPathRectangle(start, 5, 5, 10, 10);
190
+ const end = createPath('evenOdd');
191
+ appendPathRectangle(end, 0, 0, 20, 20);
192
+ appendPathMoveTo(end, 5, 5);
193
+ appendPathLineTo(end, 5, 15);
194
+ appendPathLineTo(end, 15, 15);
195
+ appendPathLineTo(end, 15, 5);
196
+ appendPathClose(end);
197
+
198
+ const morph = createPathMorph(start, end)!;
199
+
200
+ for (let i = 0; i < morph.startData.length; i++) {
201
+ expect(morph.startData[i]).toBeCloseTo(morph.endData[i]);
202
+ }
203
+ });
204
+ });
205
+
206
+ describe('samplePathMorph', () => {
207
+ it('samples the prepared endpoints at zero and one', () => {
208
+ const start = createPath();
209
+ appendPathMoveTo(start, 0, 2);
210
+ appendPathLineTo(start, 6, 8);
211
+ const end = createPath();
212
+ appendPathMoveTo(end, 10, 12);
213
+ appendPathCurveTo(end, 14, 20, 18, 16);
214
+ const morph = createPathMorph(start, end)!;
215
+ const out = createPath();
216
+
217
+ samplePathMorph(out, morph, 0);
218
+ expect(out.data).toStrictEqual(morph.startData);
219
+ samplePathMorph(out, morph, 1);
220
+ expect(out.data).toStrictEqual(morph.endData);
221
+ });
222
+
223
+ it('copies endpoint coordinates exactly instead of reconstructing them arithmetically', () => {
224
+ const start = createPath();
225
+ appendPathMoveTo(start, -255_815_156_688.713_68, 12);
226
+ const end = createPath();
227
+ appendPathMoveTo(end, 0.000_030_389_885_488_608_44, -24);
228
+ const morph = createPathMorph(start, end)!;
229
+ const out = createPath();
230
+
231
+ samplePathMorph(out, morph, 0);
232
+ expect(out.data).toStrictEqual(morph.startData);
233
+ samplePathMorph(out, morph, 1);
234
+ expect(out.data).toStrictEqual(morph.endData);
235
+ });
236
+
237
+ it('writes the midpoint and winding into an existing path', () => {
238
+ const start = createPath('evenOdd');
239
+ appendPathMoveTo(start, 0, 0);
240
+ appendPathLineTo(start, 6, 0);
241
+ const end = createPath('evenOdd');
242
+ appendPathMoveTo(end, 2, 2);
243
+ appendPathCurveTo(end, 5, 8, 8, 2);
244
+ const out = createPath('nonZero');
245
+
246
+ samplePathMorph(out, createPathMorph(start, end)!, 0.5);
247
+
248
+ expect(out.commands).toStrictEqual([PathCommand.MOVE_TO, PathCommand.CUBIC_CURVE_TO]);
249
+ expect(out.data).toStrictEqual([1, 1, 3, 3, 5, 3, 7, 1]);
250
+ expect(out.winding).toBe('evenOdd');
251
+ });
252
+
253
+ it('reuses the output command and data arrays across samples', () => {
254
+ const start = createPath();
255
+ appendPathMoveTo(start, 0, 0);
256
+ appendPathLineTo(start, 10, 0);
257
+ const end = createPath();
258
+ appendPathMoveTo(end, 10, 10);
259
+ appendPathLineTo(end, 20, 10);
260
+ const morph = createPathMorph(start, end)!;
261
+ const out = createPath();
262
+ const commands = out.commands;
263
+ const data = out.data;
264
+
265
+ samplePathMorph(out, morph, 0.25);
266
+ samplePathMorph(out, morph, 0.75);
267
+
268
+ expect(out.commands).toBe(commands);
269
+ expect(out.data).toBe(data);
270
+ });
271
+
272
+ it('permits progress outside zero to one for easing overshoot', () => {
273
+ const start = createPath();
274
+ appendPathMoveTo(start, 0, 0);
275
+ const end = createPath();
276
+ appendPathMoveTo(end, 10, 20);
277
+ const out = createPath();
278
+
279
+ samplePathMorph(out, createPathMorph(start, end)!, 1.5);
280
+
281
+ expect(out.data).toStrictEqual([15, 30]);
282
+ });
283
+
284
+ it('samples an empty path pair', () => {
285
+ const out = createPath();
286
+ samplePathMorph(out, createPathMorph(createPath(), createPath())!, 0.5);
287
+ expect(out.commands).toStrictEqual([]);
288
+ expect(out.data).toStrictEqual([]);
289
+ });
290
+ });
@@ -0,0 +1,18 @@
1
+ import { appendPathLineTo, appendPathMoveTo, createPath } from './path';
2
+ import { buildPathMorph, PathMorphIssueNone } from './pathMorphGeometry';
3
+
4
+ describe('buildPathMorph', () => {
5
+ it('returns the prepared buffers with the internal success issue', () => {
6
+ const start = createPath();
7
+ appendPathMoveTo(start, 0, 0);
8
+ appendPathLineTo(start, 1, 0);
9
+ const end = createPath();
10
+ appendPathMoveTo(end, 0, 0);
11
+ appendPathLineTo(end, 2, 0);
12
+
13
+ const result = buildPathMorph(start, end);
14
+
15
+ expect(result.issue).toBe(PathMorphIssueNone);
16
+ expect(result.morph).not.toBeNull();
17
+ });
18
+ });