• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / luma.gl / 23978164017

04 Apr 2026 11:41AM UTC coverage: 74.15% (+0.2%) from 73.912%
23978164017

push

github

web-flow
Experimental 3D text example (#2471)

5153 of 7858 branches covered (65.58%)

Branch coverage included in aggregate %.

463 of 552 new or added lines in 9 files covered. (83.88%)

11642 of 14792 relevant lines covered (78.7%)

747.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.85
/modules/text/src/paths/path.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4
// Adapted from THREE.js Path and Shape (https://github.com/mrdoob/three.js/) under the MIT License.
5

6
import {Vector2} from '@math.gl/core';
7
import {CurvePath} from './curve-path';
8
import {CubicBezierCurve, LineCurve, QuadraticBezierCurve, SplineCurve} from './curves';
9

10
/** Represents an ordered set of connected curve segments. */
11
export class Path extends CurvePath<Vector2> {
12
  /** Tracks the current pen position while constructing the path. */
13
  currentPoint = new Vector2();
34✔
14

15
  /** Creates a path initialized from an optional set of points. */
16
  constructor(points?: Vector2[]) {
17
    super();
34✔
18
    if (points?.length) {
34!
NEW
19
      this.setFromPoints(points);
×
20
    }
21
  }
22

23
  /** Replaces the path contents with straight segments through points. */
24
  setFromPoints(points: Vector2[]): this {
NEW
25
    this.moveTo(points[0].x, points[0].y);
×
NEW
26
    for (let i = 1; i < points.length; i++) {
×
NEW
27
      this.lineTo(points[i].x, points[i].y);
×
28
    }
NEW
29
    return this;
×
30
  }
31

32
  /** Moves the cursor to the provided coordinates. */
33
  moveTo(x: number, y: number): this {
34
    this.currentPoint.set(x, y);
27✔
35
    return this;
27✔
36
  }
37

38
  /** Adds a straight line segment to the path. */
39
  lineTo(x: number, y: number): this {
40
    const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y));
169✔
41
    this.curves.push(curve);
169✔
42
    this.currentPoint.set(x, y);
169✔
43
    return this;
169✔
44
  }
45

46
  /** Adds a quadratic bezier segment to the path. */
47
  quadraticCurveTo(controlPointX: number, controlPointY: number, x: number, y: number): this {
48
    const curve = new QuadraticBezierCurve(
1✔
49
      this.currentPoint.clone(),
50
      new Vector2(controlPointX, controlPointY),
51
      new Vector2(x, y)
52
    );
53
    this.curves.push(curve);
1✔
54
    this.currentPoint.set(x, y);
1✔
55
    return this;
1✔
56
  }
57

58
  /** Adds a cubic bezier segment to the path. */
59
  // eslint-disable-next-line max-params
60
  bezierCurveTo(
61
    controlPoint1X: number,
62
    controlPoint1Y: number,
63
    controlPoint2X: number,
64
    controlPoint2Y: number,
65
    x: number,
66
    y: number
67
  ): this {
68
    const curve = new CubicBezierCurve(
1✔
69
      this.currentPoint.clone(),
70
      new Vector2(controlPoint1X, controlPoint1Y),
71
      new Vector2(controlPoint2X, controlPoint2Y),
72
      new Vector2(x, y)
73
    );
74
    this.curves.push(curve);
1✔
75
    this.currentPoint.set(x, y);
1✔
76
    return this;
1✔
77
  }
78

79
  /** Adds a Catmull-Rom spline segment passing through points. */
80
  splineThru(points: Vector2[]): this {
NEW
81
    const controlPoints = [this.currentPoint.clone(), ...points];
×
NEW
82
    const curve = new SplineCurve(controlPoints);
×
NEW
83
    this.curves.push(curve);
×
NEW
84
    if (points.length > 0) {
×
NEW
85
      this.currentPoint.copy(points[points.length - 1]);
×
86
    }
NEW
87
    return this;
×
88
  }
89
}
90

91
/** Represents a closed path with optional holes. */
92
export class Shape extends Path {
93
  /** Child paths that carve holes out of the shape. */
94
  holes: Path[] = [];
7✔
95

96
  /** Creates a new shape initialized with optional points. */
97
  constructor(points?: Vector2[]) {
98
    super(points);
7✔
99
    this.holes = [];
7✔
100
  }
101

102
  /** Returns sampled points along the shape perimeter. */
103
  override getPoints(divisions = 12): Vector2[] {
7✔
104
    return super.getPoints(divisions);
7✔
105
  }
106

107
  /** Extracts sampled points for the outer contour and holes. */
108
  extractPoints(divisions = 12): {shape: Vector2[]; holes: Vector2[][]} {
7✔
109
    const shape = this.getPoints(divisions);
7✔
110
    const holes = this.holes.map(holePath => holePath.getPoints(divisions));
7✔
111
    return {shape, holes};
7✔
112
  }
113
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc