@ceale/util 1.10.0 → 1.11.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/dist/cjs/index.js +52 -8
- package/dist/esm/index.js +52 -8
- package/dist/types/bezier.d.ts +34 -8
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -272,7 +272,11 @@ var quadraticCurve;
|
|
|
272
272
|
const oneMinusT = 1 - t;
|
|
273
273
|
return 2 * oneMinusT * t * p1y + t * t;
|
|
274
274
|
};
|
|
275
|
-
quadraticCurve.solveTForX = (p1, x, iterations =
|
|
275
|
+
quadraticCurve.solveTForX = (p1, x, iterations = 15) => {
|
|
276
|
+
if (x <= 0)
|
|
277
|
+
return 0;
|
|
278
|
+
if (x >= 1)
|
|
279
|
+
return 1;
|
|
276
280
|
let tMin = 0;
|
|
277
281
|
let tMax = 1;
|
|
278
282
|
let tGuess;
|
|
@@ -287,6 +291,10 @@ var quadraticCurve;
|
|
|
287
291
|
}
|
|
288
292
|
return (tMin + tMax) / 2;
|
|
289
293
|
};
|
|
294
|
+
quadraticCurve.solveYForX = (p1, x, iterations = 15) => {
|
|
295
|
+
const t = quadraticCurve.solveTForX(p1, x, iterations);
|
|
296
|
+
return quadraticCurve.solveY(p1, t);
|
|
297
|
+
};
|
|
290
298
|
})(quadraticCurve ||= {});
|
|
291
299
|
var cubicCurve;
|
|
292
300
|
((cubicCurve) => {
|
|
@@ -304,7 +312,11 @@ var cubicCurve;
|
|
|
304
312
|
const t2 = t * t;
|
|
305
313
|
return 3 * oneMinusT * oneMinusT * t * p1y + 3 * oneMinusT * t2 * p2y + t2 * t;
|
|
306
314
|
};
|
|
307
|
-
cubicCurve.solveTForX = ([p1, p2], x, iterations =
|
|
315
|
+
cubicCurve.solveTForX = ([p1, p2], x, iterations = 20) => {
|
|
316
|
+
if (x <= 0)
|
|
317
|
+
return 0;
|
|
318
|
+
if (x >= 1)
|
|
319
|
+
return 1;
|
|
308
320
|
let tMin = 0;
|
|
309
321
|
let tMax = 1;
|
|
310
322
|
let tGuess;
|
|
@@ -319,15 +331,25 @@ var cubicCurve;
|
|
|
319
331
|
}
|
|
320
332
|
return (tMin + tMax) / 2;
|
|
321
333
|
};
|
|
334
|
+
cubicCurve.solveYForX = ([p1, p2], x, iterations = 20) => {
|
|
335
|
+
const t = cubicCurve.solveTForX([p1, p2], x, iterations);
|
|
336
|
+
return cubicCurve.solveY([p1, p2], t);
|
|
337
|
+
};
|
|
322
338
|
})(cubicCurve ||= {});
|
|
323
339
|
|
|
324
340
|
class QuadraticBezier {
|
|
325
341
|
p1;
|
|
326
|
-
|
|
342
|
+
accuracy;
|
|
343
|
+
cache = new Map;
|
|
344
|
+
constructor(p1, accuracy = 4) {
|
|
327
345
|
this.p1 = p1;
|
|
346
|
+
this.accuracy = accuracy;
|
|
328
347
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
329
348
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
330
349
|
}
|
|
350
|
+
if (accuracy !== -1) {
|
|
351
|
+
this.accuracy = 10 ** accuracy;
|
|
352
|
+
}
|
|
331
353
|
}
|
|
332
354
|
solveX(t) {
|
|
333
355
|
return quadraticCurve.solveX(this.p1, t);
|
|
@@ -336,23 +358,37 @@ class QuadraticBezier {
|
|
|
336
358
|
return quadraticCurve.solveY(this.p1, t);
|
|
337
359
|
}
|
|
338
360
|
solveYForX(x) {
|
|
339
|
-
|
|
340
|
-
|
|
361
|
+
if (this.accuracy === -1)
|
|
362
|
+
return quadraticCurve.solveYForX(this.p1, x);
|
|
363
|
+
else {
|
|
364
|
+
const roughX = Math.round(x * this.accuracy);
|
|
365
|
+
return this.cache.get(roughX) ?? (() => {
|
|
366
|
+
const y = quadraticCurve.solveYForX(this.p1, x);
|
|
367
|
+
this.cache.set(roughX, y);
|
|
368
|
+
return y;
|
|
369
|
+
})();
|
|
370
|
+
}
|
|
341
371
|
}
|
|
342
372
|
}
|
|
343
373
|
|
|
344
374
|
class CubicBezier {
|
|
345
375
|
p1;
|
|
346
376
|
p2;
|
|
347
|
-
|
|
377
|
+
accuracy;
|
|
378
|
+
cache = new Map;
|
|
379
|
+
constructor(p1, p2, accuracy = 4) {
|
|
348
380
|
this.p1 = p1;
|
|
349
381
|
this.p2 = p2;
|
|
382
|
+
this.accuracy = accuracy;
|
|
350
383
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
351
384
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
352
385
|
}
|
|
353
386
|
if (this.p2[0] < 0 || this.p2[0] > 1) {
|
|
354
387
|
throw new BezierError("控制点P2的x坐标必须在[0, 1]之间");
|
|
355
388
|
}
|
|
389
|
+
if (accuracy !== -1) {
|
|
390
|
+
this.accuracy = 10 ** accuracy;
|
|
391
|
+
}
|
|
356
392
|
}
|
|
357
393
|
solveX(t) {
|
|
358
394
|
return cubicCurve.solveX([this.p1, this.p2], t);
|
|
@@ -361,7 +397,15 @@ class CubicBezier {
|
|
|
361
397
|
return cubicCurve.solveY([this.p1, this.p2], t);
|
|
362
398
|
}
|
|
363
399
|
solveYForX(x) {
|
|
364
|
-
|
|
365
|
-
|
|
400
|
+
if (this.accuracy === -1)
|
|
401
|
+
return cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
402
|
+
else {
|
|
403
|
+
const roughX = Math.round(x * this.accuracy);
|
|
404
|
+
return this.cache.get(roughX) ?? (() => {
|
|
405
|
+
const y = cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
406
|
+
this.cache.set(roughX, y);
|
|
407
|
+
return y;
|
|
408
|
+
})();
|
|
409
|
+
}
|
|
366
410
|
}
|
|
367
411
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -226,7 +226,11 @@ var quadraticCurve;
|
|
|
226
226
|
const oneMinusT = 1 - t;
|
|
227
227
|
return 2 * oneMinusT * t * p1y + t * t;
|
|
228
228
|
};
|
|
229
|
-
quadraticCurve.solveTForX = (p1, x, iterations =
|
|
229
|
+
quadraticCurve.solveTForX = (p1, x, iterations = 15) => {
|
|
230
|
+
if (x <= 0)
|
|
231
|
+
return 0;
|
|
232
|
+
if (x >= 1)
|
|
233
|
+
return 1;
|
|
230
234
|
let tMin = 0;
|
|
231
235
|
let tMax = 1;
|
|
232
236
|
let tGuess;
|
|
@@ -241,6 +245,10 @@ var quadraticCurve;
|
|
|
241
245
|
}
|
|
242
246
|
return (tMin + tMax) / 2;
|
|
243
247
|
};
|
|
248
|
+
quadraticCurve.solveYForX = (p1, x, iterations = 15) => {
|
|
249
|
+
const t = quadraticCurve.solveTForX(p1, x, iterations);
|
|
250
|
+
return quadraticCurve.solveY(p1, t);
|
|
251
|
+
};
|
|
244
252
|
})(quadraticCurve ||= {});
|
|
245
253
|
var cubicCurve;
|
|
246
254
|
((cubicCurve) => {
|
|
@@ -258,7 +266,11 @@ var cubicCurve;
|
|
|
258
266
|
const t2 = t * t;
|
|
259
267
|
return 3 * oneMinusT * oneMinusT * t * p1y + 3 * oneMinusT * t2 * p2y + t2 * t;
|
|
260
268
|
};
|
|
261
|
-
cubicCurve.solveTForX = ([p1, p2], x, iterations =
|
|
269
|
+
cubicCurve.solveTForX = ([p1, p2], x, iterations = 20) => {
|
|
270
|
+
if (x <= 0)
|
|
271
|
+
return 0;
|
|
272
|
+
if (x >= 1)
|
|
273
|
+
return 1;
|
|
262
274
|
let tMin = 0;
|
|
263
275
|
let tMax = 1;
|
|
264
276
|
let tGuess;
|
|
@@ -273,15 +285,25 @@ var cubicCurve;
|
|
|
273
285
|
}
|
|
274
286
|
return (tMin + tMax) / 2;
|
|
275
287
|
};
|
|
288
|
+
cubicCurve.solveYForX = ([p1, p2], x, iterations = 20) => {
|
|
289
|
+
const t = cubicCurve.solveTForX([p1, p2], x, iterations);
|
|
290
|
+
return cubicCurve.solveY([p1, p2], t);
|
|
291
|
+
};
|
|
276
292
|
})(cubicCurve ||= {});
|
|
277
293
|
|
|
278
294
|
class QuadraticBezier {
|
|
279
295
|
p1;
|
|
280
|
-
|
|
296
|
+
accuracy;
|
|
297
|
+
cache = new Map;
|
|
298
|
+
constructor(p1, accuracy = 4) {
|
|
281
299
|
this.p1 = p1;
|
|
300
|
+
this.accuracy = accuracy;
|
|
282
301
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
283
302
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
284
303
|
}
|
|
304
|
+
if (accuracy !== -1) {
|
|
305
|
+
this.accuracy = 10 ** accuracy;
|
|
306
|
+
}
|
|
285
307
|
}
|
|
286
308
|
solveX(t) {
|
|
287
309
|
return quadraticCurve.solveX(this.p1, t);
|
|
@@ -290,23 +312,37 @@ class QuadraticBezier {
|
|
|
290
312
|
return quadraticCurve.solveY(this.p1, t);
|
|
291
313
|
}
|
|
292
314
|
solveYForX(x) {
|
|
293
|
-
|
|
294
|
-
|
|
315
|
+
if (this.accuracy === -1)
|
|
316
|
+
return quadraticCurve.solveYForX(this.p1, x);
|
|
317
|
+
else {
|
|
318
|
+
const roughX = Math.round(x * this.accuracy);
|
|
319
|
+
return this.cache.get(roughX) ?? (() => {
|
|
320
|
+
const y = quadraticCurve.solveYForX(this.p1, x);
|
|
321
|
+
this.cache.set(roughX, y);
|
|
322
|
+
return y;
|
|
323
|
+
})();
|
|
324
|
+
}
|
|
295
325
|
}
|
|
296
326
|
}
|
|
297
327
|
|
|
298
328
|
class CubicBezier {
|
|
299
329
|
p1;
|
|
300
330
|
p2;
|
|
301
|
-
|
|
331
|
+
accuracy;
|
|
332
|
+
cache = new Map;
|
|
333
|
+
constructor(p1, p2, accuracy = 4) {
|
|
302
334
|
this.p1 = p1;
|
|
303
335
|
this.p2 = p2;
|
|
336
|
+
this.accuracy = accuracy;
|
|
304
337
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
305
338
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
306
339
|
}
|
|
307
340
|
if (this.p2[0] < 0 || this.p2[0] > 1) {
|
|
308
341
|
throw new BezierError("控制点P2的x坐标必须在[0, 1]之间");
|
|
309
342
|
}
|
|
343
|
+
if (accuracy !== -1) {
|
|
344
|
+
this.accuracy = 10 ** accuracy;
|
|
345
|
+
}
|
|
310
346
|
}
|
|
311
347
|
solveX(t) {
|
|
312
348
|
return cubicCurve.solveX([this.p1, this.p2], t);
|
|
@@ -315,8 +351,16 @@ class CubicBezier {
|
|
|
315
351
|
return cubicCurve.solveY([this.p1, this.p2], t);
|
|
316
352
|
}
|
|
317
353
|
solveYForX(x) {
|
|
318
|
-
|
|
319
|
-
|
|
354
|
+
if (this.accuracy === -1)
|
|
355
|
+
return cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
356
|
+
else {
|
|
357
|
+
const roughX = Math.round(x * this.accuracy);
|
|
358
|
+
return this.cache.get(roughX) ?? (() => {
|
|
359
|
+
const y = cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
360
|
+
this.cache.set(roughX, y);
|
|
361
|
+
return y;
|
|
362
|
+
})();
|
|
363
|
+
}
|
|
320
364
|
}
|
|
321
365
|
}
|
|
322
366
|
export {
|
package/dist/types/bezier.d.ts
CHANGED
|
@@ -1,61 +1,84 @@
|
|
|
1
1
|
type Point = [number, number];
|
|
2
2
|
export declare namespace quadraticCurve {
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* 给定控制点 P1 和 t (时间),计算 x 坐标
|
|
5
5
|
* @param p1 控制点1 的坐标
|
|
6
6
|
* @param t 时间比例 [0, 1]
|
|
7
7
|
* @returns x 坐标
|
|
8
8
|
*/
|
|
9
9
|
const solveX: (p1: Point, t: number) => number;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* 给定控制点 P1 和 t (时间),计算 y 坐标
|
|
12
12
|
* @param p1 控制点1 坐标
|
|
13
13
|
* @param t 时间比例 [0, 1]
|
|
14
14
|
* @returns y 坐标
|
|
15
15
|
*/
|
|
16
16
|
const solveY: (p1: Point, t: number) => number;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* 给定控制点 P1 和 x (坐标),求解 t (时间)
|
|
19
19
|
* 使用二分查找法
|
|
20
20
|
* @param p1 控制点1 坐标
|
|
21
21
|
* @param x 目标 x 坐标 [0, 1]
|
|
22
|
+
* @param iterations 可选,二分法求值迭代次数,默认15次
|
|
22
23
|
* @returns 对应的时间 t
|
|
23
24
|
*/
|
|
24
25
|
const solveTForX: (p1: Point, x: number, iterations?: number) => number;
|
|
26
|
+
/**
|
|
27
|
+
* 给定控制点 P1 和 x (坐标),求解 y (坐标)
|
|
28
|
+
* 使用二分查找法
|
|
29
|
+
* @param p1 控制点1 坐标
|
|
30
|
+
* @param x 目标 x 坐标 [0, 1]
|
|
31
|
+
* @returns 对应的时间 t
|
|
32
|
+
* @param iterations 可选,二分法求值迭代次数,默认15次
|
|
33
|
+
*/
|
|
34
|
+
const solveYForX: (p1: Point, x: number, iterations?: number) => number;
|
|
25
35
|
}
|
|
26
36
|
export declare namespace cubicCurve {
|
|
27
37
|
/**
|
|
28
|
-
*
|
|
38
|
+
* 给定控制点 P1, P2 和 t (时间),计算 x 坐标
|
|
29
39
|
* @param \[p1, p2] 控制点1 控制点2 的坐标
|
|
30
40
|
* @param t 时间比例 [0, 1]
|
|
31
41
|
* @returns x 坐标
|
|
32
42
|
*/
|
|
33
43
|
const solveX: ([p1, p2]: [Point, Point], t: number) => number;
|
|
34
44
|
/**
|
|
35
|
-
*
|
|
45
|
+
* 给定控制点 P1, P2 和 t (时间),计算 y 坐标
|
|
36
46
|
* @param \[p1, p2] 控制点1 控制点2 的坐标
|
|
37
47
|
* @param t 时间比例 [0, 1]
|
|
38
48
|
* @returns y 坐标
|
|
39
49
|
*/
|
|
40
50
|
const solveY: ([p1, p2]: [Point, Point], t: number) => number;
|
|
41
51
|
/**
|
|
42
|
-
*
|
|
52
|
+
* 给定控制点 P1, P2 和 x (坐标),求解 t (时间)
|
|
43
53
|
* 使用二分查找法
|
|
44
54
|
* @param \[p1, p2] 控制点1 控制点2 的坐标
|
|
45
55
|
* @param x 目标 x 坐标 [0, 1]
|
|
46
56
|
* @returns 对应的时间 t
|
|
57
|
+
* @param iterations 可选,二分法求值迭代次数,默认20次
|
|
47
58
|
*/
|
|
48
59
|
const solveTForX: ([p1, p2]: [Point, Point], x: number, iterations?: number) => number;
|
|
60
|
+
/**
|
|
61
|
+
* 给定控制点 P1 和 x (坐标),求解 y (坐标)
|
|
62
|
+
* 使用二分查找法
|
|
63
|
+
* @param p1 控制点1 坐标
|
|
64
|
+
* @param x 目标 x 坐标 [0, 1]
|
|
65
|
+
* @returns 对应的时间 t
|
|
66
|
+
* @param iterations 可选,二分法求值迭代次数,默认20次
|
|
67
|
+
*/
|
|
68
|
+
const solveYForX: ([p1, p2]: [Point, Point], x: number, iterations?: number) => number;
|
|
49
69
|
}
|
|
50
70
|
/**
|
|
51
71
|
* 代表一个二次贝塞尔缓动曲线
|
|
52
72
|
*/
|
|
53
73
|
export declare class QuadraticBezier {
|
|
54
74
|
private readonly p1;
|
|
75
|
+
private accuracy;
|
|
76
|
+
cache: Map<number, number>;
|
|
55
77
|
/**
|
|
56
78
|
* @param p1 控制点 P1
|
|
79
|
+
* @param accuracy 缓存精度(`10^-accuracy`),默认为`4`,`-1`则表示不缓存
|
|
57
80
|
*/
|
|
58
|
-
constructor(p1: Point);
|
|
81
|
+
constructor(p1: Point, accuracy?: number);
|
|
59
82
|
/**
|
|
60
83
|
* 根据时间 t [0, 1],计算 x 坐标
|
|
61
84
|
*/
|
|
@@ -75,11 +98,14 @@ export declare class QuadraticBezier {
|
|
|
75
98
|
export declare class CubicBezier {
|
|
76
99
|
private readonly p1;
|
|
77
100
|
private readonly p2;
|
|
101
|
+
private accuracy;
|
|
102
|
+
cache: Map<number, number>;
|
|
78
103
|
/**
|
|
79
104
|
* @param p1 控制点 P1
|
|
80
105
|
* @param p2 控制点 P2
|
|
106
|
+
* @param accuracy 缓存精度(`10^-accuracy`),默认为`4`,`-1`则表示不缓存
|
|
81
107
|
*/
|
|
82
|
-
constructor(p1: Point, p2: Point);
|
|
108
|
+
constructor(p1: Point, p2: Point, accuracy?: number);
|
|
83
109
|
/**
|
|
84
110
|
* 根据时间 t [0, 1],计算 x 坐标
|
|
85
111
|
*/
|