pts 0.11.6 → 0.12.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/.eslintignore +5 -0
- package/.eslintrc.js +52 -0
- package/dist/index.d.mts +1378 -0
- package/dist/index.d.ts +31 -33
- package/dist/index.js +723 -737
- package/dist/index.mjs +723 -737
- package/dist/pts.js +723 -737
- package/dist/pts.min.js +3 -3
- package/dist/pts.min.js.map +1 -1
- package/package.json +10 -5
package/dist/index.mjs
CHANGED
|
@@ -20,7 +20,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
// src/LinearAlgebra.ts
|
|
23
|
-
var Vec = class {
|
|
23
|
+
var Vec = class _Vec {
|
|
24
24
|
/**
|
|
25
25
|
* Add `b` to vector `a`.
|
|
26
26
|
* @returns vector `a`
|
|
@@ -113,44 +113,44 @@ var Vec = class {
|
|
|
113
113
|
* Magnitude of `a`.
|
|
114
114
|
*/
|
|
115
115
|
static magnitude(a) {
|
|
116
|
-
return Math.sqrt(
|
|
116
|
+
return Math.sqrt(_Vec.dot(a, a));
|
|
117
117
|
}
|
|
118
118
|
/**
|
|
119
119
|
* Unit vector of `a`. If magnitude of `a` is already known, pass it in the second paramter to optimize calculation.
|
|
120
120
|
*/
|
|
121
121
|
static unit(a, magnitude = void 0) {
|
|
122
|
-
|
|
122
|
+
const m = magnitude === void 0 ? _Vec.magnitude(a) : magnitude;
|
|
123
123
|
if (m === 0)
|
|
124
124
|
return Pt.make(a.length);
|
|
125
|
-
return
|
|
125
|
+
return _Vec.divide(a, m);
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Set `a` to its absolute value in each dimension.
|
|
129
129
|
* @returns vector `a`
|
|
130
130
|
*/
|
|
131
131
|
static abs(a) {
|
|
132
|
-
return
|
|
132
|
+
return _Vec.map(a, Math.abs);
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
135
135
|
* Set `a` to its floor value in each dimension.
|
|
136
136
|
* @returns vector `a`
|
|
137
137
|
*/
|
|
138
138
|
static floor(a) {
|
|
139
|
-
return
|
|
139
|
+
return _Vec.map(a, Math.floor);
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* Set `a` to its ceiling value in each dimension.
|
|
143
143
|
* @returns vector `a`
|
|
144
144
|
*/
|
|
145
145
|
static ceil(a) {
|
|
146
|
-
return
|
|
146
|
+
return _Vec.map(a, Math.ceil);
|
|
147
147
|
}
|
|
148
148
|
/**
|
|
149
149
|
* Set `a` to its rounded value in each dimension.
|
|
150
150
|
* @returns vector `a`
|
|
151
151
|
*/
|
|
152
152
|
static round(a) {
|
|
153
|
-
return
|
|
153
|
+
return _Vec.map(a, Math.round);
|
|
154
154
|
}
|
|
155
155
|
/**
|
|
156
156
|
* Find the max value within a vector's dimensions.
|
|
@@ -200,7 +200,7 @@ var Vec = class {
|
|
|
200
200
|
return a;
|
|
201
201
|
}
|
|
202
202
|
};
|
|
203
|
-
var Mat = class {
|
|
203
|
+
var Mat = class _Mat {
|
|
204
204
|
constructor() {
|
|
205
205
|
this.reset();
|
|
206
206
|
}
|
|
@@ -214,13 +214,13 @@ var Mat = class {
|
|
|
214
214
|
* Convert the value of its stored 3x3 matrix to a 2D [`DOMMatrix`](https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix) instance
|
|
215
215
|
*/
|
|
216
216
|
get domMatrix() {
|
|
217
|
-
return new DOMMatrix(
|
|
217
|
+
return new DOMMatrix(_Mat.toDOMMatrix(this._33));
|
|
218
218
|
}
|
|
219
219
|
/**
|
|
220
220
|
* Reset the internal 3x3 matrix to its identity
|
|
221
221
|
*/
|
|
222
222
|
reset() {
|
|
223
|
-
this._33 =
|
|
223
|
+
this._33 = _Mat.scale2DMatrix(1, 1);
|
|
224
224
|
}
|
|
225
225
|
/**
|
|
226
226
|
* Scale the internal 3x3 matrix. You can chain this function with other related functions.
|
|
@@ -228,8 +228,8 @@ var Mat = class {
|
|
|
228
228
|
* @param at Optional origin location to scale from.
|
|
229
229
|
*/
|
|
230
230
|
scale2D(val, at = [0, 0]) {
|
|
231
|
-
const m =
|
|
232
|
-
this._33 =
|
|
231
|
+
const m = _Mat.scaleAt2DMatrix(val[0] || 1, val[1] || 1, at);
|
|
232
|
+
this._33 = _Mat.multiply(this._33, m);
|
|
233
233
|
return this;
|
|
234
234
|
}
|
|
235
235
|
/**
|
|
@@ -238,8 +238,8 @@ var Mat = class {
|
|
|
238
238
|
* @param at Optional origin location to rotate from.
|
|
239
239
|
*/
|
|
240
240
|
rotate2D(ang, at = [0, 0]) {
|
|
241
|
-
const m =
|
|
242
|
-
this._33 =
|
|
241
|
+
const m = _Mat.rotateAt2DMatrix(Math.cos(ang), Math.sin(ang), at);
|
|
242
|
+
this._33 = _Mat.multiply(this._33, m);
|
|
243
243
|
return this;
|
|
244
244
|
}
|
|
245
245
|
/**
|
|
@@ -247,8 +247,8 @@ var Mat = class {
|
|
|
247
247
|
* @param val [x, y] offset values
|
|
248
248
|
*/
|
|
249
249
|
translate2D(val) {
|
|
250
|
-
const m =
|
|
251
|
-
this._33 =
|
|
250
|
+
const m = _Mat.translate2DMatrix(val[0] || 0, val[1] || 0);
|
|
251
|
+
this._33 = _Mat.multiply(this._33, m);
|
|
252
252
|
return this;
|
|
253
253
|
}
|
|
254
254
|
/**
|
|
@@ -257,8 +257,8 @@ var Mat = class {
|
|
|
257
257
|
* @param at Optional origin location to scale from.
|
|
258
258
|
*/
|
|
259
259
|
shear2D(val, at = [0, 0]) {
|
|
260
|
-
const m =
|
|
261
|
-
this._33 =
|
|
260
|
+
const m = _Mat.shearAt2DMatrix(Math.tan(val[0] || 0), Math.tan(val[1] || 1), at);
|
|
261
|
+
this._33 = _Mat.multiply(this._33, m);
|
|
262
262
|
return this;
|
|
263
263
|
}
|
|
264
264
|
/**
|
|
@@ -274,8 +274,8 @@ var Mat = class {
|
|
|
274
274
|
if (a.length != b.length)
|
|
275
275
|
throw new Error("Cannot add matrix if rows' and columns' size don't match.");
|
|
276
276
|
}
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
const g = new Group();
|
|
278
|
+
const isNum = typeof b == "number";
|
|
279
279
|
for (let i = 0, len = a.length; i < len; i++) {
|
|
280
280
|
g.push(a[i].$add(isNum ? b : b[i]));
|
|
281
281
|
}
|
|
@@ -290,7 +290,7 @@ var Mat = class {
|
|
|
290
290
|
* @returns If not elementwise, this will return a new group with M Pt, each with N dimensions (M-rows, N-columns).
|
|
291
291
|
*/
|
|
292
292
|
static multiply(a, b, transposed = false, elementwise = false) {
|
|
293
|
-
|
|
293
|
+
const g = new Group();
|
|
294
294
|
if (typeof b != "number") {
|
|
295
295
|
if (elementwise) {
|
|
296
296
|
if (a.length != b.length)
|
|
@@ -304,9 +304,9 @@ var Mat = class {
|
|
|
304
304
|
if (transposed && a[0].length != b[0].length)
|
|
305
305
|
throw new Error("Cannot multiply matrix if transposed and the columns in both matrices don't match.");
|
|
306
306
|
if (!transposed)
|
|
307
|
-
b =
|
|
307
|
+
b = _Mat.transpose(b);
|
|
308
308
|
for (let ai = 0, alen = a.length; ai < alen; ai++) {
|
|
309
|
-
|
|
309
|
+
const p = Pt.make(b.length, 0);
|
|
310
310
|
for (let bi = 0, blen = b.length; bi < blen; bi++) {
|
|
311
311
|
p[bi] = Vec.dot(a[ai], b[bi]);
|
|
312
312
|
}
|
|
@@ -327,7 +327,7 @@ var Mat = class {
|
|
|
327
327
|
* @param defaultValue a default value to fill if index out of bound. If not provided, it will throw an error instead.
|
|
328
328
|
*/
|
|
329
329
|
static zipSlice(g, index, defaultValue = false) {
|
|
330
|
-
|
|
330
|
+
const z = [];
|
|
331
331
|
for (let i = 0, len = g.length; i < len; i++) {
|
|
332
332
|
if (g[i].length - 1 < index && defaultValue === false)
|
|
333
333
|
throw `Index ${index} is out of bounds`;
|
|
@@ -342,10 +342,10 @@ var Mat = class {
|
|
|
342
342
|
* @param useLongest If true, find the longest list of values in a Pt and use its length for zipping. Default is false, which uses the first item's length for zipping.
|
|
343
343
|
*/
|
|
344
344
|
static zip(g, defaultValue = false, useLongest = false) {
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
const ps = new Group();
|
|
346
|
+
const len = useLongest ? g.reduce((a, b) => Math.max(a, b.length), 0) : g[0].length;
|
|
347
347
|
for (let i = 0; i < len; i++) {
|
|
348
|
-
ps.push(
|
|
348
|
+
ps.push(_Mat.zipSlice(g, i, defaultValue));
|
|
349
349
|
}
|
|
350
350
|
return ps;
|
|
351
351
|
}
|
|
@@ -353,7 +353,7 @@ var Mat = class {
|
|
|
353
353
|
* Same as `zip` function.
|
|
354
354
|
*/
|
|
355
355
|
static transpose(g, defaultValue = false, useLongest = false) {
|
|
356
|
-
return
|
|
356
|
+
return _Mat.zip(g, defaultValue, useLongest);
|
|
357
357
|
}
|
|
358
358
|
static toDOMMatrix(m) {
|
|
359
359
|
return [m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]];
|
|
@@ -365,8 +365,8 @@ var Mat = class {
|
|
|
365
365
|
* @returns a new transformed Pt
|
|
366
366
|
*/
|
|
367
367
|
static transform2D(pt, m) {
|
|
368
|
-
|
|
369
|
-
|
|
368
|
+
const x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];
|
|
369
|
+
const y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];
|
|
370
370
|
return new Pt(x, y);
|
|
371
371
|
}
|
|
372
372
|
/**
|
|
@@ -413,7 +413,7 @@ var Mat = class {
|
|
|
413
413
|
* Get a matrix to scale a point from an origin point. For use in `transform2D`.
|
|
414
414
|
*/
|
|
415
415
|
static scaleAt2DMatrix(sx, sy, at) {
|
|
416
|
-
|
|
416
|
+
const m = _Mat.scale2DMatrix(sx, sy);
|
|
417
417
|
m[2][0] = -at[0] * sx + at[0];
|
|
418
418
|
m[2][1] = -at[1] * sy + at[1];
|
|
419
419
|
return m;
|
|
@@ -422,7 +422,7 @@ var Mat = class {
|
|
|
422
422
|
* Get a matrix to rotate a point from an origin point. For use in `transform2D`.
|
|
423
423
|
*/
|
|
424
424
|
static rotateAt2DMatrix(cosA, sinA, at) {
|
|
425
|
-
|
|
425
|
+
const m = _Mat.rotate2DMatrix(cosA, sinA);
|
|
426
426
|
m[2][0] = at[0] * (1 - cosA) + at[1] * sinA;
|
|
427
427
|
m[2][1] = at[1] * (1 - cosA) - at[0] * sinA;
|
|
428
428
|
return m;
|
|
@@ -431,7 +431,7 @@ var Mat = class {
|
|
|
431
431
|
* Get a matrix to shear a point from an origin point. For use in `transform2D`.
|
|
432
432
|
*/
|
|
433
433
|
static shearAt2DMatrix(tanX, tanY, at) {
|
|
434
|
-
|
|
434
|
+
const m = _Mat.shear2DMatrix(tanX, tanY);
|
|
435
435
|
m[2][0] = -at[1] * tanY;
|
|
436
436
|
m[2][1] = -at[0] * tanX;
|
|
437
437
|
return m;
|
|
@@ -442,7 +442,7 @@ var Mat = class {
|
|
|
442
442
|
* @param p1 second end point to define the reflection line
|
|
443
443
|
*/
|
|
444
444
|
static reflectAt2DMatrix(p1, p2) {
|
|
445
|
-
|
|
445
|
+
const intercept = Line.intercept(p1, p2);
|
|
446
446
|
if (intercept == void 0) {
|
|
447
447
|
return [
|
|
448
448
|
new Pt([-1, 0, 0]),
|
|
@@ -450,10 +450,10 @@ var Mat = class {
|
|
|
450
450
|
new Pt([p1[0] + p2[0], 0, 1])
|
|
451
451
|
];
|
|
452
452
|
} else {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
453
|
+
const yi = intercept.yi;
|
|
454
|
+
const ang2 = Math.atan(intercept.slope) * 2;
|
|
455
|
+
const cosA = Math.cos(ang2);
|
|
456
|
+
const sinA = Math.sin(ang2);
|
|
457
457
|
return [
|
|
458
458
|
new Pt([cosA, sinA, 0]),
|
|
459
459
|
new Pt([sinA, -cosA, 0]),
|
|
@@ -466,7 +466,7 @@ var Mat = class {
|
|
|
466
466
|
// src/Op.ts
|
|
467
467
|
var _errorLength = (obj, param = "expected") => Util.warn("Group's length is less than " + param, obj);
|
|
468
468
|
var _errorOutofBound = (obj, param = "") => Util.warn(`Index ${param} is out of bound in Group`, obj);
|
|
469
|
-
var Line = class {
|
|
469
|
+
var Line = class _Line {
|
|
470
470
|
/**
|
|
471
471
|
* Create a line that originates from an anchor point, given an angle and a magnitude.
|
|
472
472
|
* @param anchor an anchor Pt
|
|
@@ -564,7 +564,7 @@ var Line = class {
|
|
|
564
564
|
*/
|
|
565
565
|
static distanceFromPt(line, pt) {
|
|
566
566
|
let _line = Util.iterToArray(line);
|
|
567
|
-
let projectionVector =
|
|
567
|
+
let projectionVector = _Line.perpendicularFromPt(_line, pt, true);
|
|
568
568
|
if (projectionVector) {
|
|
569
569
|
return projectionVector.magnitude();
|
|
570
570
|
} else {
|
|
@@ -580,8 +580,8 @@ var Line = class {
|
|
|
580
580
|
static intersectRay2D(la, lb) {
|
|
581
581
|
let _la = Util.iterToArray(la);
|
|
582
582
|
let _lb = Util.iterToArray(lb);
|
|
583
|
-
let a =
|
|
584
|
-
let b =
|
|
583
|
+
let a = _Line.intercept(_la[0], _la[1]);
|
|
584
|
+
let b = _Line.intercept(_lb[0], _lb[1]);
|
|
585
585
|
let pa = _la[0];
|
|
586
586
|
let pb = _lb[0];
|
|
587
587
|
if (a == void 0) {
|
|
@@ -615,7 +615,7 @@ var Line = class {
|
|
|
615
615
|
static intersectLine2D(la, lb) {
|
|
616
616
|
let _la = Util.iterToArray(la);
|
|
617
617
|
let _lb = Util.iterToArray(lb);
|
|
618
|
-
let pt =
|
|
618
|
+
let pt = _Line.intersectRay2D(_la, _lb);
|
|
619
619
|
return pt && Geom.withinBound(pt, _la[0], _la[1]) && Geom.withinBound(pt, _lb[0], _lb[1]) ? pt : void 0;
|
|
620
620
|
}
|
|
621
621
|
/**
|
|
@@ -627,7 +627,7 @@ var Line = class {
|
|
|
627
627
|
static intersectLineWithRay2D(line, ray) {
|
|
628
628
|
let _line = Util.iterToArray(line);
|
|
629
629
|
let _ray = Util.iterToArray(ray);
|
|
630
|
-
let pt =
|
|
630
|
+
let pt = _Line.intersectRay2D(_line, _ray);
|
|
631
631
|
return pt && Geom.withinBound(pt, _line[0], _line[1]) ? pt : void 0;
|
|
632
632
|
}
|
|
633
633
|
/**
|
|
@@ -639,7 +639,7 @@ var Line = class {
|
|
|
639
639
|
static intersectPolygon2D(lineOrRay, poly, sourceIsRay = false) {
|
|
640
640
|
let _lineOrRay = Util.iterToArray(lineOrRay);
|
|
641
641
|
let _poly = Util.iterToArray(poly);
|
|
642
|
-
let fn = sourceIsRay ?
|
|
642
|
+
let fn = sourceIsRay ? _Line.intersectLineWithRay2D : _Line.intersectLine2D;
|
|
643
643
|
let pts = new Group();
|
|
644
644
|
for (let i = 0, len = _poly.length; i < len; i++) {
|
|
645
645
|
let next = i === len - 1 ? 0 : i + 1;
|
|
@@ -657,7 +657,7 @@ var Line = class {
|
|
|
657
657
|
*/
|
|
658
658
|
static intersectLines2D(lines1, lines2, isRay = false) {
|
|
659
659
|
let group = new Group();
|
|
660
|
-
let fn = isRay ?
|
|
660
|
+
let fn = isRay ? _Line.intersectLineWithRay2D : _Line.intersectLine2D;
|
|
661
661
|
for (let l1 of lines1) {
|
|
662
662
|
for (let l2 of lines2) {
|
|
663
663
|
let _ip = fn(l1, l2);
|
|
@@ -675,7 +675,7 @@ var Line = class {
|
|
|
675
675
|
*/
|
|
676
676
|
static intersectGridWithRay2D(ray, gridPt) {
|
|
677
677
|
let _ray = Util.iterToArray(ray);
|
|
678
|
-
let t =
|
|
678
|
+
let t = _Line.intercept(new Pt(_ray[0]).subtract(gridPt), new Pt(_ray[1]).subtract(gridPt));
|
|
679
679
|
let g = new Group();
|
|
680
680
|
if (t && t.xi)
|
|
681
681
|
g.push(new Pt(gridPt[0] + t.xi, gridPt[1]));
|
|
@@ -691,7 +691,7 @@ var Line = class {
|
|
|
691
691
|
*/
|
|
692
692
|
static intersectGridWithLine2D(line, gridPt) {
|
|
693
693
|
let _line = Util.iterToArray(line);
|
|
694
|
-
let g =
|
|
694
|
+
let g = _Line.intersectGridWithRay2D(_line, gridPt);
|
|
695
695
|
let gg = new Group();
|
|
696
696
|
for (let i = 0, len = g.length; i < len; i++) {
|
|
697
697
|
if (Geom.withinBound(g[i], _line[0], _line[1]))
|
|
@@ -711,7 +711,7 @@ var Line = class {
|
|
|
711
711
|
let box = Geom.boundingBox(Group.fromPtArray(_line));
|
|
712
712
|
if (!Rectangle.hasIntersectRect2D(box, _rect))
|
|
713
713
|
return new Group();
|
|
714
|
-
return
|
|
714
|
+
return _Line.intersectLines2D([_line], Rectangle.sides(_rect));
|
|
715
715
|
}
|
|
716
716
|
/**
|
|
717
717
|
* Get evenly distributed points on a line. Similar to [`Create.distributeLinear`](#link) but excluding end points.
|
|
@@ -752,7 +752,7 @@ var Line = class {
|
|
|
752
752
|
} else {
|
|
753
753
|
sideIdx = ls[0] < 0 ? 3 : 1;
|
|
754
754
|
}
|
|
755
|
-
return
|
|
755
|
+
return _Line.intersectRay2D(sides[sideIdx], _line);
|
|
756
756
|
}
|
|
757
757
|
}
|
|
758
758
|
/**
|
|
@@ -788,7 +788,7 @@ var Line = class {
|
|
|
788
788
|
return new Group(_line[0].$min(_line[1]), _line[0].$max(_line[1]));
|
|
789
789
|
}
|
|
790
790
|
};
|
|
791
|
-
var Rectangle = class {
|
|
791
|
+
var Rectangle = class _Rectangle {
|
|
792
792
|
/**
|
|
793
793
|
* Create a rectangle from top-left anchor point. Same as [`Rectangle.fromTopLeft`](#link).
|
|
794
794
|
* @param topLeft top-left point
|
|
@@ -797,7 +797,7 @@ var Rectangle = class {
|
|
|
797
797
|
* @returns a Group of 2 Pts representing a rectangle
|
|
798
798
|
*/
|
|
799
799
|
static from(topLeft, widthOrSize, height) {
|
|
800
|
-
return
|
|
800
|
+
return _Rectangle.fromTopLeft(topLeft, widthOrSize, height);
|
|
801
801
|
}
|
|
802
802
|
/**
|
|
803
803
|
* Create a rectangle given a top-left position and a size.
|
|
@@ -838,9 +838,9 @@ var Rectangle = class {
|
|
|
838
838
|
*/
|
|
839
839
|
static toSquare(pts, enclose = false) {
|
|
840
840
|
let _pts = Util.iterToArray(pts);
|
|
841
|
-
let s =
|
|
841
|
+
let s = _Rectangle.size(_pts);
|
|
842
842
|
let m = enclose ? s.maxValue().value : s.minValue().value;
|
|
843
|
-
return
|
|
843
|
+
return _Rectangle.fromCenter(_Rectangle.center(_pts), m, m);
|
|
844
844
|
}
|
|
845
845
|
/**
|
|
846
846
|
* Get the size of this rectangle as a Pt.
|
|
@@ -876,7 +876,7 @@ var Rectangle = class {
|
|
|
876
876
|
* @returns an array of 4 Groups, each of which represents a line segment
|
|
877
877
|
*/
|
|
878
878
|
static sides(rect) {
|
|
879
|
-
let [p0, p1, p2, p3] =
|
|
879
|
+
let [p0, p1, p2, p3] = _Rectangle.corners(rect);
|
|
880
880
|
return [
|
|
881
881
|
new Group(p0, p1),
|
|
882
882
|
new Group(p1, p2),
|
|
@@ -910,7 +910,7 @@ var Rectangle = class {
|
|
|
910
910
|
* @param rect a Group or an Iterable<Pt> with 2 Pt representing a Rectangle
|
|
911
911
|
*/
|
|
912
912
|
static polygon(rect) {
|
|
913
|
-
return
|
|
913
|
+
return _Rectangle.corners(rect);
|
|
914
914
|
}
|
|
915
915
|
/**
|
|
916
916
|
* Subdivide a rectangle into 4 rectangles, one for each quadrant.
|
|
@@ -919,8 +919,8 @@ var Rectangle = class {
|
|
|
919
919
|
*/
|
|
920
920
|
static quadrants(rect, center) {
|
|
921
921
|
let _rect = Util.iterToArray(rect);
|
|
922
|
-
let corners =
|
|
923
|
-
let _center = center != void 0 ? new Pt(center) :
|
|
922
|
+
let corners = _Rectangle.corners(_rect);
|
|
923
|
+
let _center = center != void 0 ? new Pt(center) : _Rectangle.center(_rect);
|
|
924
924
|
return corners.map((c) => new Group(c, _center).boundingBox());
|
|
925
925
|
}
|
|
926
926
|
/**
|
|
@@ -973,12 +973,12 @@ var Rectangle = class {
|
|
|
973
973
|
static intersectRect2D(rect1, rect2) {
|
|
974
974
|
let _rect1 = Util.iterToArray(rect1);
|
|
975
975
|
let _rect2 = Util.iterToArray(rect2);
|
|
976
|
-
if (!
|
|
976
|
+
if (!_Rectangle.hasIntersectRect2D(_rect1, _rect2))
|
|
977
977
|
return new Group();
|
|
978
|
-
return Line.intersectLines2D(
|
|
978
|
+
return Line.intersectLines2D(_Rectangle.sides(_rect1), _Rectangle.sides(_rect2));
|
|
979
979
|
}
|
|
980
980
|
};
|
|
981
|
-
var Circle = class {
|
|
981
|
+
var Circle = class _Circle {
|
|
982
982
|
/**
|
|
983
983
|
* Create a circle that either fits within, or encloses, a rectangle.
|
|
984
984
|
* @param pts a Group or an Iterable<PtLike> with 2 Pt representing a rectangle
|
|
@@ -1069,7 +1069,7 @@ var Circle = class {
|
|
|
1069
1069
|
static intersectLine2D(circle, line) {
|
|
1070
1070
|
let _pts = Util.iterToArray(circle);
|
|
1071
1071
|
let _line = Util.iterToArray(line);
|
|
1072
|
-
let ps =
|
|
1072
|
+
let ps = _Circle.intersectRay2D(_pts, _line);
|
|
1073
1073
|
let g = new Group();
|
|
1074
1074
|
if (ps.length > 0) {
|
|
1075
1075
|
for (let i = 0, len = ps.length; i < len; i++) {
|
|
@@ -1122,7 +1122,7 @@ var Circle = class {
|
|
|
1122
1122
|
let sides = Rectangle.sides(_rect);
|
|
1123
1123
|
let g = [];
|
|
1124
1124
|
for (let i = 0, len = sides.length; i < len; i++) {
|
|
1125
|
-
let ps =
|
|
1125
|
+
let ps = _Circle.intersectLine2D(_pts, sides[i]);
|
|
1126
1126
|
if (ps.length > 0)
|
|
1127
1127
|
g.push(ps);
|
|
1128
1128
|
}
|
|
@@ -1165,7 +1165,7 @@ var Circle = class {
|
|
|
1165
1165
|
}
|
|
1166
1166
|
}
|
|
1167
1167
|
};
|
|
1168
|
-
var Triangle = class {
|
|
1168
|
+
var Triangle = class _Triangle {
|
|
1169
1169
|
/**
|
|
1170
1170
|
* Create a triangle from a rectangle. The triangle will be isosceles, with the bottom of the rectangle as its base.
|
|
1171
1171
|
* @param rect a Group or an Iterable<Pt> with 2 Pt representing a rectangle
|
|
@@ -1191,7 +1191,7 @@ var Triangle = class {
|
|
|
1191
1191
|
* @param size size is the magnitude of lines from center to the triangle's vertices, like a "radius".
|
|
1192
1192
|
*/
|
|
1193
1193
|
static fromCenter(pt, size) {
|
|
1194
|
-
return
|
|
1194
|
+
return _Triangle.fromCircle(Circle.fromCenter(pt, size));
|
|
1195
1195
|
}
|
|
1196
1196
|
/**
|
|
1197
1197
|
* Get the medial, which is an inner triangle formed by connecting the midpoints of this triangle's sides.
|
|
@@ -1230,7 +1230,7 @@ var Triangle = class {
|
|
|
1230
1230
|
*/
|
|
1231
1231
|
static altitude(tri, index) {
|
|
1232
1232
|
let _pts = Util.iterToArray(tri);
|
|
1233
|
-
let opp =
|
|
1233
|
+
let opp = _Triangle.oppositeSide(_pts, index);
|
|
1234
1234
|
if (opp.length > 1) {
|
|
1235
1235
|
return new Group(_pts[index], Line.perpendicularFromPt(opp, _pts[index]));
|
|
1236
1236
|
} else {
|
|
@@ -1246,8 +1246,8 @@ var Triangle = class {
|
|
|
1246
1246
|
let _pts = Util.iterToArray(tri);
|
|
1247
1247
|
if (_pts.length < 3)
|
|
1248
1248
|
return _errorLength(void 0, 3);
|
|
1249
|
-
let a =
|
|
1250
|
-
let b =
|
|
1249
|
+
let a = _Triangle.altitude(_pts, 0);
|
|
1250
|
+
let b = _Triangle.altitude(_pts, 1);
|
|
1251
1251
|
return Line.intersectRay2D(a, b);
|
|
1252
1252
|
}
|
|
1253
1253
|
/**
|
|
@@ -1270,7 +1270,7 @@ var Triangle = class {
|
|
|
1270
1270
|
*/
|
|
1271
1271
|
static incircle(tri, center) {
|
|
1272
1272
|
let _pts = Util.iterToArray(tri);
|
|
1273
|
-
let c = center ? center :
|
|
1273
|
+
let c = center ? center : _Triangle.incenter(_pts);
|
|
1274
1274
|
let area = Polygon.area(_pts);
|
|
1275
1275
|
let perim = Polygon.perimeter(_pts, true);
|
|
1276
1276
|
let r = 2 * area / perim.total;
|
|
@@ -1283,7 +1283,7 @@ var Triangle = class {
|
|
|
1283
1283
|
*/
|
|
1284
1284
|
static circumcenter(tri) {
|
|
1285
1285
|
let _pts = Util.iterToArray(tri);
|
|
1286
|
-
let md =
|
|
1286
|
+
let md = _Triangle.medial(_pts);
|
|
1287
1287
|
let a = [md[0], Geom.perpendicular(_pts[0].$subtract(md[0])).p1.$add(md[0])];
|
|
1288
1288
|
let b = [md[1], Geom.perpendicular(_pts[1].$subtract(md[1])).p1.$add(md[1])];
|
|
1289
1289
|
return Line.intersectRay2D(a, b);
|
|
@@ -1295,12 +1295,12 @@ var Triangle = class {
|
|
|
1295
1295
|
*/
|
|
1296
1296
|
static circumcircle(tri, center) {
|
|
1297
1297
|
let _pts = Util.iterToArray(tri);
|
|
1298
|
-
let c = center ? center :
|
|
1298
|
+
let c = center ? center : _Triangle.circumcenter(_pts);
|
|
1299
1299
|
let r = _pts[0].$subtract(c).magnitude();
|
|
1300
1300
|
return Circle.fromCenter(c, r);
|
|
1301
1301
|
}
|
|
1302
1302
|
};
|
|
1303
|
-
var Polygon = class {
|
|
1303
|
+
var Polygon = class _Polygon {
|
|
1304
1304
|
/**
|
|
1305
1305
|
* Get the centroid of a polygon, which is the average of all its points.
|
|
1306
1306
|
* @param pts a Group or an Iterable<PtLike> representing a polygon
|
|
@@ -1364,7 +1364,7 @@ var Polygon = class {
|
|
|
1364
1364
|
* @param t a value between 0 to 1 for interpolation. Default to 0.5 which will get the middle point.
|
|
1365
1365
|
*/
|
|
1366
1366
|
static midpoints(poly, closePath = false, t = 0.5) {
|
|
1367
|
-
let sides =
|
|
1367
|
+
let sides = _Polygon.lines(poly, closePath);
|
|
1368
1368
|
let mids = sides.map((s) => Geom.interpolate(s[0], s[1], t));
|
|
1369
1369
|
return mids;
|
|
1370
1370
|
}
|
|
@@ -1401,7 +1401,7 @@ var Polygon = class {
|
|
|
1401
1401
|
* @returns a bisector Pt that's a normalized unit vector
|
|
1402
1402
|
*/
|
|
1403
1403
|
static bisector(poly, index) {
|
|
1404
|
-
let sides =
|
|
1404
|
+
let sides = _Polygon.adjacentSides(poly, index, true);
|
|
1405
1405
|
if (sides.length >= 2) {
|
|
1406
1406
|
let a = sides[0][1].$subtract(sides[0][0]).unit();
|
|
1407
1407
|
let b = sides[1][1].$subtract(sides[1][0]).unit();
|
|
@@ -1417,7 +1417,7 @@ var Polygon = class {
|
|
|
1417
1417
|
* @returns an object with `total` length, and `segments` which is a Pt that stores each segment's length
|
|
1418
1418
|
*/
|
|
1419
1419
|
static perimeter(poly, closePath = false) {
|
|
1420
|
-
let lines =
|
|
1420
|
+
let lines = _Polygon.lines(poly, closePath);
|
|
1421
1421
|
let mag = 0;
|
|
1422
1422
|
let p = Pt.make(lines.length, 0);
|
|
1423
1423
|
for (let i = 0, len = lines.length; i < len; i++) {
|
|
@@ -1557,8 +1557,8 @@ var Polygon = class {
|
|
|
1557
1557
|
* @param unitAxis unit axis
|
|
1558
1558
|
*/
|
|
1559
1559
|
static _axisOverlap(poly1, poly2, unitAxis) {
|
|
1560
|
-
let pa =
|
|
1561
|
-
let pb =
|
|
1560
|
+
let pa = _Polygon.projectAxis(poly1, unitAxis);
|
|
1561
|
+
let pb = _Polygon.projectAxis(poly2, unitAxis);
|
|
1562
1562
|
return pa[0] < pb[0] ? pb[0] - pa[1] : pa[0] - pb[1];
|
|
1563
1563
|
}
|
|
1564
1564
|
/**
|
|
@@ -1570,7 +1570,7 @@ var Polygon = class {
|
|
|
1570
1570
|
let _poly = Util.iterToArray(poly);
|
|
1571
1571
|
let c = false;
|
|
1572
1572
|
for (let i = 0, len = _poly.length; i < len; i++) {
|
|
1573
|
-
let ln =
|
|
1573
|
+
let ln = _Polygon.lineAt(_poly, i);
|
|
1574
1574
|
if (ln[0][1] > pt[1] != ln[1][1] > pt[1] && pt[0] < (ln[1][0] - ln[0][0]) * (pt[1] - ln[0][1]) / (ln[1][1] - ln[0][1]) + ln[0][0]) {
|
|
1575
1575
|
c = !c;
|
|
1576
1576
|
}
|
|
@@ -1601,10 +1601,10 @@ var Polygon = class {
|
|
|
1601
1601
|
let r = _circle[1][0];
|
|
1602
1602
|
let minDist = Number.MAX_SAFE_INTEGER;
|
|
1603
1603
|
for (let i = 0, len = _poly.length; i < len; i++) {
|
|
1604
|
-
let edge =
|
|
1604
|
+
let edge = _Polygon.lineAt(_poly, i);
|
|
1605
1605
|
let axis = new Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
|
|
1606
1606
|
let poly2 = new Group(c.$add(axis.$multiply(r)), c.$subtract(axis.$multiply(r)));
|
|
1607
|
-
let dist =
|
|
1607
|
+
let dist = _Polygon._axisOverlap(_poly, poly2, axis);
|
|
1608
1608
|
if (dist > 0) {
|
|
1609
1609
|
return null;
|
|
1610
1610
|
} else if (Math.abs(dist) < minDist) {
|
|
@@ -1619,7 +1619,7 @@ var Polygon = class {
|
|
|
1619
1619
|
}
|
|
1620
1620
|
if (!info.edge)
|
|
1621
1621
|
return null;
|
|
1622
|
-
let dir = c.$subtract(
|
|
1622
|
+
let dir = c.$subtract(_Polygon.centroid(_poly)).dot(info.normal);
|
|
1623
1623
|
if (dir < 0)
|
|
1624
1624
|
info.normal.multiply(-1);
|
|
1625
1625
|
info.dist = minDist;
|
|
@@ -1648,9 +1648,9 @@ var Polygon = class {
|
|
|
1648
1648
|
};
|
|
1649
1649
|
let minDist = Number.MAX_SAFE_INTEGER;
|
|
1650
1650
|
for (let i = 0, plen = _poly1.length + _poly2.length; i < plen; i++) {
|
|
1651
|
-
let edge = i < _poly1.length ?
|
|
1651
|
+
let edge = i < _poly1.length ? _Polygon.lineAt(_poly1, i) : _Polygon.lineAt(_poly2, i - _poly1.length);
|
|
1652
1652
|
let axis = new Pt(edge[0].y - edge[1].y, edge[1].x - edge[0].x).unit();
|
|
1653
|
-
let dist =
|
|
1653
|
+
let dist = _Polygon._axisOverlap(_poly1, _poly2, axis);
|
|
1654
1654
|
if (dist > 0) {
|
|
1655
1655
|
return null;
|
|
1656
1656
|
} else if (Math.abs(dist) < minDist) {
|
|
@@ -1663,8 +1663,8 @@ var Polygon = class {
|
|
|
1663
1663
|
info.dist = minDist;
|
|
1664
1664
|
let b1 = info.which === 0 ? _poly2 : _poly1;
|
|
1665
1665
|
let b2 = info.which === 0 ? _poly1 : _poly2;
|
|
1666
|
-
let c1 =
|
|
1667
|
-
let c2 =
|
|
1666
|
+
let c1 = _Polygon.centroid(b1);
|
|
1667
|
+
let c2 = _Polygon.centroid(b2);
|
|
1668
1668
|
let dir = c1.$subtract(c2).dot(info.normal);
|
|
1669
1669
|
if (dir < 0)
|
|
1670
1670
|
info.normal.multiply(-1);
|
|
@@ -1686,7 +1686,7 @@ var Polygon = class {
|
|
|
1686
1686
|
static intersectPolygon2D(poly1, poly2) {
|
|
1687
1687
|
let _poly1 = Util.iterToArray(poly1);
|
|
1688
1688
|
let _poly2 = Util.iterToArray(poly2);
|
|
1689
|
-
let lp =
|
|
1689
|
+
let lp = _Polygon.lines(_poly1);
|
|
1690
1690
|
let g = [];
|
|
1691
1691
|
for (let i = 0, len = lp.length; i < len; i++) {
|
|
1692
1692
|
let ins = Line.intersectPolygon2D(lp[i], _poly2, false);
|
|
@@ -1709,7 +1709,7 @@ var Polygon = class {
|
|
|
1709
1709
|
return boxes;
|
|
1710
1710
|
}
|
|
1711
1711
|
};
|
|
1712
|
-
var Curve = class {
|
|
1712
|
+
var Curve = class _Curve {
|
|
1713
1713
|
/**
|
|
1714
1714
|
* Get a precalculated coefficients per step.
|
|
1715
1715
|
* @param steps number of steps
|
|
@@ -1768,17 +1768,17 @@ var Curve = class {
|
|
|
1768
1768
|
if (_pts.length < 2)
|
|
1769
1769
|
return new Group();
|
|
1770
1770
|
let ps = new Group();
|
|
1771
|
-
let ts =
|
|
1772
|
-
let c =
|
|
1771
|
+
let ts = _Curve.getSteps(steps);
|
|
1772
|
+
let c = _Curve.controlPoints(_pts, 0, true);
|
|
1773
1773
|
for (let i = 0; i <= steps; i++) {
|
|
1774
|
-
ps.push(
|
|
1774
|
+
ps.push(_Curve.catmullRomStep(ts[i], c));
|
|
1775
1775
|
}
|
|
1776
1776
|
let k = 0;
|
|
1777
1777
|
while (k < _pts.length - 2) {
|
|
1778
|
-
let cp =
|
|
1778
|
+
let cp = _Curve.controlPoints(_pts, k);
|
|
1779
1779
|
if (cp.length > 0) {
|
|
1780
1780
|
for (let i = 0; i <= steps; i++) {
|
|
1781
|
-
ps.push(
|
|
1781
|
+
ps.push(_Curve.catmullRomStep(ts[i], cp));
|
|
1782
1782
|
}
|
|
1783
1783
|
k++;
|
|
1784
1784
|
}
|
|
@@ -1798,7 +1798,7 @@ var Curve = class {
|
|
|
1798
1798
|
new Pt(-1.5, 2, 0.5, 0),
|
|
1799
1799
|
new Pt(0.5, -0.5, 0, 0)
|
|
1800
1800
|
);
|
|
1801
|
-
return
|
|
1801
|
+
return _Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
|
|
1802
1802
|
}
|
|
1803
1803
|
/**
|
|
1804
1804
|
* Create a Cardinal curve.
|
|
@@ -1812,17 +1812,17 @@ var Curve = class {
|
|
|
1812
1812
|
if (_pts.length < 2)
|
|
1813
1813
|
return new Group();
|
|
1814
1814
|
let ps = new Group();
|
|
1815
|
-
let ts =
|
|
1816
|
-
let c =
|
|
1815
|
+
let ts = _Curve.getSteps(steps);
|
|
1816
|
+
let c = _Curve.controlPoints(_pts, 0, true);
|
|
1817
1817
|
for (let i = 0; i <= steps; i++) {
|
|
1818
|
-
ps.push(
|
|
1818
|
+
ps.push(_Curve.cardinalStep(ts[i], c, tension));
|
|
1819
1819
|
}
|
|
1820
1820
|
let k = 0;
|
|
1821
1821
|
while (k < _pts.length - 2) {
|
|
1822
|
-
let cp =
|
|
1822
|
+
let cp = _Curve.controlPoints(_pts, k);
|
|
1823
1823
|
if (cp.length > 0) {
|
|
1824
1824
|
for (let i = 0; i <= steps; i++) {
|
|
1825
|
-
ps.push(
|
|
1825
|
+
ps.push(_Curve.cardinalStep(ts[i], cp, tension));
|
|
1826
1826
|
}
|
|
1827
1827
|
k++;
|
|
1828
1828
|
}
|
|
@@ -1846,7 +1846,7 @@ var Curve = class {
|
|
|
1846
1846
|
let h = Mat.multiply([step], m, true)[0].multiply(tension);
|
|
1847
1847
|
let h2 = 2 * step[0] - 3 * step[1] + 1;
|
|
1848
1848
|
let h3 = -2 * step[0] + 3 * step[1];
|
|
1849
|
-
let pt =
|
|
1849
|
+
let pt = _Curve._calcPt(ctrls, h);
|
|
1850
1850
|
pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
|
|
1851
1851
|
pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
|
|
1852
1852
|
if (pt.length > 2)
|
|
@@ -1864,13 +1864,13 @@ var Curve = class {
|
|
|
1864
1864
|
if (_pts.length < 4)
|
|
1865
1865
|
return new Group();
|
|
1866
1866
|
let ps = new Group();
|
|
1867
|
-
let ts =
|
|
1867
|
+
let ts = _Curve.getSteps(steps);
|
|
1868
1868
|
let k = 0;
|
|
1869
1869
|
while (k < _pts.length - 3) {
|
|
1870
|
-
let c =
|
|
1870
|
+
let c = _Curve.controlPoints(_pts, k);
|
|
1871
1871
|
if (c.length > 0) {
|
|
1872
1872
|
for (let i = 0; i <= steps; i++) {
|
|
1873
|
-
ps.push(
|
|
1873
|
+
ps.push(_Curve.bezierStep(ts[i], c));
|
|
1874
1874
|
}
|
|
1875
1875
|
k += 3;
|
|
1876
1876
|
}
|
|
@@ -1890,7 +1890,7 @@ var Curve = class {
|
|
|
1890
1890
|
new Pt(-3, 3, 0, 0),
|
|
1891
1891
|
new Pt(1, 0, 0, 0)
|
|
1892
1892
|
);
|
|
1893
|
-
return
|
|
1893
|
+
return _Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
|
|
1894
1894
|
}
|
|
1895
1895
|
/**
|
|
1896
1896
|
* Create a basis spline (NURBS) curve.
|
|
@@ -1904,18 +1904,18 @@ var Curve = class {
|
|
|
1904
1904
|
if (_pts.length < 2)
|
|
1905
1905
|
return new Group();
|
|
1906
1906
|
let ps = new Group();
|
|
1907
|
-
let ts =
|
|
1907
|
+
let ts = _Curve.getSteps(steps);
|
|
1908
1908
|
let k = 0;
|
|
1909
1909
|
while (k < _pts.length - 3) {
|
|
1910
|
-
let c =
|
|
1910
|
+
let c = _Curve.controlPoints(_pts, k);
|
|
1911
1911
|
if (c.length > 0) {
|
|
1912
1912
|
if (tension !== 1) {
|
|
1913
1913
|
for (let i = 0; i <= steps; i++) {
|
|
1914
|
-
ps.push(
|
|
1914
|
+
ps.push(_Curve.bsplineTensionStep(ts[i], c, tension));
|
|
1915
1915
|
}
|
|
1916
1916
|
} else {
|
|
1917
1917
|
for (let i = 0; i <= steps; i++) {
|
|
1918
|
-
ps.push(
|
|
1918
|
+
ps.push(_Curve.bsplineStep(ts[i], c));
|
|
1919
1919
|
}
|
|
1920
1920
|
}
|
|
1921
1921
|
k++;
|
|
@@ -1936,7 +1936,7 @@ var Curve = class {
|
|
|
1936
1936
|
new Pt(-0.5, 0.5, 0.5, 0.16666666666666666),
|
|
1937
1937
|
new Pt(0.16666666666666666, 0, 0, 0)
|
|
1938
1938
|
);
|
|
1939
|
-
return
|
|
1939
|
+
return _Curve._calcPt(ctrls, Mat.multiply([step], m, true)[0]);
|
|
1940
1940
|
}
|
|
1941
1941
|
/**
|
|
1942
1942
|
* Interpolate to get a point on a basis spline curve with tension.
|
|
@@ -1955,7 +1955,7 @@ var Curve = class {
|
|
|
1955
1955
|
let h = Mat.multiply([step], m, true)[0].multiply(tension);
|
|
1956
1956
|
let h2 = 2 * step[0] - 3 * step[1] + 1;
|
|
1957
1957
|
let h3 = -2 * step[0] + 3 * step[1];
|
|
1958
|
-
let pt =
|
|
1958
|
+
let pt = _Curve._calcPt(ctrls, h);
|
|
1959
1959
|
pt.x += h2 * ctrls[1].x + h3 * ctrls[2].x;
|
|
1960
1960
|
pt.y += h2 * ctrls[1].y + h3 * ctrls[2].y;
|
|
1961
1961
|
if (pt.length > 2)
|
|
@@ -1966,13 +1966,13 @@ var Curve = class {
|
|
|
1966
1966
|
|
|
1967
1967
|
// src/uheprng.ts
|
|
1968
1968
|
function Mash() {
|
|
1969
|
-
|
|
1970
|
-
|
|
1969
|
+
let n = 4022871197;
|
|
1970
|
+
let mash = function(data) {
|
|
1971
1971
|
if (data) {
|
|
1972
1972
|
data = data.toString();
|
|
1973
|
-
for (
|
|
1973
|
+
for (let i = 0; i < data.length; i++) {
|
|
1974
1974
|
n += data.charCodeAt(i);
|
|
1975
|
-
|
|
1975
|
+
let h = 0.02519603282416938 * n;
|
|
1976
1976
|
n = h >>> 0;
|
|
1977
1977
|
h -= n;
|
|
1978
1978
|
h *= n;
|
|
@@ -1987,12 +1987,12 @@ function Mash() {
|
|
|
1987
1987
|
return mash;
|
|
1988
1988
|
}
|
|
1989
1989
|
function uheprng_default(seed) {
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1990
|
+
let o = 48;
|
|
1991
|
+
let c = 1;
|
|
1992
|
+
let p = o;
|
|
1993
|
+
let s = new Array(o);
|
|
1994
|
+
let i, j, k = 0;
|
|
1995
|
+
let mash = Mash();
|
|
1996
1996
|
for (i = 0; i < o; i++)
|
|
1997
1997
|
s[i] = mash(Math.random().toString());
|
|
1998
1998
|
function initState() {
|
|
@@ -2024,24 +2024,24 @@ function uheprng_default(seed) {
|
|
|
2024
2024
|
hashString(seed);
|
|
2025
2025
|
return {
|
|
2026
2026
|
/**
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2027
|
+
* this (not anymore) PRIVATE (internal access only) function is the heart of the multiply-with-carry
|
|
2028
|
+
* (MWC) PRNG algorithm. When called it returns a pseudo-random number in the form of a
|
|
2029
|
+
* 32-bit JavaScript fraction (0.0 to <1.0) it is a PRIVATE function used by the default
|
|
2030
|
+
* [0-1] return function, and by the random 'string(n)' function which returns 'n'
|
|
2031
|
+
* characters from 33 to 126.
|
|
2032
|
+
* @returns a number between 0.0 and 1.0
|
|
2033
|
+
*/
|
|
2034
2034
|
random() {
|
|
2035
2035
|
if (++p >= o)
|
|
2036
2036
|
p = 0;
|
|
2037
|
-
|
|
2037
|
+
let t = 1768863 * s[p] + c * 23283064365386963e-26;
|
|
2038
2038
|
return s[p] = t - (c = t | 0);
|
|
2039
2039
|
}
|
|
2040
2040
|
};
|
|
2041
2041
|
}
|
|
2042
2042
|
|
|
2043
2043
|
// src/Num.ts
|
|
2044
|
-
var Num = class {
|
|
2044
|
+
var Num = class _Num {
|
|
2045
2045
|
/**
|
|
2046
2046
|
* Check if two numbers are equal or almost equal within a threshold.
|
|
2047
2047
|
* @param a number a
|
|
@@ -2077,7 +2077,7 @@ var Num = class {
|
|
|
2077
2077
|
* @example `boundValue(361, 0, 360)` will return 1
|
|
2078
2078
|
*/
|
|
2079
2079
|
static boundValue(val, min, max) {
|
|
2080
|
-
|
|
2080
|
+
const len = Math.abs(max - min);
|
|
2081
2081
|
let a = val % len;
|
|
2082
2082
|
if (a > max)
|
|
2083
2083
|
a -= len;
|
|
@@ -2100,8 +2100,8 @@ var Num = class {
|
|
|
2100
2100
|
* @param b range value 2
|
|
2101
2101
|
*/
|
|
2102
2102
|
static randomRange(a, b = 0) {
|
|
2103
|
-
|
|
2104
|
-
return a +
|
|
2103
|
+
const r = a > b ? a - b : b - a;
|
|
2104
|
+
return a + _Num.random() * r;
|
|
2105
2105
|
}
|
|
2106
2106
|
/**
|
|
2107
2107
|
* Get a random Pt within the range defined by either 1 or 2 Pt
|
|
@@ -2109,11 +2109,11 @@ var Num = class {
|
|
|
2109
2109
|
* @param b optional Pt to define the end of the range
|
|
2110
2110
|
*/
|
|
2111
2111
|
static randomPt(a, b) {
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2112
|
+
const p = new Pt(a.length);
|
|
2113
|
+
const range = b ? Vec.subtract(b.slice(), a) : a;
|
|
2114
|
+
const start = b ? a : new Pt(a.length).fill(0);
|
|
2115
2115
|
for (let i = 0, len = p.length; i < len; i++) {
|
|
2116
|
-
p[i] =
|
|
2116
|
+
p[i] = _Num.random() * range[i] + start[i];
|
|
2117
2117
|
}
|
|
2118
2118
|
return p;
|
|
2119
2119
|
}
|
|
@@ -2124,8 +2124,8 @@ var Num = class {
|
|
|
2124
2124
|
* @param b range value 1
|
|
2125
2125
|
*/
|
|
2126
2126
|
static normalizeValue(n, a, b) {
|
|
2127
|
-
|
|
2128
|
-
|
|
2127
|
+
const min = Math.min(a, b);
|
|
2128
|
+
const max = Math.max(a, b);
|
|
2129
2129
|
return (n - min) / (max - min);
|
|
2130
2130
|
}
|
|
2131
2131
|
/**
|
|
@@ -2134,8 +2134,8 @@ var Num = class {
|
|
|
2134
2134
|
* @returns a Pt of the dimensional sums
|
|
2135
2135
|
*/
|
|
2136
2136
|
static sum(pts) {
|
|
2137
|
-
|
|
2138
|
-
|
|
2137
|
+
const _pts = Util.iterToArray(pts);
|
|
2138
|
+
const c = new Pt(_pts[0]);
|
|
2139
2139
|
for (let i = 1, len = _pts.length; i < len; i++) {
|
|
2140
2140
|
Vec.add(c, _pts[i]);
|
|
2141
2141
|
}
|
|
@@ -2147,8 +2147,8 @@ var Num = class {
|
|
|
2147
2147
|
* @returns a Pt of averages
|
|
2148
2148
|
*/
|
|
2149
2149
|
static average(pts) {
|
|
2150
|
-
|
|
2151
|
-
return
|
|
2150
|
+
const _pts = Util.iterToArray(pts);
|
|
2151
|
+
return _Num.sum(_pts).divide(_pts.length);
|
|
2152
2152
|
}
|
|
2153
2153
|
/**
|
|
2154
2154
|
* Given a value between 0 to 1, returns a value that cycles between 0 -> 1 -> 0 using the provided shaping method.
|
|
@@ -2171,9 +2171,9 @@ var Num = class {
|
|
|
2171
2171
|
static mapToRange(n, currA, currB, targetA, targetB) {
|
|
2172
2172
|
if (currA == currB)
|
|
2173
2173
|
throw new Error("[currMin, currMax] must define a range that is not zero");
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
return
|
|
2174
|
+
const min = Math.min(targetA, targetB);
|
|
2175
|
+
const max = Math.max(targetA, targetB);
|
|
2176
|
+
return _Num.normalizeValue(n, currA, currB) * (max - min) + min;
|
|
2177
2177
|
}
|
|
2178
2178
|
/**
|
|
2179
2179
|
* Seed the pseudorandom generator.
|
|
@@ -2191,7 +2191,7 @@ var Num = class {
|
|
|
2191
2191
|
return this.generator ? this.generator.random() : Math.random();
|
|
2192
2192
|
}
|
|
2193
2193
|
};
|
|
2194
|
-
var Geom = class {
|
|
2194
|
+
var Geom = class _Geom {
|
|
2195
2195
|
/**
|
|
2196
2196
|
* Bound an angle between 0 to 360 degrees.
|
|
2197
2197
|
* @param angle angle value
|
|
@@ -2227,7 +2227,7 @@ var Geom = class {
|
|
|
2227
2227
|
*/
|
|
2228
2228
|
static boundingBox(pts) {
|
|
2229
2229
|
let minPt, maxPt;
|
|
2230
|
-
for (
|
|
2230
|
+
for (const p of pts) {
|
|
2231
2231
|
if (minPt == void 0) {
|
|
2232
2232
|
minPt = p.clone();
|
|
2233
2233
|
maxPt = p.clone();
|
|
@@ -2253,9 +2253,9 @@ var Geom = class {
|
|
|
2253
2253
|
* @param direction a string either "to" (subtract all Pt with this anchor base), or "from" (add all Pt from this anchor base)
|
|
2254
2254
|
*/
|
|
2255
2255
|
static anchor(pts, ptOrIndex = 0, direction = "to") {
|
|
2256
|
-
|
|
2256
|
+
const method = direction == "to" ? "subtract" : "add";
|
|
2257
2257
|
let i = 0;
|
|
2258
|
-
for (
|
|
2258
|
+
for (const p of pts) {
|
|
2259
2259
|
if (typeof ptOrIndex == "number") {
|
|
2260
2260
|
if (ptOrIndex !== i)
|
|
2261
2261
|
p[method](pts[ptOrIndex]);
|
|
@@ -2273,8 +2273,8 @@ var Geom = class {
|
|
|
2273
2273
|
* @returns interpolated point as a new Pt
|
|
2274
2274
|
*/
|
|
2275
2275
|
static interpolate(a, b, t = 0.5) {
|
|
2276
|
-
|
|
2277
|
-
|
|
2276
|
+
const len = Math.min(a.length, b.length);
|
|
2277
|
+
const d = Pt.make(len);
|
|
2278
2278
|
for (let i = 0; i < len; i++) {
|
|
2279
2279
|
d[i] = a[i] * (1 - t) + b[i] * t;
|
|
2280
2280
|
}
|
|
@@ -2286,13 +2286,13 @@ var Geom = class {
|
|
|
2286
2286
|
* @returns an array of two Pt that are perpendicular to this Pt
|
|
2287
2287
|
*/
|
|
2288
2288
|
static perpendicular(pt, axis = Const.xy) {
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2289
|
+
const y = axis[1];
|
|
2290
|
+
const x = axis[0];
|
|
2291
|
+
const p = new Pt(pt);
|
|
2292
|
+
const pa = new Pt(p);
|
|
2293
2293
|
pa[x] = -p[y];
|
|
2294
2294
|
pa[y] = p[x];
|
|
2295
|
-
|
|
2295
|
+
const pb = new Pt(p);
|
|
2296
2296
|
pb[x] = p[y];
|
|
2297
2297
|
pb[y] = -p[x];
|
|
2298
2298
|
return new Group(pa, pb);
|
|
@@ -2321,14 +2321,14 @@ var Geom = class {
|
|
|
2321
2321
|
* @param pts a Group or an Iterable<Pt>
|
|
2322
2322
|
*/
|
|
2323
2323
|
static sortEdges(pts) {
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2324
|
+
const _pts = Util.iterToArray(pts);
|
|
2325
|
+
const bounds = _Geom.boundingBox(_pts);
|
|
2326
|
+
const center = bounds[1].add(bounds[0]).divide(2);
|
|
2327
|
+
const fn = (a, b) => {
|
|
2328
2328
|
if (a.length < 2 || b.length < 2)
|
|
2329
2329
|
throw new Error("Pt dimension cannot be less than 2");
|
|
2330
|
-
|
|
2331
|
-
|
|
2330
|
+
const da = a.$subtract(center);
|
|
2331
|
+
const db = b.$subtract(center);
|
|
2332
2332
|
if (da[0] >= 0 && db[0] < 0)
|
|
2333
2333
|
return 1;
|
|
2334
2334
|
if (da[0] < 0 && db[0] >= 0)
|
|
@@ -2338,7 +2338,7 @@ var Geom = class {
|
|
|
2338
2338
|
return da[1] > db[1] ? 1 : -1;
|
|
2339
2339
|
return db[1] > da[1] ? 1 : -1;
|
|
2340
2340
|
}
|
|
2341
|
-
|
|
2341
|
+
const det = da.$cross2D(db);
|
|
2342
2342
|
if (det < 0)
|
|
2343
2343
|
return 1;
|
|
2344
2344
|
if (det > 0)
|
|
@@ -2354,17 +2354,17 @@ var Geom = class {
|
|
|
2354
2354
|
* @param anchor optional anchor point to scale from
|
|
2355
2355
|
*/
|
|
2356
2356
|
static scale(ps, scale, anchor) {
|
|
2357
|
-
|
|
2358
|
-
|
|
2357
|
+
const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
|
|
2358
|
+
const scs = typeof scale == "number" ? Pt.make(pts[0].length, scale) : scale;
|
|
2359
2359
|
if (!anchor)
|
|
2360
2360
|
anchor = Pt.make(pts[0].length, 0);
|
|
2361
2361
|
for (let i = 0, len = pts.length; i < len; i++) {
|
|
2362
|
-
|
|
2362
|
+
const p = pts[i];
|
|
2363
2363
|
for (let k = 0, lenP = p.length; k < lenP; k++) {
|
|
2364
2364
|
p[k] = anchor && anchor[k] ? anchor[k] + (p[k] - anchor[k]) * scs[k] : p[k] * scs[k];
|
|
2365
2365
|
}
|
|
2366
2366
|
}
|
|
2367
|
-
return
|
|
2367
|
+
return _Geom;
|
|
2368
2368
|
}
|
|
2369
2369
|
/**
|
|
2370
2370
|
* Rotate a Pt or a Group of Pts in 2D space. You may also use [`Pt.rotate2D`](#link) instance method.
|
|
@@ -2374,14 +2374,14 @@ var Geom = class {
|
|
|
2374
2374
|
* @param axis optional axis such as "xy" (use Const.xy) to define a 2D plane, or a number array to specify indices
|
|
2375
2375
|
*/
|
|
2376
2376
|
static rotate2D(ps, angle, anchor, axis) {
|
|
2377
|
-
|
|
2378
|
-
|
|
2377
|
+
const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
|
|
2378
|
+
const fn = anchor ? Mat.rotateAt2DMatrix : Mat.rotate2DMatrix;
|
|
2379
2379
|
if (!anchor)
|
|
2380
2380
|
anchor = Pt.make(pts[0].length, 0);
|
|
2381
|
-
|
|
2382
|
-
|
|
2381
|
+
const cos = Math.cos(angle);
|
|
2382
|
+
const sin = Math.sin(angle);
|
|
2383
2383
|
for (let i = 0, len = pts.length; i < len; i++) {
|
|
2384
|
-
|
|
2384
|
+
const p = axis ? pts[i].$take(axis) : pts[i];
|
|
2385
2385
|
p.to(Mat.transform2D(p, fn(cos, sin, anchor)));
|
|
2386
2386
|
if (axis) {
|
|
2387
2387
|
for (let k = 0; k < axis.length; k++) {
|
|
@@ -2389,7 +2389,7 @@ var Geom = class {
|
|
|
2389
2389
|
}
|
|
2390
2390
|
}
|
|
2391
2391
|
}
|
|
2392
|
-
return
|
|
2392
|
+
return _Geom;
|
|
2393
2393
|
}
|
|
2394
2394
|
/**
|
|
2395
2395
|
* Shear a Pt or a Group of Pts in 2D space. You may also use [`Pt.shear2D`](#link) instance method.
|
|
@@ -2399,15 +2399,15 @@ var Geom = class {
|
|
|
2399
2399
|
* @param axis optional axis such as "xy" (use Const.xy) to define a 2D plane, or a number array to specify indices
|
|
2400
2400
|
*/
|
|
2401
2401
|
static shear2D(ps, scale, anchor, axis) {
|
|
2402
|
-
|
|
2403
|
-
|
|
2402
|
+
const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
|
|
2403
|
+
const s = typeof scale == "number" ? [scale, scale] : scale;
|
|
2404
2404
|
if (!anchor)
|
|
2405
2405
|
anchor = Pt.make(pts[0].length, 0);
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2406
|
+
const fn = anchor ? Mat.shearAt2DMatrix : Mat.shear2DMatrix;
|
|
2407
|
+
const tanx = Math.tan(s[0]);
|
|
2408
|
+
const tany = Math.tan(s[1]);
|
|
2409
2409
|
for (let i = 0, len = pts.length; i < len; i++) {
|
|
2410
|
-
|
|
2410
|
+
const p = axis ? pts[i].$take(axis) : pts[i];
|
|
2411
2411
|
p.to(Mat.transform2D(p, fn(tanx, tany, anchor)));
|
|
2412
2412
|
if (axis) {
|
|
2413
2413
|
for (let k = 0; k < axis.length; k++) {
|
|
@@ -2415,7 +2415,7 @@ var Geom = class {
|
|
|
2415
2415
|
}
|
|
2416
2416
|
}
|
|
2417
2417
|
}
|
|
2418
|
-
return
|
|
2418
|
+
return _Geom;
|
|
2419
2419
|
}
|
|
2420
2420
|
/**
|
|
2421
2421
|
* Reflect a Pt or a Group of Pts along a 2D line. You may also use [`Pt.reflect2D`](#link) instance method.
|
|
@@ -2424,11 +2424,11 @@ var Geom = class {
|
|
|
2424
2424
|
* @param axis optional axis such as "xy" (use Const.xy) to define a 2D plane, or a number array to specify indices
|
|
2425
2425
|
*/
|
|
2426
2426
|
static reflect2D(ps, line, axis) {
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2427
|
+
const pts = Util.iterToArray(ps[0] !== void 0 && typeof ps[0] == "number" ? [ps] : ps);
|
|
2428
|
+
const _line = Util.iterToArray(line);
|
|
2429
|
+
const mat = Mat.reflectAt2DMatrix(_line[0], _line[1]);
|
|
2430
2430
|
for (let i = 0, len = pts.length; i < len; i++) {
|
|
2431
|
-
|
|
2431
|
+
const p = axis ? pts[i].$take(axis) : pts[i];
|
|
2432
2432
|
p.to(Mat.transform2D(p, mat));
|
|
2433
2433
|
if (axis) {
|
|
2434
2434
|
for (let k = 0; k < axis.length; k++) {
|
|
@@ -2436,17 +2436,17 @@ var Geom = class {
|
|
|
2436
2436
|
}
|
|
2437
2437
|
}
|
|
2438
2438
|
}
|
|
2439
|
-
return
|
|
2439
|
+
return _Geom;
|
|
2440
2440
|
}
|
|
2441
2441
|
/**
|
|
2442
2442
|
* Generate a cosine lookup table.
|
|
2443
2443
|
* @returns an object with a cosine tables (array of 360 values) and a function to get cosine given a radian input.
|
|
2444
2444
|
*/
|
|
2445
2445
|
static cosTable() {
|
|
2446
|
-
|
|
2446
|
+
const cos = new Float64Array(360);
|
|
2447
2447
|
for (let i = 0; i < 360; i++)
|
|
2448
2448
|
cos[i] = Math.cos(i * Math.PI / 180);
|
|
2449
|
-
|
|
2449
|
+
const find = (rad) => cos[Math.floor(_Geom.boundAngle(_Geom.toDegree(rad)))];
|
|
2450
2450
|
return { table: cos, cos: find };
|
|
2451
2451
|
}
|
|
2452
2452
|
/**
|
|
@@ -2454,14 +2454,14 @@ var Geom = class {
|
|
|
2454
2454
|
* @returns an object with a sine tables (array of 360 values) and a function to get sine value given a radian input.
|
|
2455
2455
|
*/
|
|
2456
2456
|
static sinTable() {
|
|
2457
|
-
|
|
2457
|
+
const sin = new Float64Array(360);
|
|
2458
2458
|
for (let i = 0; i < 360; i++)
|
|
2459
2459
|
sin[i] = Math.sin(i * Math.PI / 180);
|
|
2460
|
-
|
|
2460
|
+
const find = (rad) => sin[Math.floor(_Geom.boundAngle(_Geom.toDegree(rad)))];
|
|
2461
2461
|
return { table: sin, sin: find };
|
|
2462
2462
|
}
|
|
2463
2463
|
};
|
|
2464
|
-
var Shaping = class {
|
|
2464
|
+
var Shaping = class _Shaping {
|
|
2465
2465
|
/**
|
|
2466
2466
|
* Linear mapping.
|
|
2467
2467
|
* @param t a value between 0 to 1
|
|
@@ -2492,7 +2492,7 @@ var Shaping = class {
|
|
|
2492
2492
|
* @param c the value to shape, default is 1
|
|
2493
2493
|
*/
|
|
2494
2494
|
static quadraticInOut(t, c = 1) {
|
|
2495
|
-
|
|
2495
|
+
const dt = t * 2;
|
|
2496
2496
|
return t < 0.5 ? c / 2 * t * t * 4 : -c / 2 * ((dt - 1) * (dt - 3) - 1);
|
|
2497
2497
|
}
|
|
2498
2498
|
/**
|
|
@@ -2509,7 +2509,7 @@ var Shaping = class {
|
|
|
2509
2509
|
* @param c the value to shape, default is 1
|
|
2510
2510
|
*/
|
|
2511
2511
|
static cubicOut(t, c = 1) {
|
|
2512
|
-
|
|
2512
|
+
const dt = t - 1;
|
|
2513
2513
|
return c * (dt * dt * dt + 1);
|
|
2514
2514
|
}
|
|
2515
2515
|
/**
|
|
@@ -2518,7 +2518,7 @@ var Shaping = class {
|
|
|
2518
2518
|
* @param c the value to shape, default is 1
|
|
2519
2519
|
*/
|
|
2520
2520
|
static cubicInOut(t, c = 1) {
|
|
2521
|
-
|
|
2521
|
+
const dt = t * 2;
|
|
2522
2522
|
return t < 0.5 ? c / 2 * dt * dt * dt : c / 2 * ((dt - 2) * (dt - 2) * (dt - 2) + 2);
|
|
2523
2523
|
}
|
|
2524
2524
|
/**
|
|
@@ -2569,9 +2569,9 @@ var Shaping = class {
|
|
|
2569
2569
|
* @param c the value to shape, default is 1
|
|
2570
2570
|
*/
|
|
2571
2571
|
static cosineApprox(t, c = 1) {
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2572
|
+
const t2 = t * t;
|
|
2573
|
+
const t4 = t2 * t2;
|
|
2574
|
+
const t6 = t4 * t2;
|
|
2575
2575
|
return c * (4 * t6 / 9 - 17 * t4 / 9 + 22 * t2 / 9);
|
|
2576
2576
|
}
|
|
2577
2577
|
/**
|
|
@@ -2588,7 +2588,7 @@ var Shaping = class {
|
|
|
2588
2588
|
* @param c the value to shape, default is 1
|
|
2589
2589
|
*/
|
|
2590
2590
|
static circularOut(t, c = 1) {
|
|
2591
|
-
|
|
2591
|
+
const dt = t - 1;
|
|
2592
2592
|
return c * Math.sqrt(1 - dt * dt);
|
|
2593
2593
|
}
|
|
2594
2594
|
/**
|
|
@@ -2597,7 +2597,7 @@ var Shaping = class {
|
|
|
2597
2597
|
* @param c the value to shape, default is 1
|
|
2598
2598
|
*/
|
|
2599
2599
|
static circularInOut(t, c = 1) {
|
|
2600
|
-
|
|
2600
|
+
const dt = t * 2;
|
|
2601
2601
|
return t < 0.5 ? -c / 2 * (Math.sqrt(1 - dt * dt) - 1) : c / 2 * (Math.sqrt(1 - (dt - 2) * (dt - 2)) + 1);
|
|
2602
2602
|
}
|
|
2603
2603
|
/**
|
|
@@ -2607,8 +2607,8 @@ var Shaping = class {
|
|
|
2607
2607
|
* @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.
|
|
2608
2608
|
*/
|
|
2609
2609
|
static elasticIn(t, c = 1, p = 0.7) {
|
|
2610
|
-
|
|
2611
|
-
|
|
2610
|
+
const dt = t - 1;
|
|
2611
|
+
const s = p / Const.two_pi * 1.5707963267948966;
|
|
2612
2612
|
return c * (-Math.pow(2, 10 * dt) * Math.sin((dt - s) * Const.two_pi / p));
|
|
2613
2613
|
}
|
|
2614
2614
|
/**
|
|
@@ -2618,7 +2618,7 @@ var Shaping = class {
|
|
|
2618
2618
|
* @param p elastic parmeter between 0 to 1. The lower the number, the more elastic it will be. Default is 0.7.
|
|
2619
2619
|
*/
|
|
2620
2620
|
static elasticOut(t, c = 1, p = 0.7) {
|
|
2621
|
-
|
|
2621
|
+
const s = p / Const.two_pi * 1.5707963267948966;
|
|
2622
2622
|
return c * (Math.pow(2, -10 * t) * Math.sin((t - s) * Const.two_pi / p)) + c;
|
|
2623
2623
|
}
|
|
2624
2624
|
/**
|
|
@@ -2629,7 +2629,7 @@ var Shaping = class {
|
|
|
2629
2629
|
*/
|
|
2630
2630
|
static elasticInOut(t, c = 1, p = 0.6) {
|
|
2631
2631
|
let dt = t * 2;
|
|
2632
|
-
|
|
2632
|
+
const s = p / Const.two_pi * 1.5707963267948966;
|
|
2633
2633
|
if (t < 0.5) {
|
|
2634
2634
|
dt -= 1;
|
|
2635
2635
|
return c * (-0.5 * (Math.pow(2, 10 * dt) * Math.sin((dt - s) * Const.two_pi / p)));
|
|
@@ -2644,7 +2644,7 @@ var Shaping = class {
|
|
|
2644
2644
|
* @param c the value to shape, default is 1
|
|
2645
2645
|
*/
|
|
2646
2646
|
static bounceIn(t, c = 1) {
|
|
2647
|
-
return c -
|
|
2647
|
+
return c - _Shaping.bounceOut(1 - t, c);
|
|
2648
2648
|
}
|
|
2649
2649
|
/**
|
|
2650
2650
|
* Bounce out, adapted from Robert Penner's [easing functions](http://robertpenner.com/easing/).
|
|
@@ -2671,7 +2671,7 @@ var Shaping = class {
|
|
|
2671
2671
|
* @param c the value to shape, default is 1
|
|
2672
2672
|
*/
|
|
2673
2673
|
static bounceInOut(t, c = 1) {
|
|
2674
|
-
return t < 0.5 ?
|
|
2674
|
+
return t < 0.5 ? _Shaping.bounceIn(t * 2, c) / 2 : _Shaping.bounceOut(t * 2 - 1, c) / 2 + c / 2;
|
|
2675
2675
|
}
|
|
2676
2676
|
/**
|
|
2677
2677
|
* Sigmoid curve changes its shape adapted from the input value, but always returns a value between 0 to 1.
|
|
@@ -2680,7 +2680,7 @@ var Shaping = class {
|
|
|
2680
2680
|
* @param p the larger the value, the "steeper" the curve will be. Default is 10.
|
|
2681
2681
|
*/
|
|
2682
2682
|
static sigmoid(t, c = 1, p = 10) {
|
|
2683
|
-
|
|
2683
|
+
const d = p * (t - 0.5);
|
|
2684
2684
|
return c / (1 + Math.exp(-d));
|
|
2685
2685
|
}
|
|
2686
2686
|
/**
|
|
@@ -2692,9 +2692,9 @@ var Shaping = class {
|
|
|
2692
2692
|
static logSigmoid(t, c = 1, p = 0.7) {
|
|
2693
2693
|
p = Math.max(Const.epsilon, Math.min(1 - Const.epsilon, p));
|
|
2694
2694
|
p = 1 / (1 - p);
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2695
|
+
const A = 1 / (1 + Math.exp((t - 0.5) * p * -2));
|
|
2696
|
+
const B = 1 / (1 + Math.exp(p));
|
|
2697
|
+
const C = 1 / (1 + Math.exp(-p));
|
|
2698
2698
|
return c * (A - B) / (C - B);
|
|
2699
2699
|
}
|
|
2700
2700
|
/**
|
|
@@ -2717,13 +2717,13 @@ var Shaping = class {
|
|
|
2717
2717
|
* @param p1 a Pt object specifying the first control Pt, or a value specifying the control Pt's x position (its y position will default to 0.5). Default is `Pt(0.95, 0.95)
|
|
2718
2718
|
*/
|
|
2719
2719
|
static quadraticBezier(t, c = 1, p = [0.05, 0.95]) {
|
|
2720
|
-
|
|
2721
|
-
|
|
2720
|
+
const a = typeof p != "number" ? p[0] : p;
|
|
2721
|
+
const b = typeof p != "number" ? p[1] : 0.5;
|
|
2722
2722
|
let om2a = 1 - 2 * a;
|
|
2723
2723
|
if (om2a === 0) {
|
|
2724
2724
|
om2a = Const.epsilon;
|
|
2725
2725
|
}
|
|
2726
|
-
|
|
2726
|
+
const d = (Math.sqrt(a * a + om2a * t) - a) / om2a;
|
|
2727
2727
|
return c * ((1 - 2 * b) * (d * d) + 2 * b * d);
|
|
2728
2728
|
}
|
|
2729
2729
|
/**
|
|
@@ -2734,7 +2734,7 @@ var Shaping = class {
|
|
|
2734
2734
|
* @param p2` a Pt object specifying the second control Pt. Default is `Pt(0.9, 0.2).
|
|
2735
2735
|
*/
|
|
2736
2736
|
static cubicBezier(t, c = 1, p1 = [0.1, 0.7], p2 = [0.9, 0.2]) {
|
|
2737
|
-
|
|
2737
|
+
const curve = new Group(new Pt(0, 0), new Pt(p1), new Pt(p2), new Pt(1, 1));
|
|
2738
2738
|
return c * Curve.bezierStep(new Pt(t * t * t, t * t, t, 1), Curve.controlPoints(curve)).y;
|
|
2739
2739
|
}
|
|
2740
2740
|
/**
|
|
@@ -2744,11 +2744,11 @@ var Shaping = class {
|
|
|
2744
2744
|
* @param p1` a Pt object specifying the Pt to pass through. Default is `Pt(0.2, 0.35)
|
|
2745
2745
|
*/
|
|
2746
2746
|
static quadraticTarget(t, c = 1, p1 = [0.2, 0.35]) {
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2747
|
+
const a = Math.min(1 - Const.epsilon, Math.max(Const.epsilon, p1[0]));
|
|
2748
|
+
const b = Math.min(1, Math.max(0, p1[1]));
|
|
2749
|
+
const A = (1 - b) / (1 - a) - b / a;
|
|
2750
|
+
const B = (A * (a * a) - b) / a;
|
|
2751
|
+
const y = A * (t * t) - B * t;
|
|
2752
2752
|
return c * Math.min(1, Math.max(0, y));
|
|
2753
2753
|
}
|
|
2754
2754
|
/**
|
|
@@ -2769,8 +2769,8 @@ var Shaping = class {
|
|
|
2769
2769
|
* @param args optional paramters to pass to original function
|
|
2770
2770
|
*/
|
|
2771
2771
|
static step(fn, steps, t, c, ...args) {
|
|
2772
|
-
|
|
2773
|
-
|
|
2772
|
+
const s = 1 / steps;
|
|
2773
|
+
const tt = Math.floor(t / s) * s;
|
|
2774
2774
|
return fn(tt, c, ...args);
|
|
2775
2775
|
}
|
|
2776
2776
|
};
|
|
@@ -2808,16 +2808,16 @@ var Range = class {
|
|
|
2808
2808
|
calc() {
|
|
2809
2809
|
if (!this._source)
|
|
2810
2810
|
return;
|
|
2811
|
-
|
|
2811
|
+
const dims = this._source[0].length;
|
|
2812
2812
|
this._dims = dims;
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2813
|
+
const max = new Pt(dims);
|
|
2814
|
+
const min = new Pt(dims);
|
|
2815
|
+
const mag = new Pt(dims);
|
|
2816
2816
|
for (let i = 0; i < dims; i++) {
|
|
2817
2817
|
max[i] = Const.min;
|
|
2818
2818
|
min[i] = Const.max;
|
|
2819
2819
|
mag[i] = 0;
|
|
2820
|
-
|
|
2820
|
+
const s = this._source.zipSlice(i);
|
|
2821
2821
|
for (let k = 0, len = s.length; k < len; k++) {
|
|
2822
2822
|
max[i] = Math.max(max[i], s[k]);
|
|
2823
2823
|
min[i] = Math.min(min[i], s[k]);
|
|
@@ -2836,10 +2836,10 @@ var Range = class {
|
|
|
2836
2836
|
* @param exclude Optional boolean array where `true` means excluding the conversion in that specific dimension.
|
|
2837
2837
|
*/
|
|
2838
2838
|
mapTo(min, max, exclude) {
|
|
2839
|
-
|
|
2839
|
+
const target = new Group();
|
|
2840
2840
|
for (let i = 0, len = this._source.length; i < len; i++) {
|
|
2841
|
-
|
|
2842
|
-
|
|
2841
|
+
const g = this._source[i];
|
|
2842
|
+
const n = new Pt(this._dims);
|
|
2843
2843
|
for (let k = 0; k < this._dims; k++) {
|
|
2844
2844
|
n[k] = exclude && exclude[k] ? g[k] : Num.mapToRange(g[k], this._min[k], this._max[k], min, max);
|
|
2845
2845
|
}
|
|
@@ -2853,7 +2853,7 @@ var Range = class {
|
|
|
2853
2853
|
* @param update Optional. Set the parameter to `false` if you want to append without immediately updating this Range's min and max values. Default is `true`.
|
|
2854
2854
|
*/
|
|
2855
2855
|
append(pts, update = true) {
|
|
2856
|
-
|
|
2856
|
+
const _pts = Util.iterToArray(pts);
|
|
2857
2857
|
if (_pts[0].length !== this._dims)
|
|
2858
2858
|
throw new Error(`Dimensions don't match. ${this._dims} dimensions in Range and ${_pts[0].length} provided in parameter. `);
|
|
2859
2859
|
this._source = this._source.concat(_pts);
|
|
@@ -2866,9 +2866,9 @@ var Range = class {
|
|
|
2866
2866
|
* @param count number of subdivision. For example, 10 subdivision will return 11 tick values, which include first(min) and last(max) values.
|
|
2867
2867
|
*/
|
|
2868
2868
|
ticks(count) {
|
|
2869
|
-
|
|
2869
|
+
const g = new Group();
|
|
2870
2870
|
for (let i = 0; i <= count; i++) {
|
|
2871
|
-
|
|
2871
|
+
const p = new Pt(this._dims);
|
|
2872
2872
|
for (let k = 0, len = this._max.length; k < len; k++) {
|
|
2873
2873
|
p[k] = Num.lerp(this._min[k], this._max[k], i / count);
|
|
2874
2874
|
}
|
|
@@ -2937,7 +2937,7 @@ var Const = {
|
|
|
2937
2937
|
/** Gaussian constant (1 / Math.sqrt(2 * Math.PI)) */
|
|
2938
2938
|
gaussian: 0.3989422804014327
|
|
2939
2939
|
};
|
|
2940
|
-
var _Util = class {
|
|
2940
|
+
var _Util = class _Util {
|
|
2941
2941
|
/**
|
|
2942
2942
|
* Set a global warning level setting. If no parameter is passed, this will return the current warn-level. See [`Util.warn`](#link).
|
|
2943
2943
|
* @param lv a [`WarningType`](#link) option, where "error" will throw an error, "warn" will log in console, and "mute" will ignore the error.
|
|
@@ -3032,7 +3032,7 @@ var _Util = class {
|
|
|
3032
3032
|
* @param flattenAsGroup a boolean to specify whether the return type should be a Group or Array. Default is `true` which returns a Group.
|
|
3033
3033
|
*/
|
|
3034
3034
|
static flatten(pts, flattenAsGroup = true) {
|
|
3035
|
-
let arr = flattenAsGroup ? new Group() :
|
|
3035
|
+
let arr = flattenAsGroup ? new Group() : [];
|
|
3036
3036
|
return arr.concat.apply(arr, pts);
|
|
3037
3037
|
}
|
|
3038
3038
|
/**
|
|
@@ -3105,7 +3105,7 @@ var _Util = class {
|
|
|
3105
3105
|
* @param callback a function to capture the data. It receives two parameters: a `response` as string, and a `success` status as boolean.
|
|
3106
3106
|
*/
|
|
3107
3107
|
static load(url, callback) {
|
|
3108
|
-
|
|
3108
|
+
let request = new XMLHttpRequest();
|
|
3109
3109
|
request.open("GET", url, true);
|
|
3110
3110
|
request.onload = function() {
|
|
3111
3111
|
if (request.status >= 200 && request.status < 400) {
|
|
@@ -3183,11 +3183,11 @@ var _Util = class {
|
|
|
3183
3183
|
return /iPhone|iPad|Android/i.test(navigator.userAgent);
|
|
3184
3184
|
}
|
|
3185
3185
|
};
|
|
3186
|
+
_Util._warnLevel = "mute";
|
|
3186
3187
|
var Util = _Util;
|
|
3187
|
-
Util._warnLevel = "mute";
|
|
3188
3188
|
|
|
3189
3189
|
// src/Pt.ts
|
|
3190
|
-
var Pt = class extends Float32Array {
|
|
3190
|
+
var Pt = class _Pt extends Float32Array {
|
|
3191
3191
|
/**
|
|
3192
3192
|
* Create a Pt. If no parameter is provided, this will instantiate a Pt with 2 dimensions [0, 0].
|
|
3193
3193
|
* Note that `new Pt(3)` will only instantiate Pt with length of 3 (ie, same as `new Float32Array(3)` ). If you need a Pt with 1 dimension of value 3, use `new Pt([3])`.
|
|
@@ -3210,7 +3210,7 @@ var Pt = class extends Float32Array {
|
|
|
3210
3210
|
* @param randomize if `true`, randomize the value between 0 to default value
|
|
3211
3211
|
*/
|
|
3212
3212
|
static make(dimensions, defaultValue = 0, randomize = false) {
|
|
3213
|
-
|
|
3213
|
+
const p = new Float32Array(dimensions);
|
|
3214
3214
|
if (defaultValue)
|
|
3215
3215
|
p.fill(defaultValue);
|
|
3216
3216
|
if (randomize) {
|
|
@@ -3218,7 +3218,7 @@ var Pt = class extends Float32Array {
|
|
|
3218
3218
|
p[i] = p[i] * Num.random();
|
|
3219
3219
|
}
|
|
3220
3220
|
}
|
|
3221
|
-
return new
|
|
3221
|
+
return new _Pt(p);
|
|
3222
3222
|
}
|
|
3223
3223
|
/**
|
|
3224
3224
|
* ID string of this Pt
|
|
@@ -3269,7 +3269,7 @@ var Pt = class extends Float32Array {
|
|
|
3269
3269
|
* Clone this Pt and return it as a new Pt.
|
|
3270
3270
|
*/
|
|
3271
3271
|
clone() {
|
|
3272
|
-
return new
|
|
3272
|
+
return new _Pt(this);
|
|
3273
3273
|
}
|
|
3274
3274
|
/**
|
|
3275
3275
|
* Check if another Pt is equal to this Pt, within a threshold.
|
|
@@ -3288,7 +3288,7 @@ var Pt = class extends Float32Array {
|
|
|
3288
3288
|
* @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
|
|
3289
3289
|
*/
|
|
3290
3290
|
to(...args) {
|
|
3291
|
-
|
|
3291
|
+
const p = Util.getArgs(args);
|
|
3292
3292
|
for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
|
|
3293
3293
|
this[i] = p[i];
|
|
3294
3294
|
}
|
|
@@ -3308,8 +3308,8 @@ var Pt = class extends Float32Array {
|
|
|
3308
3308
|
* @param anchorFromPt If `true`, add it from this Pt's current position. Default is `false` which update the position from origin (0,0). See also [`Geom.rotate2D`](#link) for rotating a point from another anchor point.
|
|
3309
3309
|
*/
|
|
3310
3310
|
toAngle(radian, magnitude, anchorFromPt = false) {
|
|
3311
|
-
|
|
3312
|
-
|
|
3311
|
+
const m = magnitude != void 0 ? magnitude : this.magnitude();
|
|
3312
|
+
const change = [Math.cos(radian) * m, Math.sin(radian) * m];
|
|
3313
3313
|
return anchorFromPt ? this.add(change) : this.to(change);
|
|
3314
3314
|
}
|
|
3315
3315
|
/**
|
|
@@ -3319,7 +3319,7 @@ var Pt = class extends Float32Array {
|
|
|
3319
3319
|
* @returns a resulting function that takes other parameters required in `fn`
|
|
3320
3320
|
*/
|
|
3321
3321
|
op(fn) {
|
|
3322
|
-
|
|
3322
|
+
const self = this;
|
|
3323
3323
|
return (...params) => {
|
|
3324
3324
|
return fn(self, ...params);
|
|
3325
3325
|
};
|
|
@@ -3331,7 +3331,7 @@ var Pt = class extends Float32Array {
|
|
|
3331
3331
|
* @returns an array of resulting functions
|
|
3332
3332
|
*/
|
|
3333
3333
|
ops(fns) {
|
|
3334
|
-
|
|
3334
|
+
const _ops = [];
|
|
3335
3335
|
for (let i = 0, len = fns.length; i < len; i++) {
|
|
3336
3336
|
_ops.push(this.op(fns[i]));
|
|
3337
3337
|
}
|
|
@@ -3342,18 +3342,18 @@ var Pt = class extends Float32Array {
|
|
|
3342
3342
|
* @param axis a string such as "xy" (use Const.xy) or an array to specify indices
|
|
3343
3343
|
*/
|
|
3344
3344
|
$take(axis) {
|
|
3345
|
-
|
|
3345
|
+
const p = [];
|
|
3346
3346
|
for (let i = 0, len = axis.length; i < len; i++) {
|
|
3347
3347
|
p.push(this[axis[i]] || 0);
|
|
3348
3348
|
}
|
|
3349
|
-
return new
|
|
3349
|
+
return new _Pt(p);
|
|
3350
3350
|
}
|
|
3351
3351
|
/**
|
|
3352
3352
|
* Concatenate this Pt with addition dimensional values and return as a new Pt.
|
|
3353
3353
|
* @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
|
|
3354
3354
|
*/
|
|
3355
3355
|
$concat(...args) {
|
|
3356
|
-
return new
|
|
3356
|
+
return new _Pt(this.toArray().concat(Util.getArgs(args)));
|
|
3357
3357
|
}
|
|
3358
3358
|
/**
|
|
3359
3359
|
* Add scalar or vector values to this Pt.
|
|
@@ -3548,8 +3548,8 @@ var Pt = class extends Float32Array {
|
|
|
3548
3548
|
* @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
|
|
3549
3549
|
*/
|
|
3550
3550
|
$min(...args) {
|
|
3551
|
-
|
|
3552
|
-
|
|
3551
|
+
const p = Util.getArgs(args);
|
|
3552
|
+
const m = this.clone();
|
|
3553
3553
|
for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
|
|
3554
3554
|
m[i] = Math.min(this[i], p[i]);
|
|
3555
3555
|
}
|
|
@@ -3560,8 +3560,8 @@ var Pt = class extends Float32Array {
|
|
|
3560
3560
|
* @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
|
|
3561
3561
|
*/
|
|
3562
3562
|
$max(...args) {
|
|
3563
|
-
|
|
3564
|
-
|
|
3563
|
+
const p = Util.getArgs(args);
|
|
3564
|
+
const m = this.clone();
|
|
3565
3565
|
for (let i = 0, len = Math.min(this.length, p.length); i < len; i++) {
|
|
3566
3566
|
m[i] = Math.max(this[i], p[i]);
|
|
3567
3567
|
}
|
|
@@ -3588,7 +3588,7 @@ var Pt = class extends Float32Array {
|
|
|
3588
3588
|
* @param anchor optional anchor point to scale from
|
|
3589
3589
|
*/
|
|
3590
3590
|
scale(scale, anchor) {
|
|
3591
|
-
Geom.scale(this, scale, anchor ||
|
|
3591
|
+
Geom.scale(this, scale, anchor || _Pt.make(this.length, 0));
|
|
3592
3592
|
return this;
|
|
3593
3593
|
}
|
|
3594
3594
|
/**
|
|
@@ -3598,7 +3598,7 @@ var Pt = class extends Float32Array {
|
|
|
3598
3598
|
* @param axis optional string such as "yz" to specify a 2D plane
|
|
3599
3599
|
*/
|
|
3600
3600
|
rotate2D(angle, anchor, axis) {
|
|
3601
|
-
Geom.rotate2D(this, angle, anchor ||
|
|
3601
|
+
Geom.rotate2D(this, angle, anchor || _Pt.make(this.length, 0), axis);
|
|
3602
3602
|
return this;
|
|
3603
3603
|
}
|
|
3604
3604
|
/**
|
|
@@ -3608,7 +3608,7 @@ var Pt = class extends Float32Array {
|
|
|
3608
3608
|
* @param axis optional string such as "yz" to specify a 2D plane
|
|
3609
3609
|
*/
|
|
3610
3610
|
shear2D(scale, anchor, axis) {
|
|
3611
|
-
Geom.shear2D(this, scale, anchor ||
|
|
3611
|
+
Geom.shear2D(this, scale, anchor || _Pt.make(this.length, 0), axis);
|
|
3612
3612
|
return this;
|
|
3613
3613
|
}
|
|
3614
3614
|
/**
|
|
@@ -3636,16 +3636,16 @@ var Pt = class extends Float32Array {
|
|
|
3636
3636
|
* Convert this Pt to a Group as new Group([0,...], pt)
|
|
3637
3637
|
*/
|
|
3638
3638
|
toGroup() {
|
|
3639
|
-
return new Group(
|
|
3639
|
+
return new Group(_Pt.make(this.length), this.clone());
|
|
3640
3640
|
}
|
|
3641
3641
|
/**
|
|
3642
3642
|
* Convert this Pt to a Bound as new Group([0,...], pt)
|
|
3643
3643
|
*/
|
|
3644
3644
|
toBound() {
|
|
3645
|
-
return new Bound(
|
|
3645
|
+
return new Bound(_Pt.make(this.length), this.clone());
|
|
3646
3646
|
}
|
|
3647
3647
|
};
|
|
3648
|
-
var Group = class extends Array {
|
|
3648
|
+
var Group = class _Group extends Array {
|
|
3649
3649
|
/**
|
|
3650
3650
|
* Create a Group by passing an array of [`Pt`](#link). You may also create a Group using [`Group.fromArray`](#link) or [`Group.fromPtArray`](#link).
|
|
3651
3651
|
* @param args an array of Pts
|
|
@@ -3714,7 +3714,7 @@ var Group = class extends Array {
|
|
|
3714
3714
|
* Depp clone this group and its Pts.
|
|
3715
3715
|
*/
|
|
3716
3716
|
clone() {
|
|
3717
|
-
|
|
3717
|
+
const group = new _Group();
|
|
3718
3718
|
for (let i = 0, len = this.length; i < len; i++) {
|
|
3719
3719
|
group.push(this[i].clone());
|
|
3720
3720
|
}
|
|
@@ -3726,9 +3726,9 @@ var Group = class extends Array {
|
|
|
3726
3726
|
* @example `Group.fromArray( [[1,2], [3,4], [5,6]] )`
|
|
3727
3727
|
*/
|
|
3728
3728
|
static fromArray(list) {
|
|
3729
|
-
|
|
3730
|
-
for (
|
|
3731
|
-
|
|
3729
|
+
const g = new _Group();
|
|
3730
|
+
for (const li of list) {
|
|
3731
|
+
const p = li instanceof Pt ? li : new Pt(li);
|
|
3732
3732
|
g.push(p);
|
|
3733
3733
|
}
|
|
3734
3734
|
return g;
|
|
@@ -3738,7 +3738,7 @@ var Group = class extends Array {
|
|
|
3738
3738
|
* @param list an Iterable<Pt>
|
|
3739
3739
|
*/
|
|
3740
3740
|
static fromPtArray(list) {
|
|
3741
|
-
return
|
|
3741
|
+
return _Group.from(list);
|
|
3742
3742
|
}
|
|
3743
3743
|
/**
|
|
3744
3744
|
* Split this Group into an array of sub-groups.
|
|
@@ -3747,7 +3747,7 @@ var Group = class extends Array {
|
|
|
3747
3747
|
* @param loopBack if `true`, always go through the array till the end and loop back to the beginning to complete the segments if needed
|
|
3748
3748
|
*/
|
|
3749
3749
|
split(chunkSize, stride, loopBack = false) {
|
|
3750
|
-
|
|
3750
|
+
const sp = Util.split(this, chunkSize, stride, loopBack);
|
|
3751
3751
|
return sp;
|
|
3752
3752
|
}
|
|
3753
3753
|
/**
|
|
@@ -3756,7 +3756,7 @@ var Group = class extends Array {
|
|
|
3756
3756
|
* @param index the index position to insert into
|
|
3757
3757
|
*/
|
|
3758
3758
|
insert(pts, index = 0) {
|
|
3759
|
-
|
|
3759
|
+
_Group.prototype.splice.apply(this, [index, 0, ...pts]);
|
|
3760
3760
|
return this;
|
|
3761
3761
|
}
|
|
3762
3762
|
/**
|
|
@@ -3766,8 +3766,8 @@ var Group = class extends Array {
|
|
|
3766
3766
|
* @returns The items that are removed.
|
|
3767
3767
|
*/
|
|
3768
3768
|
remove(index = 0, count = 1) {
|
|
3769
|
-
|
|
3770
|
-
return
|
|
3769
|
+
const param = index < 0 ? [index * -1 - 1, count] : [index, count];
|
|
3770
|
+
return _Group.prototype.splice.apply(this, param);
|
|
3771
3771
|
}
|
|
3772
3772
|
/**
|
|
3773
3773
|
* Split this group into an array of sub-group segments.
|
|
@@ -3818,7 +3818,7 @@ var Group = class extends Array {
|
|
|
3818
3818
|
* @returns a resulting function that takes other parameters required in `fn`
|
|
3819
3819
|
*/
|
|
3820
3820
|
op(fn) {
|
|
3821
|
-
|
|
3821
|
+
const self = this;
|
|
3822
3822
|
return (...params) => {
|
|
3823
3823
|
return fn(self, ...params);
|
|
3824
3824
|
};
|
|
@@ -3830,7 +3830,7 @@ var Group = class extends Array {
|
|
|
3830
3830
|
* @returns an array of resulting functions
|
|
3831
3831
|
*/
|
|
3832
3832
|
ops(fns) {
|
|
3833
|
-
|
|
3833
|
+
const _ops = [];
|
|
3834
3834
|
for (let i = 0, len = fns.length; i < len; i++) {
|
|
3835
3835
|
_ops.push(this.op(fns[i]));
|
|
3836
3836
|
}
|
|
@@ -3842,9 +3842,9 @@ var Group = class extends Array {
|
|
|
3842
3842
|
*/
|
|
3843
3843
|
interpolate(t) {
|
|
3844
3844
|
t = Num.clamp(t, 0, 1);
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3845
|
+
const chunk = this.length - 1;
|
|
3846
|
+
const tc = 1 / (this.length - 1);
|
|
3847
|
+
const idx = Math.floor(t / tc);
|
|
3848
3848
|
return Geom.interpolate(this[idx], this[Math.min(this.length - 1, idx + 1)], (t - idx * tc) * chunk);
|
|
3849
3849
|
}
|
|
3850
3850
|
/**
|
|
@@ -3859,7 +3859,7 @@ var Group = class extends Array {
|
|
|
3859
3859
|
* @param args can be either a list of numbers, an array, a Pt, or an object with {x,y,z,w} properties
|
|
3860
3860
|
*/
|
|
3861
3861
|
moveTo(...args) {
|
|
3862
|
-
|
|
3862
|
+
const d = new Pt(Util.getArgs(args)).subtract(this[0]);
|
|
3863
3863
|
this.moveBy(d);
|
|
3864
3864
|
return this;
|
|
3865
3865
|
}
|
|
@@ -4007,7 +4007,7 @@ var Group = class extends Array {
|
|
|
4007
4007
|
return "Group[ " + this.reduce((p, c) => p + c.toString() + " ", "") + " ]";
|
|
4008
4008
|
}
|
|
4009
4009
|
};
|
|
4010
|
-
var Bound = class extends Group {
|
|
4010
|
+
var Bound = class _Bound extends Group {
|
|
4011
4011
|
/**
|
|
4012
4012
|
* Create a Bound. This is similar to the Group constructor. You can also create a Bound via the static function [`Bound.fromGroup`](#link), or alternatively via the [Group.toBound](#link) function.
|
|
4013
4013
|
* @param args a list of Pt as parameters
|
|
@@ -4028,7 +4028,7 @@ var Bound = class extends Group {
|
|
|
4028
4028
|
* @returns a Bound object
|
|
4029
4029
|
*/
|
|
4030
4030
|
static fromBoundingRect(rect) {
|
|
4031
|
-
|
|
4031
|
+
const b = new _Bound(new Pt(rect.left || 0, rect.top || 0), new Pt(rect.right || 0, rect.bottom || 0));
|
|
4032
4032
|
if (rect.width && rect.height)
|
|
4033
4033
|
b.size = new Pt(rect.width, rect.height);
|
|
4034
4034
|
return b;
|
|
@@ -4038,10 +4038,10 @@ var Bound = class extends Group {
|
|
|
4038
4038
|
* @param g a Group or an Iterable<PtLike>
|
|
4039
4039
|
*/
|
|
4040
4040
|
static fromGroup(g) {
|
|
4041
|
-
|
|
4041
|
+
const _g = Util.iterToArray(g);
|
|
4042
4042
|
if (_g.length < 2)
|
|
4043
4043
|
throw new Error("Cannot create a Bound from a group that has less than 2 Pt");
|
|
4044
|
-
return new
|
|
4044
|
+
return new _Bound(_g[0], _g[_g.length - 1]);
|
|
4045
4045
|
}
|
|
4046
4046
|
/**
|
|
4047
4047
|
* Initiate the bound's properties.
|
|
@@ -4052,8 +4052,8 @@ var Bound = class extends Group {
|
|
|
4052
4052
|
this._inited = true;
|
|
4053
4053
|
}
|
|
4054
4054
|
if (this.p1 && this.p2) {
|
|
4055
|
-
|
|
4056
|
-
|
|
4055
|
+
const a = this.p1;
|
|
4056
|
+
const b = this.p2;
|
|
4057
4057
|
this.topLeft = a.$min(b);
|
|
4058
4058
|
this._bottomRight = a.$max(b);
|
|
4059
4059
|
this._updateSize();
|
|
@@ -4064,7 +4064,7 @@ var Bound = class extends Group {
|
|
|
4064
4064
|
* Clone this bound and return a new one.
|
|
4065
4065
|
*/
|
|
4066
4066
|
clone() {
|
|
4067
|
-
return new
|
|
4067
|
+
return new _Bound(this._topLeft.clone(), this._bottomRight.clone());
|
|
4068
4068
|
}
|
|
4069
4069
|
/**
|
|
4070
4070
|
* Recalculte size and center.
|
|
@@ -4097,7 +4097,7 @@ var Bound = class extends Group {
|
|
|
4097
4097
|
* Recalculate based on center position and size.
|
|
4098
4098
|
*/
|
|
4099
4099
|
_updatePosFromCenter() {
|
|
4100
|
-
|
|
4100
|
+
const half = this._size.$multiply(0.5);
|
|
4101
4101
|
this._topLeft = this._center.$subtract(half);
|
|
4102
4102
|
this._bottomRight = this._center.$add(half);
|
|
4103
4103
|
}
|
|
@@ -4237,7 +4237,7 @@ var UIPointerActions = {
|
|
|
4237
4237
|
contextmenu: "contextmenu",
|
|
4238
4238
|
all: "all"
|
|
4239
4239
|
};
|
|
4240
|
-
var _UI = class {
|
|
4240
|
+
var _UI = class _UI {
|
|
4241
4241
|
/**
|
|
4242
4242
|
* Create an UI element. You may also create a new UI using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).
|
|
4243
4243
|
* @param group a Group or an Iterable<PtLike> that defines the UI's appearance
|
|
@@ -4473,8 +4473,8 @@ var _UI = class {
|
|
|
4473
4473
|
}
|
|
4474
4474
|
}
|
|
4475
4475
|
};
|
|
4476
|
+
_UI._counter = 0;
|
|
4476
4477
|
var UI = _UI;
|
|
4477
|
-
UI._counter = 0;
|
|
4478
4478
|
var UIButton = class extends UI {
|
|
4479
4479
|
/**
|
|
4480
4480
|
* Create an UIButton. A button has 2 states, "clicks" (number) and "hover" (boolean), which you can access through [`UI.state`](#link) function. You may also create a new UIButton using one of the static helper like [`UI.fromRectangle`](#link) or [`UI.fromCircle`](#link).
|
|
@@ -4499,7 +4499,7 @@ var UIButton = class extends UI {
|
|
|
4499
4499
|
if (hover && !this._states.hover) {
|
|
4500
4500
|
this.state("hover", true);
|
|
4501
4501
|
UI._trigger(this._actions[UA.enter], this, pt, UA.enter, evt);
|
|
4502
|
-
|
|
4502
|
+
let _capID = this.hold(UA.move);
|
|
4503
4503
|
this._hoverID = this.on(UA.move, (t, p) => {
|
|
4504
4504
|
if (!this._within(p) && !this.state("dragging")) {
|
|
4505
4505
|
this.state("hover", false);
|
|
@@ -4550,7 +4550,7 @@ var UIButton = class extends UI {
|
|
|
4550
4550
|
* @returns id numbers that refer to enter/leave handlers, for use in [`UIButton.offHover`](#link) or [`UI.off`](#link).
|
|
4551
4551
|
*/
|
|
4552
4552
|
onHover(enter, leave) {
|
|
4553
|
-
|
|
4553
|
+
let ids = [void 0, void 0];
|
|
4554
4554
|
if (enter)
|
|
4555
4555
|
ids[0] = this.on(UIPointerActions.enter, enter);
|
|
4556
4556
|
if (leave)
|
|
@@ -4564,7 +4564,7 @@ var UIButton = class extends UI {
|
|
|
4564
4564
|
* @returns an array of booleans indicating whether the handlers were removed successfully
|
|
4565
4565
|
*/
|
|
4566
4566
|
offHover(enterID, leaveID) {
|
|
4567
|
-
|
|
4567
|
+
let s = [false, false];
|
|
4568
4568
|
if (enterID === void 0 || enterID >= 0)
|
|
4569
4569
|
s[0] = this.off(UIPointerActions.enter, enterID);
|
|
4570
4570
|
if (leaveID === void 0 || leaveID >= 0)
|
|
@@ -4707,9 +4707,9 @@ var Space = class {
|
|
|
4707
4707
|
* @param player an [`IPlayer`](#link) object with animate function, or a callback function `fn(time, ftime)`.
|
|
4708
4708
|
*/
|
|
4709
4709
|
add(p) {
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4710
|
+
const player = typeof p == "function" ? { animate: p } : p;
|
|
4711
|
+
const k = this.playerCount++;
|
|
4712
|
+
const pid = player.animateID || this.id + k;
|
|
4713
4713
|
this.players[pid] = player;
|
|
4714
4714
|
player.animateID = pid;
|
|
4715
4715
|
if (player.resize && this.bound.inited)
|
|
@@ -4776,7 +4776,7 @@ var Space = class {
|
|
|
4776
4776
|
if (this._refresh)
|
|
4777
4777
|
this.clear();
|
|
4778
4778
|
if (this._isReady) {
|
|
4779
|
-
for (
|
|
4779
|
+
for (const k in this.players) {
|
|
4780
4780
|
if (this.players[k].animate)
|
|
4781
4781
|
this.players[k].animate(time, this._time.diff, this);
|
|
4782
4782
|
}
|
|
@@ -4894,7 +4894,7 @@ var MultiTouchSpace = class extends Space {
|
|
|
4894
4894
|
* Get the mouse or touch pointer that stores the last action.
|
|
4895
4895
|
*/
|
|
4896
4896
|
get pointer() {
|
|
4897
|
-
|
|
4897
|
+
const p = this._pointer.clone();
|
|
4898
4898
|
p.id = this._pointer.id;
|
|
4899
4899
|
return p;
|
|
4900
4900
|
}
|
|
@@ -4946,27 +4946,21 @@ var MultiTouchSpace = class extends Space {
|
|
|
4946
4946
|
this._mouseOut = this._mouseOut.bind(this);
|
|
4947
4947
|
this._mouseMove = this._mouseMove.bind(this);
|
|
4948
4948
|
this._mouseClick = this._mouseClick.bind(this);
|
|
4949
|
-
this._pointerDown = this._pointerDown.bind(this);
|
|
4950
|
-
this._pointerUp = this._pointerUp.bind(this);
|
|
4951
4949
|
this._contextMenu = this._contextMenu.bind(this);
|
|
4952
|
-
this.bindCanvas("
|
|
4953
|
-
this.bindCanvas("
|
|
4954
|
-
this.bindCanvas("
|
|
4955
|
-
this.bindCanvas("
|
|
4956
|
-
this.bindCanvas("
|
|
4957
|
-
this.bindCanvas("mouseout", this._mouseOut, {}, customTarget);
|
|
4958
|
-
this.bindCanvas("mousemove", this._mouseMove, {}, customTarget);
|
|
4950
|
+
this.bindCanvas("pointerdown", this._mouseDown, {}, customTarget);
|
|
4951
|
+
this.bindCanvas("pointerup", this._mouseUp, {}, customTarget);
|
|
4952
|
+
this.bindCanvas("pointerover", this._mouseOver, {}, customTarget);
|
|
4953
|
+
this.bindCanvas("pointerout", this._mouseOut, {}, customTarget);
|
|
4954
|
+
this.bindCanvas("pointermove", this._mouseMove, {}, customTarget);
|
|
4959
4955
|
this.bindCanvas("click", this._mouseClick, {}, customTarget);
|
|
4960
4956
|
this.bindCanvas("contextmenu", this._contextMenu, {}, customTarget);
|
|
4961
4957
|
this._hasMouse = true;
|
|
4962
4958
|
} else {
|
|
4963
|
-
this.unbindCanvas("
|
|
4964
|
-
this.unbindCanvas("
|
|
4965
|
-
this.unbindCanvas("
|
|
4966
|
-
this.unbindCanvas("
|
|
4967
|
-
this.unbindCanvas("
|
|
4968
|
-
this.unbindCanvas("mouseout", this._mouseOut, {}, customTarget);
|
|
4969
|
-
this.unbindCanvas("mousemove", this._mouseMove, {}, customTarget);
|
|
4959
|
+
this.unbindCanvas("pointerdown", this._mouseDown, {}, customTarget);
|
|
4960
|
+
this.unbindCanvas("pointerup", this._mouseUp, {}, customTarget);
|
|
4961
|
+
this.unbindCanvas("pointerover", this._mouseOver, {}, customTarget);
|
|
4962
|
+
this.unbindCanvas("pointerout", this._mouseOut, {}, customTarget);
|
|
4963
|
+
this.unbindCanvas("pointermove", this._mouseMove, {}, customTarget);
|
|
4970
4964
|
this.unbindCanvas("click", this._mouseClick, {}, customTarget);
|
|
4971
4965
|
this.unbindCanvas("contextmenu", this._contextMenu, {}, customTarget);
|
|
4972
4966
|
this._hasMouse = false;
|
|
@@ -5021,9 +5015,9 @@ var MultiTouchSpace = class extends Space {
|
|
|
5021
5015
|
touchesToPoints(evt, which = "touches") {
|
|
5022
5016
|
if (!evt || !evt[which])
|
|
5023
5017
|
return [];
|
|
5024
|
-
|
|
5025
|
-
for (
|
|
5026
|
-
|
|
5018
|
+
const ts = [];
|
|
5019
|
+
for (let i = 0; i < evt[which].length; i++) {
|
|
5020
|
+
const t = evt[which].item(i);
|
|
5027
5021
|
ts.push(new Pt(t.pageX - this.bound.topLeft.x, t.pageY - this.bound.topLeft.y));
|
|
5028
5022
|
}
|
|
5029
5023
|
return ts;
|
|
@@ -5039,9 +5033,9 @@ var MultiTouchSpace = class extends Space {
|
|
|
5039
5033
|
return;
|
|
5040
5034
|
let px = 0, py = 0;
|
|
5041
5035
|
if (evt instanceof MouseEvent) {
|
|
5042
|
-
for (
|
|
5036
|
+
for (const k in this.players) {
|
|
5043
5037
|
if (this.players.hasOwnProperty(k)) {
|
|
5044
|
-
|
|
5038
|
+
const v = this.players[k];
|
|
5045
5039
|
px = evt.pageX - this.outerBound.x;
|
|
5046
5040
|
py = evt.pageY - this.outerBound.y;
|
|
5047
5041
|
if (v.action)
|
|
@@ -5049,11 +5043,11 @@ var MultiTouchSpace = class extends Space {
|
|
|
5049
5043
|
}
|
|
5050
5044
|
}
|
|
5051
5045
|
} else {
|
|
5052
|
-
for (
|
|
5046
|
+
for (const k in this.players) {
|
|
5053
5047
|
if (this.players.hasOwnProperty(k)) {
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5048
|
+
const v = this.players[k];
|
|
5049
|
+
const c = evt.changedTouches && evt.changedTouches.length > 0;
|
|
5050
|
+
const touch = evt.changedTouches.item(0);
|
|
5057
5051
|
px = c ? touch.pageX - this.outerBound.x : 0;
|
|
5058
5052
|
py = c ? touch.pageY - this.outerBound.y : 0;
|
|
5059
5053
|
if (v.action)
|
|
@@ -5072,11 +5066,8 @@ var MultiTouchSpace = class extends Space {
|
|
|
5072
5066
|
*/
|
|
5073
5067
|
_mouseDown(evt) {
|
|
5074
5068
|
this._mouseAction(UIPointerActions.down, evt);
|
|
5075
|
-
this._pressed = true;
|
|
5076
|
-
return false;
|
|
5077
|
-
}
|
|
5078
|
-
_pointerDown(evt) {
|
|
5079
5069
|
this._mouseAction(UIPointerActions.pointerdown, evt);
|
|
5070
|
+
this._pressed = true;
|
|
5080
5071
|
if (evt.target instanceof Element) {
|
|
5081
5072
|
evt.target.setPointerCapture(evt.pointerId);
|
|
5082
5073
|
}
|
|
@@ -5087,6 +5078,7 @@ var MultiTouchSpace = class extends Space {
|
|
|
5087
5078
|
* @param evt
|
|
5088
5079
|
*/
|
|
5089
5080
|
_mouseUp(evt) {
|
|
5081
|
+
this._mouseAction(UIPointerActions.pointerup, evt);
|
|
5090
5082
|
if (this._dragged) {
|
|
5091
5083
|
this._mouseAction(UIPointerActions.drop, evt);
|
|
5092
5084
|
} else {
|
|
@@ -5094,15 +5086,8 @@ var MultiTouchSpace = class extends Space {
|
|
|
5094
5086
|
}
|
|
5095
5087
|
this._pressed = false;
|
|
5096
5088
|
this._dragged = false;
|
|
5097
|
-
return false;
|
|
5098
|
-
}
|
|
5099
|
-
_pointerUp(evt) {
|
|
5100
|
-
this._mouseAction(UIPointerActions.pointerup, evt);
|
|
5101
5089
|
if (evt.target instanceof Element) {
|
|
5102
5090
|
evt.target.releasePointerCapture(evt.pointerId);
|
|
5103
|
-
if (this._dragged)
|
|
5104
|
-
this._mouseAction(UIPointerActions.drop, evt);
|
|
5105
|
-
this._dragged = false;
|
|
5106
5091
|
}
|
|
5107
5092
|
return false;
|
|
5108
5093
|
}
|
|
@@ -5111,10 +5096,11 @@ var MultiTouchSpace = class extends Space {
|
|
|
5111
5096
|
* @param evt
|
|
5112
5097
|
*/
|
|
5113
5098
|
_mouseMove(evt) {
|
|
5114
|
-
this._mouseAction(UIPointerActions.move, evt);
|
|
5115
5099
|
if (this._pressed) {
|
|
5116
5100
|
this._dragged = true;
|
|
5117
5101
|
this._mouseAction(UIPointerActions.drag, evt);
|
|
5102
|
+
} else {
|
|
5103
|
+
this._mouseAction(UIPointerActions.move, evt);
|
|
5118
5104
|
}
|
|
5119
5105
|
return false;
|
|
5120
5106
|
}
|
|
@@ -5160,7 +5146,11 @@ var MultiTouchSpace = class extends Space {
|
|
|
5160
5146
|
* @param evt
|
|
5161
5147
|
*/
|
|
5162
5148
|
_touchMove(evt) {
|
|
5163
|
-
this.
|
|
5149
|
+
this._mouseAction(UIPointerActions.move, evt);
|
|
5150
|
+
if (this._pressed) {
|
|
5151
|
+
this._dragged = true;
|
|
5152
|
+
this._mouseAction(UIPointerActions.drag, evt);
|
|
5153
|
+
}
|
|
5164
5154
|
evt.preventDefault();
|
|
5165
5155
|
return false;
|
|
5166
5156
|
}
|
|
@@ -5169,7 +5159,9 @@ var MultiTouchSpace = class extends Space {
|
|
|
5169
5159
|
* @param evt
|
|
5170
5160
|
*/
|
|
5171
5161
|
_touchStart(evt) {
|
|
5172
|
-
this.
|
|
5162
|
+
this._mouseAction(UIPointerActions.down, evt);
|
|
5163
|
+
this._pressed = true;
|
|
5164
|
+
return false;
|
|
5173
5165
|
evt.preventDefault();
|
|
5174
5166
|
return false;
|
|
5175
5167
|
}
|
|
@@ -5184,9 +5176,9 @@ var MultiTouchSpace = class extends Space {
|
|
|
5184
5176
|
_keyboardAction(type, evt) {
|
|
5185
5177
|
if (!this.isPlaying)
|
|
5186
5178
|
return;
|
|
5187
|
-
for (
|
|
5179
|
+
for (const k in this.players) {
|
|
5188
5180
|
if (this.players.hasOwnProperty(k)) {
|
|
5189
|
-
|
|
5181
|
+
const v = this.players[k];
|
|
5190
5182
|
if (v.action)
|
|
5191
5183
|
v.action(type, evt.shiftKey ? 1 : 0, evt.altKey ? 1 : 0, evt);
|
|
5192
5184
|
}
|
|
@@ -5435,7 +5427,7 @@ var Typography = class {
|
|
|
5435
5427
|
};
|
|
5436
5428
|
|
|
5437
5429
|
// src/Image.ts
|
|
5438
|
-
var Img = class {
|
|
5430
|
+
var Img = class _Img {
|
|
5439
5431
|
/**
|
|
5440
5432
|
* Create an Img
|
|
5441
5433
|
* @param editable Specify if you want to manipulate pixels of this image. Default is `false`.
|
|
@@ -5460,7 +5452,7 @@ var Img = class {
|
|
|
5460
5452
|
* @param ready An optional ready callback function
|
|
5461
5453
|
*/
|
|
5462
5454
|
static load(src, editable = false, space, ready) {
|
|
5463
|
-
const img = new
|
|
5455
|
+
const img = new _Img(editable, space);
|
|
5464
5456
|
img.load(src).then((res) => {
|
|
5465
5457
|
if (ready)
|
|
5466
5458
|
ready(res);
|
|
@@ -5476,7 +5468,7 @@ var Img = class {
|
|
|
5476
5468
|
*/
|
|
5477
5469
|
static loadAsync(src, editable = false, space) {
|
|
5478
5470
|
return __async(this, null, function* () {
|
|
5479
|
-
const img = yield new
|
|
5471
|
+
const img = yield new _Img(editable, space).load(src);
|
|
5480
5472
|
return img;
|
|
5481
5473
|
});
|
|
5482
5474
|
}
|
|
@@ -5490,7 +5482,7 @@ var Img = class {
|
|
|
5490
5482
|
*/
|
|
5491
5483
|
static loadPattern(src, space, repeat = "repeat", editable = false) {
|
|
5492
5484
|
return __async(this, null, function* () {
|
|
5493
|
-
const img = yield
|
|
5485
|
+
const img = yield _Img.loadAsync(src, editable, space);
|
|
5494
5486
|
return img.pattern(repeat);
|
|
5495
5487
|
});
|
|
5496
5488
|
}
|
|
@@ -5501,7 +5493,7 @@ var Img = class {
|
|
|
5501
5493
|
* @param scale Optionally set a specific pixel scale (density) of the image canvas.
|
|
5502
5494
|
*/
|
|
5503
5495
|
static blank(size, space, scale) {
|
|
5504
|
-
let img = new
|
|
5496
|
+
let img = new _Img(true, space);
|
|
5505
5497
|
const s = scale ? scale : space.pixelScale;
|
|
5506
5498
|
img.initCanvas(size[0], size[1], s);
|
|
5507
5499
|
return img;
|
|
@@ -5607,7 +5599,7 @@ var Img = class {
|
|
|
5607
5599
|
*/
|
|
5608
5600
|
pixel(p, rescale = true) {
|
|
5609
5601
|
const s = typeof rescale == "number" ? rescale : rescale ? this._scale : 1;
|
|
5610
|
-
return
|
|
5602
|
+
return _Img.getPixel(this._data, [p[0] * s, p[1] * s]);
|
|
5611
5603
|
}
|
|
5612
5604
|
/**
|
|
5613
5605
|
* Given an ImaegData object and a position, return the RGBA pixel value at that position.
|
|
@@ -5672,7 +5664,7 @@ var Img = class {
|
|
|
5672
5664
|
*/
|
|
5673
5665
|
static fromBlob(blob, editable = false, space) {
|
|
5674
5666
|
let url = URL.createObjectURL(blob);
|
|
5675
|
-
return new
|
|
5667
|
+
return new _Img(editable, space).load(url);
|
|
5676
5668
|
}
|
|
5677
5669
|
/**
|
|
5678
5670
|
* Convert ImageData object to a Blob, which you can then create an Img instance via [`Img.fromBlob`](#link). Note that the resulting image's dimensions will not account for pixel density.
|
|
@@ -5800,8 +5792,8 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
5800
5792
|
this._bgcolor = "#e1e9f0";
|
|
5801
5793
|
this._offscreen = false;
|
|
5802
5794
|
this._initialResize = false;
|
|
5803
|
-
|
|
5804
|
-
|
|
5795
|
+
let _selector = null;
|
|
5796
|
+
let _existed = false;
|
|
5805
5797
|
this.id = "pt";
|
|
5806
5798
|
if (elem instanceof Element) {
|
|
5807
5799
|
_selector = elem;
|
|
@@ -5838,7 +5830,7 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
5838
5830
|
* @param id element id attribute
|
|
5839
5831
|
*/
|
|
5840
5832
|
_createElement(elem = "div", id) {
|
|
5841
|
-
|
|
5833
|
+
const d = document.createElement(elem);
|
|
5842
5834
|
d.setAttribute("id", id);
|
|
5843
5835
|
return d;
|
|
5844
5836
|
}
|
|
@@ -5853,7 +5845,7 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
5853
5845
|
this._resizeHandler(null);
|
|
5854
5846
|
this.clear(this._bgcolor);
|
|
5855
5847
|
this._canvas.dispatchEvent(new Event("ready"));
|
|
5856
|
-
for (
|
|
5848
|
+
for (const k in this.players) {
|
|
5857
5849
|
if (this.players.hasOwnProperty(k)) {
|
|
5858
5850
|
if (this.players[k].start)
|
|
5859
5851
|
this.players[k].start(this.bound.clone(), this);
|
|
@@ -5873,8 +5865,8 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
5873
5865
|
this._bgcolor = opt.bgcolor ? opt.bgcolor : "transparent";
|
|
5874
5866
|
this.autoResize = opt.resize != void 0 ? opt.resize : false;
|
|
5875
5867
|
if (opt.retina !== false) {
|
|
5876
|
-
|
|
5877
|
-
|
|
5868
|
+
const r1 = window ? window.devicePixelRatio || 1 : 1;
|
|
5869
|
+
const r2 = this._ctx.webkitBackingStorePixelRatio || this._ctx.mozBackingStorePixelRatio || this._ctx.msBackingStorePixelRatio || this._ctx.oBackingStorePixelRatio || this._ctx.backingStorePixelRatio || 1;
|
|
5878
5870
|
this._pixelScale = Math.max(1, r1 / r2);
|
|
5879
5871
|
}
|
|
5880
5872
|
if (opt.offscreen) {
|
|
@@ -5928,9 +5920,9 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
5928
5920
|
this._offCtx.scale(this._pixelScale, this._pixelScale);
|
|
5929
5921
|
}
|
|
5930
5922
|
}
|
|
5931
|
-
for (
|
|
5923
|
+
for (const k in this.players) {
|
|
5932
5924
|
if (this.players.hasOwnProperty(k)) {
|
|
5933
|
-
|
|
5925
|
+
const p = this.players[k];
|
|
5934
5926
|
if (p.resize)
|
|
5935
5927
|
p.resize(this.bound, evt);
|
|
5936
5928
|
}
|
|
@@ -5947,9 +5939,9 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
5947
5939
|
_resizeHandler(evt) {
|
|
5948
5940
|
if (!window)
|
|
5949
5941
|
return;
|
|
5950
|
-
|
|
5942
|
+
const b = this._autoResize || this._initialResize ? this._container.getBoundingClientRect() : this._canvas.getBoundingClientRect();
|
|
5951
5943
|
if (b) {
|
|
5952
|
-
|
|
5944
|
+
const box = Bound.fromBoundingRect(b);
|
|
5953
5945
|
box.center = box.center.add(window.pageXOffset, window.pageYOffset);
|
|
5954
5946
|
this.resize(box, evt);
|
|
5955
5947
|
}
|
|
@@ -6092,14 +6084,14 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
6092
6084
|
* @example `let rec = space.recorder(true); rec.start(); setTimeout( () => rec.stop(), 5000); // record 5s of video and download the file`
|
|
6093
6085
|
*/
|
|
6094
6086
|
recorder(downloadOrCallback, filetype = "webm", bitrate = 15e6) {
|
|
6095
|
-
|
|
6087
|
+
const stream = this._canvas.captureStream();
|
|
6096
6088
|
const recorder = new MediaRecorder(stream, { mimeType: `video/${filetype}`, bitsPerSecond: bitrate });
|
|
6097
6089
|
recorder.ondataavailable = function(d) {
|
|
6098
|
-
|
|
6090
|
+
const url = URL.createObjectURL(new Blob([d.data], { type: `video/${filetype}` }));
|
|
6099
6091
|
if (typeof downloadOrCallback === "function") {
|
|
6100
6092
|
downloadOrCallback(url);
|
|
6101
6093
|
} else if (downloadOrCallback) {
|
|
6102
|
-
|
|
6094
|
+
const a = document.createElement("a");
|
|
6103
6095
|
a.href = url;
|
|
6104
6096
|
a.download = `canvas_video.${filetype}`;
|
|
6105
6097
|
a.click();
|
|
@@ -6109,7 +6101,7 @@ var CanvasSpace2 = class extends MultiTouchSpace {
|
|
|
6109
6101
|
return recorder;
|
|
6110
6102
|
}
|
|
6111
6103
|
};
|
|
6112
|
-
var CanvasForm = class extends VisualForm {
|
|
6104
|
+
var CanvasForm = class _CanvasForm extends VisualForm {
|
|
6113
6105
|
/**
|
|
6114
6106
|
* Create a new CanvasForm. You may also use [`CanvasSpace.getForm()`](#link) to get the default form.
|
|
6115
6107
|
* @param space an instance of CanvasSpace
|
|
@@ -6186,20 +6178,20 @@ var CanvasForm = class extends VisualForm {
|
|
|
6186
6178
|
}
|
|
6187
6179
|
}
|
|
6188
6180
|
/**
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6181
|
+
* Set current alpha value.
|
|
6182
|
+
* @example `form.alpha(0.6)`
|
|
6183
|
+
* @param a alpha value between 0 and 1
|
|
6184
|
+
*/
|
|
6193
6185
|
alpha(a) {
|
|
6194
6186
|
this._ctx.globalAlpha = a;
|
|
6195
6187
|
this._style.globalAlpha = a;
|
|
6196
6188
|
return this;
|
|
6197
6189
|
}
|
|
6198
6190
|
/**
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6191
|
+
* Set current fill style. Provide a valid color string such as `"#FFF"` or `"rgba(255,0,100,0.5)"` or `false` to specify no fill color.
|
|
6192
|
+
* @example `form.fill("#F90")`, `form.fill("rgba(0,0,0,.5")`, `form.fill(false)`
|
|
6193
|
+
* @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))
|
|
6194
|
+
*/
|
|
6203
6195
|
fill(c) {
|
|
6204
6196
|
if (typeof c == "boolean") {
|
|
6205
6197
|
this.filled = c;
|
|
@@ -6211,21 +6203,21 @@ var CanvasForm = class extends VisualForm {
|
|
|
6211
6203
|
return this;
|
|
6212
6204
|
}
|
|
6213
6205
|
/**
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6206
|
+
* Set current fill style and remove stroke style.
|
|
6207
|
+
* @param c fill color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle))
|
|
6208
|
+
*/
|
|
6217
6209
|
fillOnly(c) {
|
|
6218
6210
|
this.stroke(false);
|
|
6219
6211
|
return this.fill(c);
|
|
6220
6212
|
}
|
|
6221
6213
|
/**
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6214
|
+
* Set current stroke style. Provide a valid color string or `false` to specify no stroke color.
|
|
6215
|
+
* @example `form.stroke("#F90")`, `form.stroke("rgba(0,0,0,.5")`, `form.stroke(false)`, `form.stroke("#000", 0.5, 'round', 'square')`
|
|
6216
|
+
* @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))
|
|
6217
|
+
* @param width Optional value (can be floating point) to set line width
|
|
6218
|
+
* @param linejoin Optional string to set line joint style. Can be "miter", "bevel", or "round".
|
|
6219
|
+
* @param linecap Optional string to set line cap style. Can be "butt", "round", or "square".
|
|
6220
|
+
*/
|
|
6229
6221
|
stroke(c, width, linejoin, linecap) {
|
|
6230
6222
|
if (typeof c == "boolean") {
|
|
6231
6223
|
this.stroked = c;
|
|
@@ -6249,24 +6241,24 @@ var CanvasForm = class extends VisualForm {
|
|
|
6249
6241
|
return this;
|
|
6250
6242
|
}
|
|
6251
6243
|
/**
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6244
|
+
* Set stroke style and remove fill style.
|
|
6245
|
+
* @param c stroke color which can be as color, gradient, or pattern. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle))
|
|
6246
|
+
* @param width Optional value (can be floating point) to set line width
|
|
6247
|
+
* @param linejoin Optional string to set line joint style. Can be "miter", "bevel", or "round".
|
|
6248
|
+
* @param linecap Optional string to set line cap style. Can be "butt", "round", or "square".
|
|
6249
|
+
*/
|
|
6258
6250
|
strokeOnly(c, width, linejoin, linecap) {
|
|
6259
6251
|
this.fill(false);
|
|
6260
6252
|
return this.stroke(c, width, linejoin, linecap);
|
|
6261
6253
|
}
|
|
6262
6254
|
/**
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6255
|
+
* A convenient function to apply fill and/or stroke after custom drawings using canvas context (eg, `form.ctx.ellipse(...)`).
|
|
6256
|
+
* You don't need to call this function if you're using Pts' drawing functions like `form.point` or `form.rect`
|
|
6257
|
+
* @param filled apply fill when set to `true`
|
|
6258
|
+
* @param stroked apply stroke when set to `true`
|
|
6259
|
+
* @param strokeWidth optionally set a stroke width
|
|
6260
|
+
* @example `form.ctx.beginPath(); form.ctx.ellipse(...); form.applyFillStroke();`
|
|
6261
|
+
*/
|
|
6270
6262
|
applyFillStroke(filled = true, stroked = true, strokeWidth = 1) {
|
|
6271
6263
|
if (filled) {
|
|
6272
6264
|
if (typeof filled === "string")
|
|
@@ -6281,22 +6273,22 @@ var CanvasForm = class extends VisualForm {
|
|
|
6281
6273
|
return this;
|
|
6282
6274
|
}
|
|
6283
6275
|
/**
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6276
|
+
* This function takes an array of gradient colors, and returns a function to define the areas of the gradient fill. See demo code in [CanvasForm.gradient](https://ptsjs.org/demo/?name=canvasform.textBox).
|
|
6277
|
+
* @param stops an array of gradient stops. This can be an array of colors `["#f00", "#0f0", ...]` for evenly distributed gradient, or an array of [stop, color] like `[[0.1, "#f00"], [0.7, "#0f0"]]`
|
|
6278
|
+
* @returns a function that takes 1 or 2 `Group` as parameters. Use a single `Group` to specify a rectangular area for linear gradient, or use 2 `Groups` to specify 2 `Circles` for radial gradient.
|
|
6279
|
+
* @example `c1 = Circle.fromCenter(...); grad = form.gradient(["#f00", "#00f"]); form.fill( grad( c1, c2 ) ).circle( c1 )`
|
|
6280
|
+
*/
|
|
6289
6281
|
gradient(stops) {
|
|
6290
|
-
|
|
6282
|
+
const vals = [];
|
|
6291
6283
|
if (stops.length < 2)
|
|
6292
6284
|
stops.push([0.99, "#000"], [1, "#000"]);
|
|
6293
6285
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
6294
|
-
|
|
6295
|
-
|
|
6286
|
+
const t = typeof stops[i] === "string" ? i * (1 / (stops.length - 1)) : stops[i][0];
|
|
6287
|
+
const v = typeof stops[i] === "string" ? stops[i] : stops[i][1];
|
|
6296
6288
|
vals.push([t, v]);
|
|
6297
6289
|
}
|
|
6298
6290
|
return (area1, area2) => {
|
|
6299
|
-
|
|
6291
|
+
const grad = area2 ? this._ctx.createRadialGradient(area1[0][0], area1[0][1], Math.abs(area1[1][0]), area2[0][0], area2[0][1], Math.abs(area2[1][0])) : this._ctx.createLinearGradient(area1[0][0], area1[0][1], area1[1][0], area1[1][1]);
|
|
6300
6292
|
for (let i = 0, len = vals.length; i < len; i++) {
|
|
6301
6293
|
grad.addColorStop(vals[i][0], vals[i][1]);
|
|
6302
6294
|
}
|
|
@@ -6304,26 +6296,26 @@ var CanvasForm = class extends VisualForm {
|
|
|
6304
6296
|
};
|
|
6305
6297
|
}
|
|
6306
6298
|
/**
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6299
|
+
* Set composite operation (also known as blend mode). You can also call this function without parameters to get back to default 'source-over' mode. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) for the full list of operations you can use.
|
|
6300
|
+
* @param mode a composite operation such as 'lighten', 'multiply', 'overlay', and 'color-burn'.
|
|
6301
|
+
*/
|
|
6310
6302
|
composite(mode = "source-over") {
|
|
6311
6303
|
this._ctx.globalCompositeOperation = mode;
|
|
6312
6304
|
return this;
|
|
6313
6305
|
}
|
|
6314
6306
|
/**
|
|
6315
|
-
|
|
6316
|
-
|
|
6307
|
+
* Create a clipping mask from the current path. See [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip) for details.
|
|
6308
|
+
*/
|
|
6317
6309
|
clip() {
|
|
6318
6310
|
this._ctx.clip();
|
|
6319
6311
|
return this;
|
|
6320
6312
|
}
|
|
6321
6313
|
/**
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6314
|
+
* Activate dashed stroke and set dash style. You can customize the segments and offset.
|
|
6315
|
+
* @example `form.dash()`, `form.dash([5, 10])`, `form.dash([5, 5], 5)`, `form.dash(false)`
|
|
6316
|
+
* @param segments Dash segments. Defaults to `true` which corresponds to `[5, 5]`. Pass `false` to deactivate dashes. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash))
|
|
6317
|
+
* @param offset Dash offset. Defaults to 0. (See [canvas documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
|
|
6318
|
+
*/
|
|
6327
6319
|
dash(segments = true, offset = 0) {
|
|
6328
6320
|
if (!segments) {
|
|
6329
6321
|
this._ctx.setLineDash([]);
|
|
@@ -6338,14 +6330,14 @@ var CanvasForm = class extends VisualForm {
|
|
|
6338
6330
|
return this;
|
|
6339
6331
|
}
|
|
6340
6332
|
/**
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6333
|
+
* Set the current font.
|
|
6334
|
+
* @param sizeOrFont either a number to specify font-size, or a `Font` object to specify all font properties
|
|
6335
|
+
* @param weight Optional font-weight string such as "bold"
|
|
6336
|
+
* @param style Optional font-style string such as "italic"
|
|
6337
|
+
* @param lineHeight Optional line-height number suchas 1.5
|
|
6338
|
+
* @param family Optional font-family such as "Helvetica, sans-serif"
|
|
6339
|
+
* @example `form.font( myFont )`, `form.font(14, "bold")`
|
|
6340
|
+
*/
|
|
6349
6341
|
font(sizeOrFont, weight, style, lineHeight, family) {
|
|
6350
6342
|
if (typeof sizeOrFont == "number") {
|
|
6351
6343
|
this._font.size = sizeOrFont;
|
|
@@ -6366,49 +6358,49 @@ var CanvasForm = class extends VisualForm {
|
|
|
6366
6358
|
return this;
|
|
6367
6359
|
}
|
|
6368
6360
|
/**
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6361
|
+
* Set whether to use html canvas' [`measureText`](#link) function, or a faster but less accurate heuristic function.
|
|
6362
|
+
* @param estimate `true` to use heuristic function, or `false` to use ctx.measureText
|
|
6363
|
+
*/
|
|
6372
6364
|
fontWidthEstimate(estimate = true) {
|
|
6373
6365
|
this._estimateTextWidth = estimate ? Typography.textWidthEstimator((c) => this._ctx.measureText(c).width) : void 0;
|
|
6374
6366
|
return this;
|
|
6375
6367
|
}
|
|
6376
6368
|
/**
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6369
|
+
* Get the width of this text. It will return an actual measurement or an estimate based on [`fontWidthEstimate`](#link) setting. Default is an actual measurement using canvas context's measureText.
|
|
6370
|
+
* @param c a string of text contents
|
|
6371
|
+
*/
|
|
6380
6372
|
getTextWidth(c) {
|
|
6381
6373
|
return !this._estimateTextWidth ? this._ctx.measureText(c + " .").width : this._estimateTextWidth(c);
|
|
6382
6374
|
}
|
|
6383
6375
|
/**
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6376
|
+
* Truncate text to fit width.
|
|
6377
|
+
* @param str text to truncate
|
|
6378
|
+
* @param width width to fit
|
|
6379
|
+
* @param tail text to indicate overflow such as "...". Default is empty "".
|
|
6380
|
+
*/
|
|
6389
6381
|
_textTruncate(str, width, tail = "") {
|
|
6390
6382
|
return Typography.truncate(this.getTextWidth.bind(this), str, width, tail);
|
|
6391
6383
|
}
|
|
6392
6384
|
/**
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6397
|
-
|
|
6398
|
-
|
|
6385
|
+
* Align text within a rectangle box.
|
|
6386
|
+
* @param box a Group or an Iterable<PtLike> that defines a rectangular box
|
|
6387
|
+
* @param vertical a string that specifies the vertical alignment in the box: "top", "bottom", "middle", "start", "end"
|
|
6388
|
+
* @param offset Optional offset from the edge (like padding)
|
|
6389
|
+
* @param center Optional center position
|
|
6390
|
+
*/
|
|
6399
6391
|
_textAlign(box, vertical, offset, center) {
|
|
6400
|
-
|
|
6392
|
+
const _box = Util.iterToArray(box);
|
|
6401
6393
|
if (!Util.arrayCheck(_box))
|
|
6402
6394
|
return;
|
|
6403
6395
|
if (!center)
|
|
6404
6396
|
center = Rectangle.center(_box);
|
|
6405
|
-
|
|
6397
|
+
let px = _box[0][0];
|
|
6406
6398
|
if (this._ctx.textAlign == "end" || this._ctx.textAlign == "right") {
|
|
6407
6399
|
px = _box[1][0];
|
|
6408
6400
|
} else if (this._ctx.textAlign == "center" || this._ctx.textAlign == "middle") {
|
|
6409
6401
|
px = center[0];
|
|
6410
6402
|
}
|
|
6411
|
-
|
|
6403
|
+
let py = center[1];
|
|
6412
6404
|
if (vertical == "top" || vertical == "start") {
|
|
6413
6405
|
py = _box[0][1];
|
|
6414
6406
|
} else if (vertical == "end" || vertical == "bottom") {
|
|
@@ -6417,10 +6409,10 @@ var CanvasForm = class extends VisualForm {
|
|
|
6417
6409
|
return offset ? new Pt(px + offset[0], py + offset[1]) : new Pt(px, py);
|
|
6418
6410
|
}
|
|
6419
6411
|
/**
|
|
6420
|
-
|
|
6421
|
-
|
|
6412
|
+
* Reset the rendering context's common styles to this form's styles. This supports using multiple forms on the same canvas context.
|
|
6413
|
+
*/
|
|
6422
6414
|
reset() {
|
|
6423
|
-
for (
|
|
6415
|
+
for (const k in this._style) {
|
|
6424
6416
|
if (this._style.hasOwnProperty(k)) {
|
|
6425
6417
|
this._ctx[k] = this._style[k];
|
|
6426
6418
|
}
|
|
@@ -6436,38 +6428,38 @@ var CanvasForm = class extends VisualForm {
|
|
|
6436
6428
|
this._ctx.stroke();
|
|
6437
6429
|
}
|
|
6438
6430
|
/**
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6431
|
+
* A static function to draw a point.
|
|
6432
|
+
* @param ctx canvas rendering context
|
|
6433
|
+
* @param p a Pt object
|
|
6434
|
+
* @param radius radius of the point. Default is 5.
|
|
6435
|
+
* @param shape The shape of the point. Defaults to "square", but it can be "circle" or a custom shape function in your own implementation.
|
|
6436
|
+
* @example `form.point( p )`, `form.point( p, 10, "circle" )`
|
|
6437
|
+
*/
|
|
6446
6438
|
static point(ctx, p, radius = 5, shape = "square") {
|
|
6447
6439
|
if (!p)
|
|
6448
6440
|
return;
|
|
6449
|
-
if (!
|
|
6441
|
+
if (!_CanvasForm[shape])
|
|
6450
6442
|
throw new Error(`${shape} is not a static function of CanvasForm`);
|
|
6451
|
-
|
|
6443
|
+
_CanvasForm[shape](ctx, p, radius);
|
|
6452
6444
|
}
|
|
6453
6445
|
/**
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6446
|
+
* Draws a point.
|
|
6447
|
+
* @param p a Pt object
|
|
6448
|
+
* @param radius radius of the point. Default is 5.
|
|
6449
|
+
* @param shape The shape of the point. Defaults to "square", but it can be "circle" or a custom shape function in your own implementation.
|
|
6450
|
+
* @example `form.point( p )`, `form.point( p, 10, "circle" )`
|
|
6451
|
+
*/
|
|
6460
6452
|
point(p, radius = 5, shape = "square") {
|
|
6461
|
-
|
|
6453
|
+
_CanvasForm.point(this._ctx, p, radius, shape);
|
|
6462
6454
|
this._paint();
|
|
6463
6455
|
return this;
|
|
6464
6456
|
}
|
|
6465
6457
|
/**
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6458
|
+
* A static function to draw a circle.
|
|
6459
|
+
* @param ctx canvas rendering context
|
|
6460
|
+
* @param pt center position of the circle
|
|
6461
|
+
* @param radius radius of the circle
|
|
6462
|
+
*/
|
|
6471
6463
|
static circle(ctx, pt, radius = 10) {
|
|
6472
6464
|
if (!pt)
|
|
6473
6465
|
return;
|
|
@@ -6476,25 +6468,25 @@ var CanvasForm = class extends VisualForm {
|
|
|
6476
6468
|
ctx.closePath();
|
|
6477
6469
|
}
|
|
6478
6470
|
/**
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6471
|
+
* Draw a circle. See also [`Circle.fromCenter`](#link)
|
|
6472
|
+
* @param pts usually a Group or an Iterable<PtLike> with 2 Pt, but it can also take an array of two numeric arrays [ [position], [size] ]
|
|
6473
|
+
*/
|
|
6482
6474
|
circle(pts) {
|
|
6483
|
-
|
|
6484
|
-
|
|
6475
|
+
const p = Util.iterToArray(pts);
|
|
6476
|
+
_CanvasForm.circle(this._ctx, p[0], p[1][0]);
|
|
6485
6477
|
this._paint();
|
|
6486
6478
|
return this;
|
|
6487
6479
|
}
|
|
6488
6480
|
/**
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6481
|
+
* A static function to draw an ellipse.
|
|
6482
|
+
* @param ctx canvas rendering context
|
|
6483
|
+
* @param pt center position
|
|
6484
|
+
* @param radius radius [x, y] of the ellipse
|
|
6485
|
+
* @param rotation rotation of the ellipse in radian. Default is 0.
|
|
6486
|
+
* @param startAngle start angle of the ellipse. Default is 0.
|
|
6487
|
+
* @param endAngle end angle of the ellipse. Default is 2 PI.
|
|
6488
|
+
* @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
|
|
6489
|
+
*/
|
|
6498
6490
|
static ellipse(ctx, pt, radius, rotation = 0, startAngle = 0, endAngle = Const.two_pi, cc = false) {
|
|
6499
6491
|
if (!pt || !radius)
|
|
6500
6492
|
return;
|
|
@@ -6502,28 +6494,28 @@ var CanvasForm = class extends VisualForm {
|
|
|
6502
6494
|
ctx.ellipse(pt[0], pt[1], radius[0], radius[1], rotation, startAngle, endAngle, cc);
|
|
6503
6495
|
}
|
|
6504
6496
|
/**
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6497
|
+
* Draw an ellipse.
|
|
6498
|
+
* @param pt center position
|
|
6499
|
+
* @param radius radius [x, y] of the ellipse
|
|
6500
|
+
* @param rotation rotation of the ellipse in radian. Default is 0.
|
|
6501
|
+
* @param startAngle start angle of the ellipse. Default is 0.
|
|
6502
|
+
* @param endAngle end angle of the ellipse. Default is 2 PI.
|
|
6503
|
+
* @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
|
|
6504
|
+
*/
|
|
6513
6505
|
ellipse(pt, radius, rotation = 0, startAngle = 0, endAngle = Const.two_pi, cc = false) {
|
|
6514
|
-
|
|
6506
|
+
_CanvasForm.ellipse(this._ctx, pt, radius, rotation, startAngle, endAngle, cc);
|
|
6515
6507
|
this._paint();
|
|
6516
6508
|
return this;
|
|
6517
6509
|
}
|
|
6518
6510
|
/**
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6511
|
+
* A static function to draw an arc.
|
|
6512
|
+
* @param ctx canvas rendering context
|
|
6513
|
+
* @param pt center position
|
|
6514
|
+
* @param radius radius of the arc circle
|
|
6515
|
+
* @param startAngle start angle of the arc
|
|
6516
|
+
* @param endAngle end angle of the arc
|
|
6517
|
+
* @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
|
|
6518
|
+
*/
|
|
6527
6519
|
static arc(ctx, pt, radius, startAngle, endAngle, cc) {
|
|
6528
6520
|
if (!pt)
|
|
6529
6521
|
return;
|
|
@@ -6531,31 +6523,31 @@ var CanvasForm = class extends VisualForm {
|
|
|
6531
6523
|
ctx.arc(pt[0], pt[1], radius, startAngle, endAngle, cc);
|
|
6532
6524
|
}
|
|
6533
6525
|
/**
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6526
|
+
* Draw an arc.
|
|
6527
|
+
* @param pt center position
|
|
6528
|
+
* @param radius radius of the arc circle
|
|
6529
|
+
* @param startAngle start angle of the arc
|
|
6530
|
+
* @param endAngle end angle of the arc
|
|
6531
|
+
* @param cc an optional boolean value to specify if it should be drawn clockwise (`false`) or counter-clockwise (`true`). Default is clockwise.
|
|
6532
|
+
*/
|
|
6541
6533
|
arc(pt, radius, startAngle, endAngle, cc) {
|
|
6542
|
-
|
|
6534
|
+
_CanvasForm.arc(this._ctx, pt, radius, startAngle, endAngle, cc);
|
|
6543
6535
|
this._paint();
|
|
6544
6536
|
return this;
|
|
6545
6537
|
}
|
|
6546
6538
|
/**
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6539
|
+
* A static function to draw a square.
|
|
6540
|
+
* @param ctx canvas rendering context
|
|
6541
|
+
* @param pt center position of the square
|
|
6542
|
+
* @param halfsize half size of the square
|
|
6543
|
+
*/
|
|
6552
6544
|
static square(ctx, pt, halfsize) {
|
|
6553
6545
|
if (!pt)
|
|
6554
6546
|
return;
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6547
|
+
const x1 = pt[0] - halfsize;
|
|
6548
|
+
const y1 = pt[1] - halfsize;
|
|
6549
|
+
const x2 = pt[0] + halfsize;
|
|
6550
|
+
const y2 = pt[1] + halfsize;
|
|
6559
6551
|
ctx.beginPath();
|
|
6560
6552
|
ctx.moveTo(x1, y1);
|
|
6561
6553
|
ctx.lineTo(x1, y2);
|
|
@@ -6564,26 +6556,26 @@ var CanvasForm = class extends VisualForm {
|
|
|
6564
6556
|
ctx.closePath();
|
|
6565
6557
|
}
|
|
6566
6558
|
/**
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6559
|
+
* Draw a square, given a center and its half-size.
|
|
6560
|
+
* @param pt center Pt
|
|
6561
|
+
* @param halfsize half-size
|
|
6562
|
+
*/
|
|
6571
6563
|
square(pt, halfsize) {
|
|
6572
|
-
|
|
6564
|
+
_CanvasForm.square(this._ctx, pt, halfsize);
|
|
6573
6565
|
this._paint();
|
|
6574
6566
|
return this;
|
|
6575
6567
|
}
|
|
6576
6568
|
/**
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6569
|
+
* A static function to draw a line or polyline.
|
|
6570
|
+
* @param ctx canvas rendering context
|
|
6571
|
+
* @param pts a Group or an Iterable<PtLike> representing a line
|
|
6572
|
+
*/
|
|
6581
6573
|
static line(ctx, pts) {
|
|
6582
6574
|
if (!Util.arrayCheck(pts))
|
|
6583
6575
|
return;
|
|
6584
6576
|
let i = 0;
|
|
6585
6577
|
ctx.beginPath();
|
|
6586
|
-
for (
|
|
6578
|
+
for (const it of pts) {
|
|
6587
6579
|
if (it) {
|
|
6588
6580
|
if (i++ > 0) {
|
|
6589
6581
|
ctx.lineTo(it[0], it[1]);
|
|
@@ -6594,41 +6586,41 @@ var CanvasForm = class extends VisualForm {
|
|
|
6594
6586
|
}
|
|
6595
6587
|
}
|
|
6596
6588
|
/**
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6589
|
+
* Draw a line or polyline.
|
|
6590
|
+
* @param pts a Group or an Iterable<PtLike> representing a line
|
|
6591
|
+
*/
|
|
6600
6592
|
line(pts) {
|
|
6601
|
-
|
|
6593
|
+
_CanvasForm.line(this._ctx, pts);
|
|
6602
6594
|
this._paint();
|
|
6603
6595
|
return this;
|
|
6604
6596
|
}
|
|
6605
6597
|
/**
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6598
|
+
* A static function to draw a polygon.
|
|
6599
|
+
* @param ctx canvas rendering context
|
|
6600
|
+
* @param pts a Group or an Iterable<PtLike> representing a polygon
|
|
6601
|
+
*/
|
|
6610
6602
|
static polygon(ctx, pts) {
|
|
6611
6603
|
if (!Util.arrayCheck(pts))
|
|
6612
6604
|
return;
|
|
6613
|
-
|
|
6605
|
+
_CanvasForm.line(ctx, pts);
|
|
6614
6606
|
ctx.closePath();
|
|
6615
6607
|
}
|
|
6616
6608
|
/**
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6609
|
+
* Draw a polygon.
|
|
6610
|
+
* @param pts a Group or an Iterable<PtLike> representingg a polygon
|
|
6611
|
+
*/
|
|
6620
6612
|
polygon(pts) {
|
|
6621
|
-
|
|
6613
|
+
_CanvasForm.polygon(this._ctx, pts);
|
|
6622
6614
|
this._paint();
|
|
6623
6615
|
return this;
|
|
6624
6616
|
}
|
|
6625
6617
|
/**
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6618
|
+
* A static function to draw a rectangle.
|
|
6619
|
+
* @param ctx canvas rendering context
|
|
6620
|
+
* @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.
|
|
6621
|
+
*/
|
|
6630
6622
|
static rect(ctx, pts) {
|
|
6631
|
-
|
|
6623
|
+
const p = Util.iterToArray(pts);
|
|
6632
6624
|
if (!Util.arrayCheck(p))
|
|
6633
6625
|
return;
|
|
6634
6626
|
ctx.beginPath();
|
|
@@ -6639,29 +6631,29 @@ var CanvasForm = class extends VisualForm {
|
|
|
6639
6631
|
ctx.closePath();
|
|
6640
6632
|
}
|
|
6641
6633
|
/**
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
|
|
6634
|
+
* Draw a rectangle.
|
|
6635
|
+
* @param pts a Group or an Iterable<PtLike> with 2 Pt specifying the top-left and bottom-right positions.
|
|
6636
|
+
*/
|
|
6645
6637
|
rect(pts) {
|
|
6646
|
-
|
|
6638
|
+
_CanvasForm.rect(this._ctx, pts);
|
|
6647
6639
|
this._paint();
|
|
6648
6640
|
return this;
|
|
6649
6641
|
}
|
|
6650
6642
|
/**
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6643
|
+
* A static function to draw an image.
|
|
6644
|
+
* @param ctx canvas rendering context
|
|
6645
|
+
* @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)
|
|
6646
|
+
* @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
|
|
6647
|
+
* @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a cropping box in the original target.
|
|
6648
|
+
*/
|
|
6657
6649
|
static image(ctx, ptOrRect, img, orig) {
|
|
6658
|
-
|
|
6650
|
+
const t = Util.iterToArray(ptOrRect);
|
|
6659
6651
|
let pos;
|
|
6660
6652
|
if (typeof t[0] === "number") {
|
|
6661
6653
|
pos = t;
|
|
6662
6654
|
} else {
|
|
6663
6655
|
if (orig) {
|
|
6664
|
-
|
|
6656
|
+
const o = Util.iterToArray(orig);
|
|
6665
6657
|
pos = [
|
|
6666
6658
|
o[0][0],
|
|
6667
6659
|
o[0][1],
|
|
@@ -6685,29 +6677,29 @@ var CanvasForm = class extends VisualForm {
|
|
|
6685
6677
|
}
|
|
6686
6678
|
}
|
|
6687
6679
|
/**
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6680
|
+
* Draw an image.
|
|
6681
|
+
* @param img either an [Img](#link) instance or an [`CanvasImageSource`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasImageSource) instance (eg the image from `<img>`, `<video>` or `<canvas>`)
|
|
6682
|
+
* @param ptOrRect a target area to place the image. Either a PtLike specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a bounding box. Default is (0,0) at top-left.
|
|
6683
|
+
* @param orig optionally a Group or an Iterable<PtLike> with 2 Pt (top-left position, bottom-right position) that specifies a cropping box in the original target.
|
|
6684
|
+
*/
|
|
6693
6685
|
image(ptOrRect, img, orig) {
|
|
6694
6686
|
if (img instanceof Img) {
|
|
6695
6687
|
if (img.loaded) {
|
|
6696
|
-
|
|
6688
|
+
_CanvasForm.image(this._ctx, ptOrRect, img.image, orig);
|
|
6697
6689
|
}
|
|
6698
6690
|
} else {
|
|
6699
|
-
|
|
6691
|
+
_CanvasForm.image(this._ctx, ptOrRect, img, orig);
|
|
6700
6692
|
}
|
|
6701
6693
|
return this;
|
|
6702
6694
|
}
|
|
6703
6695
|
/**
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6696
|
+
* A static function to draw ImageData on canvas
|
|
6697
|
+
* @param ctx canvas rendering context
|
|
6698
|
+
* @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
|
|
6699
|
+
* @param img an ImageData object
|
|
6700
|
+
*/
|
|
6709
6701
|
static imageData(ctx, ptOrRect, img) {
|
|
6710
|
-
|
|
6702
|
+
const t = Util.iterToArray(ptOrRect);
|
|
6711
6703
|
if (typeof t[0] === "number") {
|
|
6712
6704
|
ctx.putImageData(img, t[0], t[1]);
|
|
6713
6705
|
} else {
|
|
@@ -6715,74 +6707,74 @@ var CanvasForm = class extends VisualForm {
|
|
|
6715
6707
|
}
|
|
6716
6708
|
}
|
|
6717
6709
|
/**
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6710
|
+
* Draw ImageData on canvas using ImageData
|
|
6711
|
+
* @param ptOrRect a target area to place the image. Either a Pt or numeric array specifying a position, or a Group or an Iterable<PtLike> with 2 Pt (top-left, bottom-right) that specifies a bounding box for resizing. Default is (0,0) at top-left.
|
|
6712
|
+
* @param img an ImageData object
|
|
6713
|
+
*/
|
|
6722
6714
|
imageData(ptOrRect, img) {
|
|
6723
|
-
|
|
6715
|
+
_CanvasForm.imageData(this._ctx, ptOrRect, img);
|
|
6724
6716
|
return this;
|
|
6725
6717
|
}
|
|
6726
6718
|
/**
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6719
|
+
* A static function to draw text.
|
|
6720
|
+
* @param ctx canvas rendering context
|
|
6721
|
+
* @param `pt` a Point object to specify the anchor point
|
|
6722
|
+
* @param `txt` a string of text to draw
|
|
6723
|
+
* @param `maxWidth` specify a maximum width per line
|
|
6724
|
+
*/
|
|
6733
6725
|
static text(ctx, pt, txt, maxWidth) {
|
|
6734
6726
|
if (!pt)
|
|
6735
6727
|
return;
|
|
6736
6728
|
ctx.fillText(txt, pt[0], pt[1], maxWidth);
|
|
6737
6729
|
}
|
|
6738
6730
|
/**
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6731
|
+
* Draw text on canvas.
|
|
6732
|
+
* @param `pt` a Pt or numeric array to specify the anchor point
|
|
6733
|
+
* @param `txt` text
|
|
6734
|
+
* @param `maxWidth` specify a maximum width per line
|
|
6735
|
+
*/
|
|
6744
6736
|
text(pt, txt, maxWidth) {
|
|
6745
|
-
|
|
6737
|
+
_CanvasForm.text(this._ctx, pt, txt, maxWidth);
|
|
6746
6738
|
return this;
|
|
6747
6739
|
}
|
|
6748
6740
|
/**
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6741
|
+
* Fit a single-line text in a rectangular box.
|
|
6742
|
+
* @param box a rectangle box defined by a Group or an Iterable<Pt>
|
|
6743
|
+
* @param txt string of text
|
|
6744
|
+
* @param tail text to indicate overflow such as "...". Default is empty "".
|
|
6745
|
+
* @param verticalAlign "top", "middle", or "bottom" to specify vertical alignment inside the box
|
|
6746
|
+
* @param overrideBaseline If `true`, use the corresponding baseline as verticalAlign. If `false`, use the current canvas context's textBaseline setting. Default is `true`.
|
|
6747
|
+
*/
|
|
6756
6748
|
textBox(box, txt, verticalAlign = "middle", tail = "", overrideBaseline = true) {
|
|
6757
6749
|
if (overrideBaseline)
|
|
6758
6750
|
this._ctx.textBaseline = verticalAlign;
|
|
6759
|
-
|
|
6760
|
-
|
|
6751
|
+
const size = Rectangle.size(box);
|
|
6752
|
+
const t = this._textTruncate(txt, size[0], tail);
|
|
6761
6753
|
this.text(this._textAlign(box, verticalAlign), t[0]);
|
|
6762
6754
|
return this;
|
|
6763
6755
|
}
|
|
6764
6756
|
/**
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6757
|
+
* Fit multi-line text in a rectangular box. Note that this will also set canvas context's textBaseline to "top".
|
|
6758
|
+
* @param box a Group or an Iterable<PtLike> with 2 Pt that represents a bounding box
|
|
6759
|
+
* @param txt string of text
|
|
6760
|
+
* @param lineHeight line height as a ratio of font size. Default is 1.2.
|
|
6761
|
+
* @param verticalAlign "top", "middle", or "bottom" to specify vertical alignment inside the box
|
|
6762
|
+
* @param crop a boolean to specify whether to crop text when overflowing
|
|
6763
|
+
*/
|
|
6772
6764
|
paragraphBox(box, txt, lineHeight = 1.2, verticalAlign = "top", crop = true) {
|
|
6773
|
-
|
|
6774
|
-
|
|
6765
|
+
const b = Util.iterToArray(box);
|
|
6766
|
+
const size = Rectangle.size(b);
|
|
6775
6767
|
this._ctx.textBaseline = "top";
|
|
6776
|
-
|
|
6777
|
-
|
|
6768
|
+
const lstep = this._font.size * lineHeight;
|
|
6769
|
+
const nextLine = (sub, buffer = [], cc = 0) => {
|
|
6778
6770
|
if (!sub)
|
|
6779
6771
|
return buffer;
|
|
6780
6772
|
if (crop && cc * lstep > size[1] - lstep * 2)
|
|
6781
6773
|
return buffer;
|
|
6782
6774
|
if (cc > 1e4)
|
|
6783
6775
|
throw new Error("max recursion reached (10000)");
|
|
6784
|
-
|
|
6785
|
-
|
|
6776
|
+
const t = this._textTruncate(sub, size[0], "");
|
|
6777
|
+
const newln = t[0].indexOf("\n");
|
|
6786
6778
|
if (newln >= 0) {
|
|
6787
6779
|
buffer.push(t[0].substr(0, newln));
|
|
6788
6780
|
return nextLine(sub.substr(newln + 1), buffer, cc + 1);
|
|
@@ -6790,12 +6782,12 @@ var CanvasForm = class extends VisualForm {
|
|
|
6790
6782
|
let dt = t[0].lastIndexOf(" ") + 1;
|
|
6791
6783
|
if (dt <= 0 || t[1] === sub.length)
|
|
6792
6784
|
dt = void 0;
|
|
6793
|
-
|
|
6785
|
+
const line = t[0].substr(0, dt);
|
|
6794
6786
|
buffer.push(line);
|
|
6795
6787
|
return t[1] <= 0 || t[1] === sub.length ? buffer : nextLine(sub.substr(dt || t[1]), buffer, cc + 1);
|
|
6796
6788
|
};
|
|
6797
|
-
|
|
6798
|
-
|
|
6789
|
+
const lines = nextLine(txt);
|
|
6790
|
+
const lsize = lines.length * lstep;
|
|
6799
6791
|
let lbox = b;
|
|
6800
6792
|
if (verticalAlign == "middle" || verticalAlign == "center") {
|
|
6801
6793
|
let lpad = (size[1] - lsize) / 2;
|
|
@@ -6807,17 +6799,17 @@ var CanvasForm = class extends VisualForm {
|
|
|
6807
6799
|
} else {
|
|
6808
6800
|
lbox = new Group(b[0], b[0].$add(size[0], lsize));
|
|
6809
6801
|
}
|
|
6810
|
-
|
|
6802
|
+
const center = Rectangle.center(lbox);
|
|
6811
6803
|
for (let i = 0, len = lines.length; i < len; i++) {
|
|
6812
6804
|
this.text(this._textAlign(lbox, "top", [0, i * lstep], center), lines[i]);
|
|
6813
6805
|
}
|
|
6814
6806
|
return this;
|
|
6815
6807
|
}
|
|
6816
6808
|
/**
|
|
6817
|
-
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6809
|
+
* Set text alignment and baseline (eg, vertical-align).
|
|
6810
|
+
* @param alignment HTML canvas' textAlign option: "left", "right", "center", "start", or "end"
|
|
6811
|
+
* @param baseline HTML canvas' textBaseline option: "top", "hanging", "middle", "alphabetic", "ideographic", "bottom". For convenience, you can also use "center" (same as "middle"), and "baseline" (same as "alphabetic")
|
|
6812
|
+
*/
|
|
6821
6813
|
alignText(alignment = "left", baseline = "alphabetic") {
|
|
6822
6814
|
if (baseline == "center")
|
|
6823
6815
|
baseline = "middle";
|
|
@@ -6828,11 +6820,11 @@ var CanvasForm = class extends VisualForm {
|
|
|
6828
6820
|
return this;
|
|
6829
6821
|
}
|
|
6830
6822
|
/**
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6823
|
+
* A convenient way to draw some text on canvas for logging or debugging. It'll be draw on the top-left of the canvas as an overlay.
|
|
6824
|
+
* @param txt text
|
|
6825
|
+
*/
|
|
6834
6826
|
log(txt) {
|
|
6835
|
-
|
|
6827
|
+
const w = this._ctx.measureText(txt).width + 20;
|
|
6836
6828
|
this.stroke(false).fill("rgba(0,0,0,.4)").rect([[0, 0], [w, 20]]);
|
|
6837
6829
|
this.fill("#fff").text([10, 14], txt);
|
|
6838
6830
|
return this;
|
|
@@ -7295,7 +7287,7 @@ var Noise = class extends Pt {
|
|
|
7295
7287
|
return Num.lerp(Num.lerp(n00, n10, tx), Num.lerp(n01, n11, tx), _fade(y));
|
|
7296
7288
|
}
|
|
7297
7289
|
};
|
|
7298
|
-
var Delaunay = class extends Group {
|
|
7290
|
+
var Delaunay = class _Delaunay extends Group {
|
|
7299
7291
|
constructor() {
|
|
7300
7292
|
super(...arguments);
|
|
7301
7293
|
this._mesh = [];
|
|
@@ -7342,7 +7334,7 @@ var Delaunay = class extends Group {
|
|
|
7342
7334
|
edges.push(circum.i, circum.j, circum.j, circum.k, circum.k, circum.i);
|
|
7343
7335
|
opened.splice(j, 1);
|
|
7344
7336
|
}
|
|
7345
|
-
|
|
7337
|
+
_Delaunay._dedupe(edges);
|
|
7346
7338
|
j = edges.length;
|
|
7347
7339
|
while (j > 1) {
|
|
7348
7340
|
opened.push(this._circum(edges[--j], edges[--j], c, false, pts));
|
|
@@ -7484,7 +7476,7 @@ var Delaunay = class extends Group {
|
|
|
7484
7476
|
};
|
|
7485
7477
|
|
|
7486
7478
|
// src/Color.ts
|
|
7487
|
-
var _Color = class extends Pt {
|
|
7479
|
+
var _Color = class _Color extends Pt {
|
|
7488
7480
|
/**
|
|
7489
7481
|
* Create a Color. Same as creating a Pt. Optionally you may use [`Color.from`](#link) to create a color.
|
|
7490
7482
|
* @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties
|
|
@@ -7499,8 +7491,8 @@ var _Color = class extends Pt {
|
|
|
7499
7491
|
* @param args Pt-like parameters which can be a list of numeric parameters, an array of numbers, or an object with {x,y,z,w} properties
|
|
7500
7492
|
*/
|
|
7501
7493
|
static from(...args) {
|
|
7502
|
-
|
|
7503
|
-
|
|
7494
|
+
const p = [1, 1, 1, 1];
|
|
7495
|
+
const c = Util.getArgs(args);
|
|
7504
7496
|
for (let i = 0, len = p.length; i < len; i++) {
|
|
7505
7497
|
if (i < c.length)
|
|
7506
7498
|
p[i] = c[i];
|
|
@@ -7515,7 +7507,7 @@ var _Color = class extends Pt {
|
|
|
7515
7507
|
if (hex[0] == "#")
|
|
7516
7508
|
hex = hex.substr(1);
|
|
7517
7509
|
if (hex.length <= 3) {
|
|
7518
|
-
|
|
7510
|
+
const fn = (i) => hex[i] || "F";
|
|
7519
7511
|
hex = `${fn(0)}${fn(0)}${fn(1)}${fn(1)}${fn(2)}${fn(2)}`;
|
|
7520
7512
|
}
|
|
7521
7513
|
let alpha = 1;
|
|
@@ -7523,7 +7515,7 @@ var _Color = class extends Pt {
|
|
|
7523
7515
|
alpha = hex.substr(6) && 255 / 255;
|
|
7524
7516
|
hex = hex.substring(0, 6);
|
|
7525
7517
|
}
|
|
7526
|
-
|
|
7518
|
+
const hexVal = parseInt(hex, 16);
|
|
7527
7519
|
return new _Color(hexVal >> 16, hexVal >> 8 & 255, hexVal & 255, alpha);
|
|
7528
7520
|
}
|
|
7529
7521
|
/**
|
|
@@ -7605,7 +7597,7 @@ var _Color = class extends Pt {
|
|
|
7605
7597
|
* Clone this Color.
|
|
7606
7598
|
*/
|
|
7607
7599
|
clone() {
|
|
7608
|
-
|
|
7600
|
+
const c = new _Color(this);
|
|
7609
7601
|
c.toMode(this._mode);
|
|
7610
7602
|
return c;
|
|
7611
7603
|
}
|
|
@@ -7616,7 +7608,7 @@ var _Color = class extends Pt {
|
|
|
7616
7608
|
*/
|
|
7617
7609
|
toMode(mode, convert = false) {
|
|
7618
7610
|
if (convert) {
|
|
7619
|
-
|
|
7611
|
+
const fname = this._mode.toUpperCase() + "to" + mode.toUpperCase();
|
|
7620
7612
|
if (_Color[fname]) {
|
|
7621
7613
|
this.to(_Color[fname](this, this._isNorm, this._isNorm));
|
|
7622
7614
|
} else {
|
|
@@ -7668,7 +7660,7 @@ var _Color = class extends Pt {
|
|
|
7668
7660
|
return this._mode == "lch" ? this[2] : this[0];
|
|
7669
7661
|
}
|
|
7670
7662
|
set h(n) {
|
|
7671
|
-
|
|
7663
|
+
const i = this._mode == "lch" ? 2 : 0;
|
|
7672
7664
|
this[i] = n;
|
|
7673
7665
|
}
|
|
7674
7666
|
/**
|
|
@@ -7687,7 +7679,7 @@ var _Color = class extends Pt {
|
|
|
7687
7679
|
return this._mode == "hsl" ? this[2] : this[0];
|
|
7688
7680
|
}
|
|
7689
7681
|
set l(n) {
|
|
7690
|
-
|
|
7682
|
+
const i = this._mode == "hsl" ? 2 : 0;
|
|
7691
7683
|
this[i] = n;
|
|
7692
7684
|
}
|
|
7693
7685
|
// lab, lch, luv
|
|
@@ -7753,7 +7745,7 @@ var _Color = class extends Pt {
|
|
|
7753
7745
|
normalize(toNorm = true) {
|
|
7754
7746
|
if (this._isNorm == toNorm)
|
|
7755
7747
|
return this;
|
|
7756
|
-
|
|
7748
|
+
const ranges = _Color.ranges[this._mode];
|
|
7757
7749
|
for (let i = 0; i < 3; i++) {
|
|
7758
7750
|
this[i] = !toNorm ? Num.mapToRange(this[i], 0, 1, ranges[i][0], ranges[i][1]) : Num.mapToRange(this[i], ranges[i][0], ranges[i][1], 0, 1);
|
|
7759
7751
|
}
|
|
@@ -7774,8 +7766,8 @@ var _Color = class extends Pt {
|
|
|
7774
7766
|
*/
|
|
7775
7767
|
toString(format = "mode") {
|
|
7776
7768
|
if (format == "hex") {
|
|
7777
|
-
|
|
7778
|
-
|
|
7769
|
+
const _hex = (n) => {
|
|
7770
|
+
const s = Math.floor(n).toString(16);
|
|
7779
7771
|
return s.length < 2 ? "0" + s : s;
|
|
7780
7772
|
};
|
|
7781
7773
|
return `#${_hex(this[0])}${_hex(this[1])}${_hex(this[2])}`;
|
|
@@ -7795,17 +7787,17 @@ var _Color = class extends Pt {
|
|
|
7795
7787
|
* @returns a new HSL Color
|
|
7796
7788
|
*/
|
|
7797
7789
|
static RGBtoHSL(rgb, normalizedInput = false, normalizedOutput = false) {
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7790
|
+
const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;
|
|
7791
|
+
const max = Math.max(r, g, b);
|
|
7792
|
+
const min = Math.min(r, g, b);
|
|
7801
7793
|
let h = (max + min) / 2;
|
|
7802
7794
|
let s = h;
|
|
7803
|
-
|
|
7795
|
+
const l = h;
|
|
7804
7796
|
if (max == min) {
|
|
7805
7797
|
h = 0;
|
|
7806
7798
|
s = 0;
|
|
7807
7799
|
} else {
|
|
7808
|
-
|
|
7800
|
+
const d = max - min;
|
|
7809
7801
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
7810
7802
|
h = 0;
|
|
7811
7803
|
if (max === r) {
|
|
@@ -7831,9 +7823,9 @@ var _Color = class extends Pt {
|
|
|
7831
7823
|
h = h / 360;
|
|
7832
7824
|
if (s == 0)
|
|
7833
7825
|
return _Color.rgb(l * 255, l * 255, l * 255, hsl.alpha);
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7826
|
+
const q = l <= 0.5 ? l * (1 + s) : l + s - l * s;
|
|
7827
|
+
const p = 2 * l - q;
|
|
7828
|
+
const convert = (t) => {
|
|
7837
7829
|
t = t < 0 ? t + 1 : t > 1 ? t - 1 : t;
|
|
7838
7830
|
if (t * 6 < 1) {
|
|
7839
7831
|
return p + (q - p) * t * 6;
|
|
@@ -7845,7 +7837,7 @@ var _Color = class extends Pt {
|
|
|
7845
7837
|
return p;
|
|
7846
7838
|
}
|
|
7847
7839
|
};
|
|
7848
|
-
|
|
7840
|
+
const sc = normalizedOutput ? 1 : 255;
|
|
7849
7841
|
return _Color.rgb(
|
|
7850
7842
|
sc * convert(h + 1 / 3),
|
|
7851
7843
|
sc * convert(h),
|
|
@@ -7861,13 +7853,13 @@ var _Color = class extends Pt {
|
|
|
7861
7853
|
* @returns a new HSB Color
|
|
7862
7854
|
*/
|
|
7863
7855
|
static RGBtoHSB(rgb, normalizedInput = false, normalizedOutput = false) {
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7856
|
+
const [r, g, b] = !normalizedInput ? rgb.$normalize() : rgb;
|
|
7857
|
+
const max = Math.max(r, g, b);
|
|
7858
|
+
const min = Math.min(r, g, b);
|
|
7859
|
+
const d = max - min;
|
|
7868
7860
|
let h = 0;
|
|
7869
|
-
|
|
7870
|
-
|
|
7861
|
+
const s = max === 0 ? 0 : d / max;
|
|
7862
|
+
const v = max;
|
|
7871
7863
|
if (max != min) {
|
|
7872
7864
|
if (max === r) {
|
|
7873
7865
|
h = (g - b) / d + (g < b ? 6 : 0);
|
|
@@ -7890,12 +7882,12 @@ var _Color = class extends Pt {
|
|
|
7890
7882
|
let [h, s, v] = hsb;
|
|
7891
7883
|
if (!normalizedInput)
|
|
7892
7884
|
h = h / 360;
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7885
|
+
const i = Math.floor(h * 6);
|
|
7886
|
+
const f = h * 6 - i;
|
|
7887
|
+
const p = v * (1 - s);
|
|
7888
|
+
const q = v * (1 - f * s);
|
|
7889
|
+
const t = v * (1 - (1 - f) * s);
|
|
7890
|
+
const pick = [
|
|
7899
7891
|
[v, t, p],
|
|
7900
7892
|
[q, v, p],
|
|
7901
7893
|
[p, v, t],
|
|
@@ -7903,8 +7895,8 @@ var _Color = class extends Pt {
|
|
|
7903
7895
|
[t, p, v],
|
|
7904
7896
|
[v, p, q]
|
|
7905
7897
|
];
|
|
7906
|
-
|
|
7907
|
-
|
|
7898
|
+
const c = pick[i % 6];
|
|
7899
|
+
const sc = normalizedOutput ? 1 : 255;
|
|
7908
7900
|
return _Color.rgb(
|
|
7909
7901
|
sc * c[0],
|
|
7910
7902
|
sc * c[1],
|
|
@@ -7920,7 +7912,7 @@ var _Color = class extends Pt {
|
|
|
7920
7912
|
* @returns a new LAB Color
|
|
7921
7913
|
*/
|
|
7922
7914
|
static RGBtoLAB(rgb, normalizedInput = false, normalizedOutput = false) {
|
|
7923
|
-
|
|
7915
|
+
const c = normalizedInput ? rgb.$normalize(false) : rgb;
|
|
7924
7916
|
return _Color.XYZtoLAB(_Color.RGBtoXYZ(c), false, normalizedOutput);
|
|
7925
7917
|
}
|
|
7926
7918
|
/**
|
|
@@ -7931,7 +7923,7 @@ var _Color = class extends Pt {
|
|
|
7931
7923
|
* @returns a new RGB Color
|
|
7932
7924
|
*/
|
|
7933
7925
|
static LABtoRGB(lab, normalizedInput = false, normalizedOutput = false) {
|
|
7934
|
-
|
|
7926
|
+
const c = normalizedInput ? lab.$normalize(false) : lab;
|
|
7935
7927
|
return _Color.XYZtoRGB(_Color.LABtoXYZ(c), false, normalizedOutput);
|
|
7936
7928
|
}
|
|
7937
7929
|
/**
|
|
@@ -7942,7 +7934,7 @@ var _Color = class extends Pt {
|
|
|
7942
7934
|
* @returns a new LCH Color
|
|
7943
7935
|
*/
|
|
7944
7936
|
static RGBtoLCH(rgb, normalizedInput = false, normalizedOutput = false) {
|
|
7945
|
-
|
|
7937
|
+
const c = normalizedInput ? rgb.$normalize(false) : rgb;
|
|
7946
7938
|
return _Color.LABtoLCH(_Color.RGBtoLAB(c), false, normalizedOutput);
|
|
7947
7939
|
}
|
|
7948
7940
|
/**
|
|
@@ -7953,7 +7945,7 @@ var _Color = class extends Pt {
|
|
|
7953
7945
|
* @returns a new RGB Color
|
|
7954
7946
|
*/
|
|
7955
7947
|
static LCHtoRGB(lch, normalizedInput = false, normalizedOutput = false) {
|
|
7956
|
-
|
|
7948
|
+
const c = normalizedInput ? lch.$normalize(false) : lch;
|
|
7957
7949
|
return _Color.LABtoRGB(_Color.LCHtoLAB(c), false, normalizedOutput);
|
|
7958
7950
|
}
|
|
7959
7951
|
/**
|
|
@@ -7964,7 +7956,7 @@ var _Color = class extends Pt {
|
|
|
7964
7956
|
* @returns a new LUV Color
|
|
7965
7957
|
*/
|
|
7966
7958
|
static RGBtoLUV(rgb, normalizedInput = false, normalizedOutput = false) {
|
|
7967
|
-
|
|
7959
|
+
const c = normalizedInput ? rgb.$normalize(false) : rgb;
|
|
7968
7960
|
return _Color.XYZtoLUV(_Color.RGBtoXYZ(c), false, normalizedOutput);
|
|
7969
7961
|
}
|
|
7970
7962
|
/**
|
|
@@ -7975,7 +7967,7 @@ var _Color = class extends Pt {
|
|
|
7975
7967
|
* @returns a new RGB Color
|
|
7976
7968
|
*/
|
|
7977
7969
|
static LUVtoRGB(luv, normalizedInput = false, normalizedOutput = false) {
|
|
7978
|
-
|
|
7970
|
+
const c = normalizedInput ? luv.$normalize(false) : luv;
|
|
7979
7971
|
return _Color.XYZtoRGB(_Color.LUVtoXYZ(c), false, normalizedOutput);
|
|
7980
7972
|
}
|
|
7981
7973
|
/**
|
|
@@ -7986,13 +7978,13 @@ var _Color = class extends Pt {
|
|
|
7986
7978
|
* @returns a new XYZ Color
|
|
7987
7979
|
*/
|
|
7988
7980
|
static RGBtoXYZ(rgb, normalizedInput = false, normalizedOutput = false) {
|
|
7989
|
-
|
|
7981
|
+
const c = !normalizedInput ? rgb.$normalize() : rgb.clone();
|
|
7990
7982
|
for (let i = 0; i < 3; i++) {
|
|
7991
7983
|
c[i] = c[i] > 0.04045 ? Math.pow((c[i] + 0.055) / 1.055, 2.4) : c[i] / 12.92;
|
|
7992
7984
|
if (!normalizedOutput)
|
|
7993
7985
|
c[i] = c[i] * 100;
|
|
7994
7986
|
}
|
|
7995
|
-
|
|
7987
|
+
const cc = _Color.xyz(
|
|
7996
7988
|
c[0] * 0.4124564 + c[1] * 0.3575761 + c[2] * 0.1804375,
|
|
7997
7989
|
c[0] * 0.2126729 + c[1] * 0.7151522 + c[2] * 0.072175,
|
|
7998
7990
|
c[0] * 0.0193339 + c[1] * 0.119192 + c[2] * 0.9503041,
|
|
@@ -8008,8 +8000,8 @@ var _Color = class extends Pt {
|
|
|
8008
8000
|
* @returns a new RGB Color
|
|
8009
8001
|
*/
|
|
8010
8002
|
static XYZtoRGB(xyz, normalizedInput = false, normalizedOutput = false) {
|
|
8011
|
-
|
|
8012
|
-
|
|
8003
|
+
const [x, y, z] = !normalizedInput ? xyz.$normalize() : xyz;
|
|
8004
|
+
const rgb = [
|
|
8013
8005
|
x * 3.2406254773200533 + y * -1.5372079722103187 + z * -0.4986285986982479,
|
|
8014
8006
|
x * -0.9689307147293197 + y * 1.8757560608852415 + z * 0.041517523842953964,
|
|
8015
8007
|
x * 0.055710120445510616 + y * -0.2040210505984867 + z * 1.0569959422543882
|
|
@@ -8020,7 +8012,7 @@ var _Color = class extends Pt {
|
|
|
8020
8012
|
if (!normalizedOutput)
|
|
8021
8013
|
rgb[i] = Math.round(rgb[i] * 255);
|
|
8022
8014
|
}
|
|
8023
|
-
|
|
8015
|
+
const cc = _Color.rgb(rgb[0], rgb[1], rgb[2], xyz.alpha);
|
|
8024
8016
|
return normalizedOutput ? cc.normalize() : cc;
|
|
8025
8017
|
}
|
|
8026
8018
|
/**
|
|
@@ -8031,13 +8023,13 @@ var _Color = class extends Pt {
|
|
|
8031
8023
|
* @returns a new LAB Color
|
|
8032
8024
|
*/
|
|
8033
8025
|
static XYZtoLAB(xyz, normalizedInput = false, normalizedOutput = false) {
|
|
8034
|
-
|
|
8026
|
+
const c = normalizedInput ? xyz.$normalize(false) : xyz.clone();
|
|
8035
8027
|
const eps = 0.00885645167;
|
|
8036
8028
|
const kap = 903.296296296;
|
|
8037
8029
|
c.divide(_Color.D65);
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8030
|
+
const fn = (n) => n > eps ? Math.pow(n, 1 / 3) : (kap * n + 16) / 116;
|
|
8031
|
+
const cy = fn(c[1]);
|
|
8032
|
+
const cc = _Color.lab(
|
|
8041
8033
|
116 * cy - 16,
|
|
8042
8034
|
500 * (fn(c[0]) - cy),
|
|
8043
8035
|
200 * (cy - fn(c[2])),
|
|
@@ -8053,16 +8045,16 @@ var _Color = class extends Pt {
|
|
|
8053
8045
|
* @returns a new XYZ Color
|
|
8054
8046
|
*/
|
|
8055
8047
|
static LABtoXYZ(lab, normalizedInput = false, normalizedOutput = false) {
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8048
|
+
const c = normalizedInput ? lab.$normalize(false) : lab;
|
|
8049
|
+
const y = (c[0] + 16) / 116;
|
|
8050
|
+
const x = c[1] / 500 + y;
|
|
8051
|
+
const z = y - c[2] / 200;
|
|
8060
8052
|
const eps = 0.00885645167;
|
|
8061
8053
|
const kap = 903.296296296;
|
|
8062
|
-
|
|
8054
|
+
const d = _Color.D65;
|
|
8063
8055
|
const xxx = Math.pow(x, 3);
|
|
8064
8056
|
const zzz = Math.pow(z, 3);
|
|
8065
|
-
|
|
8057
|
+
const cc = _Color.xyz(
|
|
8066
8058
|
d[0] * (xxx > eps ? xxx : (116 * x - 16) / kap),
|
|
8067
8059
|
d[1] * (c[0] > kap * eps ? Math.pow((c[0] + 16) / 116, 3) : c[0] / kap),
|
|
8068
8060
|
d[2] * (zzz > eps ? zzz : (116 * z - 16) / kap),
|
|
@@ -8079,13 +8071,13 @@ var _Color = class extends Pt {
|
|
|
8079
8071
|
*/
|
|
8080
8072
|
static XYZtoLUV(xyz, normalizedInput = false, normalizedOutput = false) {
|
|
8081
8073
|
let [x, y, z] = normalizedInput ? xyz.$normalize(false) : xyz;
|
|
8082
|
-
|
|
8083
|
-
|
|
8074
|
+
const u = 4 * x / (x + 15 * y + 3 * z);
|
|
8075
|
+
const v = 9 * y / (x + 15 * y + 3 * z);
|
|
8084
8076
|
y = y / 100;
|
|
8085
8077
|
y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8078
|
+
const refU = 4 * _Color.D65[0] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
|
|
8079
|
+
const refV = 9 * _Color.D65[1] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
|
|
8080
|
+
const L = 116 * y - 16;
|
|
8089
8081
|
return _Color.luv(
|
|
8090
8082
|
L,
|
|
8091
8083
|
13 * L * (u - refU),
|
|
@@ -8103,15 +8095,15 @@ var _Color = class extends Pt {
|
|
|
8103
8095
|
static LUVtoXYZ(luv, normalizedInput = false, normalizedOutput = false) {
|
|
8104
8096
|
let [l, u, v] = normalizedInput ? luv.$normalize(false) : luv;
|
|
8105
8097
|
let y = (l + 16) / 116;
|
|
8106
|
-
|
|
8098
|
+
const cubeY = y * y * y;
|
|
8107
8099
|
y = cubeY > 8856e-6 ? cubeY : (y - 16 / 116) / 7.787;
|
|
8108
|
-
|
|
8109
|
-
|
|
8100
|
+
const refU = 4 * _Color.D65[0] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
|
|
8101
|
+
const refV = 9 * _Color.D65[1] / (_Color.D65[0] + 15 * _Color.D65[1] + 3 * _Color.D65[2]);
|
|
8110
8102
|
u = u / (13 * l) + refU;
|
|
8111
8103
|
v = v / (13 * l) + refV;
|
|
8112
8104
|
y = y * 100;
|
|
8113
|
-
|
|
8114
|
-
|
|
8105
|
+
const x = -1 * (9 * y * u) / ((u - 4) * v - u * v);
|
|
8106
|
+
const z = (9 * y - 15 * v * y - v * x) / (3 * v);
|
|
8115
8107
|
return _Color.xyz(x, y, z, luv.alpha);
|
|
8116
8108
|
}
|
|
8117
8109
|
/**
|
|
@@ -8122,8 +8114,8 @@ var _Color = class extends Pt {
|
|
|
8122
8114
|
* @returns a new LCH Color
|
|
8123
8115
|
*/
|
|
8124
8116
|
static LABtoLCH(lab, normalizedInput = false, normalizedOutput = false) {
|
|
8125
|
-
|
|
8126
|
-
|
|
8117
|
+
const c = normalizedInput ? lab.$normalize(false) : lab;
|
|
8118
|
+
const h = Geom.toDegree(Geom.boundRadian(Math.atan2(c[2], c[1])));
|
|
8127
8119
|
return _Color.lch(
|
|
8128
8120
|
c[0],
|
|
8129
8121
|
Math.sqrt(c[1] * c[1] + c[2] * c[2]),
|
|
@@ -8139,8 +8131,8 @@ var _Color = class extends Pt {
|
|
|
8139
8131
|
* @returns a new LAB Color
|
|
8140
8132
|
*/
|
|
8141
8133
|
static LCHtoLAB(lch, normalizedInput = false, normalizedOutput = false) {
|
|
8142
|
-
|
|
8143
|
-
|
|
8134
|
+
const c = normalizedInput ? lch.$normalize(false) : lch;
|
|
8135
|
+
const rad = Geom.toRadian(c[2]);
|
|
8144
8136
|
return _Color.lab(
|
|
8145
8137
|
c[0],
|
|
8146
8138
|
Math.cos(rad) * c[1],
|
|
@@ -8149,13 +8141,12 @@ var _Color = class extends Pt {
|
|
|
8149
8141
|
);
|
|
8150
8142
|
}
|
|
8151
8143
|
};
|
|
8152
|
-
var Color = _Color;
|
|
8153
8144
|
// XYZ property for Standard Observer 2deg, Daylight/sRGB illuminant D65
|
|
8154
|
-
|
|
8145
|
+
_Color.D65 = new Pt(95.047, 100, 108.883, 1);
|
|
8155
8146
|
/**
|
|
8156
8147
|
* Value range for each color space
|
|
8157
8148
|
*/
|
|
8158
|
-
|
|
8149
|
+
_Color.ranges = {
|
|
8159
8150
|
rgb: new Group(new Pt(0, 255), new Pt(0, 255), new Pt(0, 255)),
|
|
8160
8151
|
hsl: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),
|
|
8161
8152
|
hsb: new Group(new Pt(0, 360), new Pt(0, 1), new Pt(0, 1)),
|
|
@@ -8164,9 +8155,10 @@ Color.ranges = {
|
|
|
8164
8155
|
luv: new Group(new Pt(0, 100), new Pt(-134, 220), new Pt(-140, 122)),
|
|
8165
8156
|
xyz: new Group(new Pt(0, 100), new Pt(0, 100), new Pt(0, 100))
|
|
8166
8157
|
};
|
|
8158
|
+
var Color = _Color;
|
|
8167
8159
|
|
|
8168
8160
|
// src/Dom.ts
|
|
8169
|
-
var DOMSpace = class extends MultiTouchSpace {
|
|
8161
|
+
var DOMSpace = class _DOMSpace extends MultiTouchSpace {
|
|
8170
8162
|
/**
|
|
8171
8163
|
* Create a DOMSpace for HTML DOM elements
|
|
8172
8164
|
* @param elem Specify an element by its "id" attribute as string, or by the element object itself. Use css to customize its appearance if needed.
|
|
@@ -8179,8 +8171,8 @@ var DOMSpace = class extends MultiTouchSpace {
|
|
|
8179
8171
|
this._autoResize = true;
|
|
8180
8172
|
this._bgcolor = "#e1e9f0";
|
|
8181
8173
|
this._css = {};
|
|
8182
|
-
|
|
8183
|
-
|
|
8174
|
+
let _selector = null;
|
|
8175
|
+
let _existed = false;
|
|
8184
8176
|
this.id = "pts";
|
|
8185
8177
|
if (elem instanceof Element) {
|
|
8186
8178
|
_selector = elem;
|
|
@@ -8191,8 +8183,8 @@ var DOMSpace = class extends MultiTouchSpace {
|
|
|
8191
8183
|
this.id = elem.substr(1);
|
|
8192
8184
|
}
|
|
8193
8185
|
if (!_selector) {
|
|
8194
|
-
this._container =
|
|
8195
|
-
this._canvas =
|
|
8186
|
+
this._container = _DOMSpace.createElement("div", "pts_container");
|
|
8187
|
+
this._canvas = _DOMSpace.createElement("div", "pts_element");
|
|
8196
8188
|
this._container.appendChild(this._canvas);
|
|
8197
8189
|
document.body.appendChild(this._container);
|
|
8198
8190
|
_existed = false;
|
|
@@ -8454,7 +8446,7 @@ var HTMLSpace = class extends DOMSpace {
|
|
|
8454
8446
|
return super.removeAll();
|
|
8455
8447
|
}
|
|
8456
8448
|
};
|
|
8457
|
-
var _HTMLForm = class extends VisualForm {
|
|
8449
|
+
var _HTMLForm = class _HTMLForm extends VisualForm {
|
|
8458
8450
|
/**
|
|
8459
8451
|
* Create a new `HTMLForm`. Alternatively, you can use [`HTMLSpace.getForm`](#link) function to get an instance of HTMLForm.
|
|
8460
8452
|
* @param space the space to use
|
|
@@ -8873,12 +8865,12 @@ var _HTMLForm = class extends VisualForm {
|
|
|
8873
8865
|
return this;
|
|
8874
8866
|
}
|
|
8875
8867
|
};
|
|
8868
|
+
_HTMLForm.groupID = 0;
|
|
8869
|
+
_HTMLForm.domID = 0;
|
|
8876
8870
|
var HTMLForm = _HTMLForm;
|
|
8877
|
-
HTMLForm.groupID = 0;
|
|
8878
|
-
HTMLForm.domID = 0;
|
|
8879
8871
|
|
|
8880
8872
|
// src/Svg.ts
|
|
8881
|
-
var SVGSpace = class extends DOMSpace {
|
|
8873
|
+
var SVGSpace = class _SVGSpace extends DOMSpace {
|
|
8882
8874
|
/**
|
|
8883
8875
|
* Create a SVGSpace which represents a Space for SVG elements.
|
|
8884
8876
|
* @param elem Specify an element by its "id" attribute as string, or by the element object itself. An element can be an existing `<svg>`, or a `<div>` container in which a new `<svg>` will be created. If left empty, a `<div id="pt_container"><svg id="pt" /></div>` will be added to DOM. Use css to customize its appearance if needed.
|
|
@@ -8889,7 +8881,7 @@ var SVGSpace = class extends DOMSpace {
|
|
|
8889
8881
|
super(elem, callback);
|
|
8890
8882
|
this._bgcolor = "#999";
|
|
8891
8883
|
if (this._canvas.nodeName.toLowerCase() != "svg") {
|
|
8892
|
-
let s =
|
|
8884
|
+
let s = _SVGSpace.svgElement(this._canvas, "svg", `${this.id}_svg`);
|
|
8893
8885
|
this._container = this._canvas;
|
|
8894
8886
|
this._canvas = s;
|
|
8895
8887
|
}
|
|
@@ -8915,7 +8907,7 @@ var SVGSpace = class extends DOMSpace {
|
|
|
8915
8907
|
*/
|
|
8916
8908
|
resize(b, evt) {
|
|
8917
8909
|
super.resize(b, evt);
|
|
8918
|
-
|
|
8910
|
+
_SVGSpace.setAttr(this.element, {
|
|
8919
8911
|
"viewBox": `0 0 ${this.bound.width} ${this.bound.height}`,
|
|
8920
8912
|
"width": `${this.bound.width}`,
|
|
8921
8913
|
"height": `${this.bound.height}`,
|
|
@@ -8960,7 +8952,7 @@ var SVGSpace = class extends DOMSpace {
|
|
|
8960
8952
|
return super.removeAll();
|
|
8961
8953
|
}
|
|
8962
8954
|
};
|
|
8963
|
-
var _SVGForm = class extends VisualForm {
|
|
8955
|
+
var _SVGForm = class _SVGForm extends VisualForm {
|
|
8964
8956
|
/**
|
|
8965
8957
|
* Create a new SVGForm. You may also use [`SVGSpace.getForm`](#link) to get a default form directly.
|
|
8966
8958
|
* @param space an instance of SVGSpace
|
|
@@ -9454,12 +9446,12 @@ var _SVGForm = class extends VisualForm {
|
|
|
9454
9446
|
return this;
|
|
9455
9447
|
}
|
|
9456
9448
|
};
|
|
9449
|
+
_SVGForm.groupID = 0;
|
|
9450
|
+
_SVGForm.domID = 0;
|
|
9457
9451
|
var SVGForm = _SVGForm;
|
|
9458
|
-
SVGForm.groupID = 0;
|
|
9459
|
-
SVGForm.domID = 0;
|
|
9460
9452
|
|
|
9461
9453
|
// src/Physics.ts
|
|
9462
|
-
var World = class {
|
|
9454
|
+
var World = class _World {
|
|
9463
9455
|
/**
|
|
9464
9456
|
* Create a `World` for 2D physics simulation.
|
|
9465
9457
|
* @param bound a Group or an Iterable<Pt> representing a rectangular bounding box
|
|
@@ -9547,13 +9539,10 @@ var World = class {
|
|
|
9547
9539
|
* @returns a Body, or undefined if not found
|
|
9548
9540
|
*/
|
|
9549
9541
|
body(id) {
|
|
9550
|
-
let idx = id;
|
|
9551
9542
|
if (typeof id === "string" && id.length > 0) {
|
|
9552
|
-
|
|
9543
|
+
return this._bodies[this._bnames.indexOf(id)];
|
|
9553
9544
|
}
|
|
9554
|
-
|
|
9555
|
-
return void 0;
|
|
9556
|
-
return this._bodies[idx];
|
|
9545
|
+
return typeof id === "number" && id >= 0 ? this._bodies[id] : void 0;
|
|
9557
9546
|
}
|
|
9558
9547
|
/**
|
|
9559
9548
|
* Get a particle in this world by index or string id.
|
|
@@ -9561,13 +9550,10 @@ var World = class {
|
|
|
9561
9550
|
* @returns a Particle, or undefined if not found
|
|
9562
9551
|
*/
|
|
9563
9552
|
particle(id) {
|
|
9564
|
-
let idx = id;
|
|
9565
9553
|
if (typeof id === "string" && id.length > 0) {
|
|
9566
|
-
|
|
9554
|
+
return this._particles[this._pnames.indexOf(id)];
|
|
9567
9555
|
}
|
|
9568
|
-
|
|
9569
|
-
return void 0;
|
|
9570
|
-
return this._particles[idx];
|
|
9556
|
+
return typeof id === "number" && id >= 0 ? this._particles[id] : void 0;
|
|
9571
9557
|
}
|
|
9572
9558
|
/**
|
|
9573
9559
|
* Given a body's name, return its index in the bodies array, or -1 if not found.
|
|
@@ -9714,7 +9700,7 @@ var World = class {
|
|
|
9714
9700
|
for (let i = 0, len = this._particles.length; i < len; i++) {
|
|
9715
9701
|
let p = this._particles[i];
|
|
9716
9702
|
this.integrate(p, dt, this._lastTime);
|
|
9717
|
-
|
|
9703
|
+
_World.boundConstraint(p, this._bound, this._damping);
|
|
9718
9704
|
for (let k = i + 1; k < len; k++) {
|
|
9719
9705
|
if (i !== k) {
|
|
9720
9706
|
let p2 = this._particles[k];
|
|
@@ -9735,7 +9721,7 @@ var World = class {
|
|
|
9735
9721
|
if (bds) {
|
|
9736
9722
|
for (let k = 0, klen = bds.length; k < klen; k++) {
|
|
9737
9723
|
let bk = bds[k];
|
|
9738
|
-
|
|
9724
|
+
_World.boundConstraint(bk, this._bound, this._damping);
|
|
9739
9725
|
this.integrate(bk, dt, this._lastTime);
|
|
9740
9726
|
}
|
|
9741
9727
|
for (let k = i + 1; k < len; k++) {
|
|
@@ -9918,7 +9904,7 @@ var Particle = class extends Pt {
|
|
|
9918
9904
|
return `Particle: ${this[0]} ${this[1]} | previous ${this._prev[0]} ${this._prev[1]} | mass ${this._mass}`;
|
|
9919
9905
|
}
|
|
9920
9906
|
};
|
|
9921
|
-
var Body = class extends Group {
|
|
9907
|
+
var Body = class _Body extends Group {
|
|
9922
9908
|
/**
|
|
9923
9909
|
* Create an empty Body, this is usually followed by [`Body.init`](#link) to populate the Body. Alternatively, use static function [`Body.fromGroup`](#link) to create and initate a body directly.
|
|
9924
9910
|
*/
|
|
@@ -9937,7 +9923,7 @@ var Body = class extends Group {
|
|
|
9937
9923
|
* @param autoMass Automatically calculate the mass based on the area of the polygon. Default is true.
|
|
9938
9924
|
*/
|
|
9939
9925
|
static fromGroup(body, stiff = 1, autoLink = true, autoMass = true) {
|
|
9940
|
-
let b = new
|
|
9926
|
+
let b = new _Body().init(body);
|
|
9941
9927
|
if (autoLink)
|
|
9942
9928
|
b.linkAll(stiff);
|
|
9943
9929
|
if (autoMass)
|
|
@@ -10092,7 +10078,7 @@ var Body = class extends Group {
|
|
|
10092
10078
|
};
|
|
10093
10079
|
|
|
10094
10080
|
// src/Play.ts
|
|
10095
|
-
var Tempo = class {
|
|
10081
|
+
var Tempo = class _Tempo {
|
|
10096
10082
|
/**
|
|
10097
10083
|
* Construct a new Tempo instance by beats-per-minute. Alternatively, you can use [`Tempo.fromBeat`](#link) to create from milliseconds.
|
|
10098
10084
|
* @param bpm beats per minute
|
|
@@ -10108,7 +10094,7 @@ var Tempo = class {
|
|
|
10108
10094
|
* @param ms milliseconds per beat
|
|
10109
10095
|
*/
|
|
10110
10096
|
static fromBeat(ms) {
|
|
10111
|
-
return new
|
|
10097
|
+
return new _Tempo(6e4 / ms);
|
|
10112
10098
|
}
|
|
10113
10099
|
/**
|
|
10114
10100
|
* Beats-per-minute value
|
|
@@ -10150,16 +10136,16 @@ var Tempo = class {
|
|
|
10150
10136
|
* @returns an object with chainable functions
|
|
10151
10137
|
*/
|
|
10152
10138
|
every(beats) {
|
|
10153
|
-
|
|
10154
|
-
|
|
10139
|
+
const self = this;
|
|
10140
|
+
const p = Array.isArray(beats) ? beats[0] : beats;
|
|
10155
10141
|
return {
|
|
10156
10142
|
start: function(fn, offset = 0, name) {
|
|
10157
|
-
|
|
10143
|
+
const id = name || self._createID(fn);
|
|
10158
10144
|
self._listeners[id] = { name: id, beats, period: p, index: 0, offset, duration: -1, continuous: false, fn };
|
|
10159
10145
|
return this;
|
|
10160
10146
|
},
|
|
10161
10147
|
progress: function(fn, offset = 0, name) {
|
|
10162
|
-
|
|
10148
|
+
const id = name || self._createID(fn);
|
|
10163
10149
|
self._listeners[id] = { name: id, beats, period: p, index: 0, offset, duration: -1, continuous: true, fn };
|
|
10164
10150
|
return this;
|
|
10165
10151
|
}
|
|
@@ -10171,11 +10157,11 @@ var Tempo = class {
|
|
|
10171
10157
|
* @param time current time in milliseconds
|
|
10172
10158
|
*/
|
|
10173
10159
|
track(time) {
|
|
10174
|
-
for (
|
|
10160
|
+
for (const k in this._listeners) {
|
|
10175
10161
|
if (this._listeners.hasOwnProperty(k)) {
|
|
10176
|
-
|
|
10177
|
-
|
|
10178
|
-
|
|
10162
|
+
const li = this._listeners[k];
|
|
10163
|
+
const _t = li.offset ? time + li.offset : time;
|
|
10164
|
+
const ms = li.period * this._ms;
|
|
10179
10165
|
let isStart = false;
|
|
10180
10166
|
if (_t > li.duration + ms) {
|
|
10181
10167
|
li.duration = _t - _t % this._ms;
|
|
@@ -10185,10 +10171,10 @@ var Tempo = class {
|
|
|
10185
10171
|
}
|
|
10186
10172
|
isStart = true;
|
|
10187
10173
|
}
|
|
10188
|
-
|
|
10189
|
-
|
|
10174
|
+
const count = Math.max(0, Math.ceil(Math.floor(li.duration / this._ms) / li.period));
|
|
10175
|
+
const params = li.continuous ? [count, Num.clamp((_t - li.duration) / ms, 0, 1), _t, isStart] : [count];
|
|
10190
10176
|
if (li.continuous || isStart) {
|
|
10191
|
-
|
|
10177
|
+
const done = li.fn.apply(li, params);
|
|
10192
10178
|
if (done)
|
|
10193
10179
|
delete this._listeners[li.name];
|
|
10194
10180
|
}
|
|
@@ -10222,7 +10208,7 @@ var Tempo = class {
|
|
|
10222
10208
|
return;
|
|
10223
10209
|
}
|
|
10224
10210
|
};
|
|
10225
|
-
var Sound = class {
|
|
10211
|
+
var Sound = class _Sound {
|
|
10226
10212
|
// Tracking play time against ctx.currentTime
|
|
10227
10213
|
/**
|
|
10228
10214
|
* Construct a `Sound` instance. Usually, it's more convenient to use one of the static methods like [`Sound.load`](#function_load) or [`Sound.from`](#function_from).
|
|
@@ -10237,7 +10223,7 @@ var Sound = class {
|
|
|
10237
10223
|
* Create an AudioContext instance. This is called internally only.
|
|
10238
10224
|
*/
|
|
10239
10225
|
_createAudioContext() {
|
|
10240
|
-
|
|
10226
|
+
const _ctx = window.AudioContext;
|
|
10241
10227
|
if (!_ctx)
|
|
10242
10228
|
throw new Error("Your browser doesn't support Web Audio. (No AudioContext)");
|
|
10243
10229
|
this._ctx = _ctx ? new _ctx() : void 0;
|
|
@@ -10251,7 +10237,7 @@ var Sound = class {
|
|
|
10251
10237
|
* @returns a `Sound` instance
|
|
10252
10238
|
*/
|
|
10253
10239
|
static from(node, ctx, type = "gen", stream) {
|
|
10254
|
-
|
|
10240
|
+
const s = new _Sound(type);
|
|
10255
10241
|
s._node = node;
|
|
10256
10242
|
s._ctx = ctx;
|
|
10257
10243
|
if (stream)
|
|
@@ -10267,7 +10253,7 @@ var Sound = class {
|
|
|
10267
10253
|
*/
|
|
10268
10254
|
static load(source, crossOrigin = "anonymous") {
|
|
10269
10255
|
return new Promise((resolve, reject) => {
|
|
10270
|
-
|
|
10256
|
+
const s = new _Sound("file");
|
|
10271
10257
|
s._source = typeof source === "string" ? new Audio(source) : source;
|
|
10272
10258
|
s._source.autoplay = false;
|
|
10273
10259
|
s._source.crossOrigin = crossOrigin;
|
|
@@ -10292,10 +10278,10 @@ var Sound = class {
|
|
|
10292
10278
|
*/
|
|
10293
10279
|
static loadAsBuffer(url) {
|
|
10294
10280
|
return new Promise((resolve, reject) => {
|
|
10295
|
-
|
|
10281
|
+
const request = new XMLHttpRequest();
|
|
10296
10282
|
request.open("GET", url, true);
|
|
10297
10283
|
request.responseType = "arraybuffer";
|
|
10298
|
-
|
|
10284
|
+
const s = new _Sound("file");
|
|
10299
10285
|
request.onload = function() {
|
|
10300
10286
|
s._ctx.decodeAudioData(request.response, function(buffer) {
|
|
10301
10287
|
s.createBuffer(buffer);
|
|
@@ -10327,13 +10313,13 @@ var Sound = class {
|
|
|
10327
10313
|
* @example `Sound.generate( 'sine', 120 )`
|
|
10328
10314
|
*/
|
|
10329
10315
|
static generate(type, val) {
|
|
10330
|
-
|
|
10316
|
+
const s = new _Sound("gen");
|
|
10331
10317
|
return s._gen(type, val);
|
|
10332
10318
|
}
|
|
10333
10319
|
// Create the oscillator
|
|
10334
10320
|
_gen(type, val) {
|
|
10335
10321
|
this._node = this._ctx.createOscillator();
|
|
10336
|
-
|
|
10322
|
+
const osc = this._node;
|
|
10337
10323
|
osc.type = type;
|
|
10338
10324
|
if (type === "custom") {
|
|
10339
10325
|
osc.setPeriodicWave(val);
|
|
@@ -10351,7 +10337,7 @@ var Sound = class {
|
|
|
10351
10337
|
static input(constraint) {
|
|
10352
10338
|
return __async(this, null, function* () {
|
|
10353
10339
|
try {
|
|
10354
|
-
|
|
10340
|
+
const s = new _Sound("input");
|
|
10355
10341
|
if (!s)
|
|
10356
10342
|
return void 0;
|
|
10357
10343
|
const c = constraint ? constraint : { audio: true, video: false };
|
|
@@ -10421,7 +10407,7 @@ var Sound = class {
|
|
|
10421
10407
|
get progress() {
|
|
10422
10408
|
let dur = 0;
|
|
10423
10409
|
let curr = 0;
|
|
10424
|
-
if (
|
|
10410
|
+
if (this._buffer) {
|
|
10425
10411
|
dur = this._buffer.duration;
|
|
10426
10412
|
curr = this._timestamp ? this._ctx.currentTime - this._timestamp : 0;
|
|
10427
10413
|
} else {
|
|
@@ -10493,7 +10479,7 @@ var Sound = class {
|
|
|
10493
10479
|
* @param smooth Optional smoothing value (corresponds to `AnalyserNode.smoothingTimeConstant`)
|
|
10494
10480
|
*/
|
|
10495
10481
|
analyze(size = 256, minDb = -100, maxDb = -30, smooth = 0.8) {
|
|
10496
|
-
|
|
10482
|
+
const a = this._ctx.createAnalyser();
|
|
10497
10483
|
a.fftSize = size * 2;
|
|
10498
10484
|
a.minDecibels = minDb;
|
|
10499
10485
|
a.maxDecibels = maxDb;
|
|
@@ -10520,8 +10506,8 @@ var Sound = class {
|
|
|
10520
10506
|
}
|
|
10521
10507
|
// Map domain data to another range
|
|
10522
10508
|
_domainTo(time, size, position = [0, 0], trim = [0, 0]) {
|
|
10523
|
-
|
|
10524
|
-
|
|
10509
|
+
const data = time ? this.timeDomain() : this.freqDomain();
|
|
10510
|
+
const g = new Group();
|
|
10525
10511
|
for (let i = trim[0], len = data.length - trim[1]; i < len; i++) {
|
|
10526
10512
|
g.push(new Pt(position[0] + size[0] * i / len, position[1] + size[1] * data[i] / 255));
|
|
10527
10513
|
}
|
|
@@ -10580,7 +10566,7 @@ var Sound = class {
|
|
|
10580
10566
|
this._ctx.resume();
|
|
10581
10567
|
}
|
|
10582
10568
|
if (this._type === "file") {
|
|
10583
|
-
if (
|
|
10569
|
+
if (this._buffer) {
|
|
10584
10570
|
this._node.start(timeAt);
|
|
10585
10571
|
this._timestamp = this._ctx.currentTime + timeAt;
|
|
10586
10572
|
} else {
|
|
@@ -10605,7 +10591,7 @@ var Sound = class {
|
|
|
10605
10591
|
if (this._playing)
|
|
10606
10592
|
(this._outputNode || this._node).disconnect(this._ctx.destination);
|
|
10607
10593
|
if (this._type === "file") {
|
|
10608
|
-
if (
|
|
10594
|
+
if (this._buffer) {
|
|
10609
10595
|
if (this.progress < 1)
|
|
10610
10596
|
this._node.stop();
|
|
10611
10597
|
} else {
|