@ceale/util 1.10.0 → 1.11.0
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 +38 -8
- package/dist/esm/index.js +38 -8
- package/dist/types/bezier.d.ts +34 -8
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -272,7 +272,7 @@ 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
276
|
let tMin = 0;
|
|
277
277
|
let tMax = 1;
|
|
278
278
|
let tGuess;
|
|
@@ -287,6 +287,10 @@ var quadraticCurve;
|
|
|
287
287
|
}
|
|
288
288
|
return (tMin + tMax) / 2;
|
|
289
289
|
};
|
|
290
|
+
quadraticCurve.solveYForX = (p1, x, iterations = 15) => {
|
|
291
|
+
const t = quadraticCurve.solveTForX(p1, x, iterations);
|
|
292
|
+
return quadraticCurve.solveY(p1, t);
|
|
293
|
+
};
|
|
290
294
|
})(quadraticCurve ||= {});
|
|
291
295
|
var cubicCurve;
|
|
292
296
|
((cubicCurve) => {
|
|
@@ -304,7 +308,7 @@ var cubicCurve;
|
|
|
304
308
|
const t2 = t * t;
|
|
305
309
|
return 3 * oneMinusT * oneMinusT * t * p1y + 3 * oneMinusT * t2 * p2y + t2 * t;
|
|
306
310
|
};
|
|
307
|
-
cubicCurve.solveTForX = ([p1, p2], x, iterations =
|
|
311
|
+
cubicCurve.solveTForX = ([p1, p2], x, iterations = 20) => {
|
|
308
312
|
let tMin = 0;
|
|
309
313
|
let tMax = 1;
|
|
310
314
|
let tGuess;
|
|
@@ -319,12 +323,19 @@ var cubicCurve;
|
|
|
319
323
|
}
|
|
320
324
|
return (tMin + tMax) / 2;
|
|
321
325
|
};
|
|
326
|
+
cubicCurve.solveYForX = ([p1, p2], x, iterations = 20) => {
|
|
327
|
+
const t = cubicCurve.solveTForX([p1, p2], x, iterations);
|
|
328
|
+
return cubicCurve.solveY([p1, p2], t);
|
|
329
|
+
};
|
|
322
330
|
})(cubicCurve ||= {});
|
|
323
331
|
|
|
324
332
|
class QuadraticBezier {
|
|
325
333
|
p1;
|
|
326
|
-
|
|
334
|
+
accuracy;
|
|
335
|
+
cache = new Map;
|
|
336
|
+
constructor(p1, accuracy = 4) {
|
|
327
337
|
this.p1 = p1;
|
|
338
|
+
this.accuracy = accuracy;
|
|
328
339
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
329
340
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
330
341
|
}
|
|
@@ -336,17 +347,28 @@ class QuadraticBezier {
|
|
|
336
347
|
return quadraticCurve.solveY(this.p1, t);
|
|
337
348
|
}
|
|
338
349
|
solveYForX(x) {
|
|
339
|
-
|
|
340
|
-
|
|
350
|
+
if (this.accuracy === -1)
|
|
351
|
+
return quadraticCurve.solveYForX(this.p1, x);
|
|
352
|
+
else {
|
|
353
|
+
const roughX = Math.round(x * this.accuracy);
|
|
354
|
+
return this.cache.get(roughX) ?? (() => {
|
|
355
|
+
const y = quadraticCurve.solveYForX(this.p1, x);
|
|
356
|
+
this.cache.set(roughX, y);
|
|
357
|
+
return y;
|
|
358
|
+
})();
|
|
359
|
+
}
|
|
341
360
|
}
|
|
342
361
|
}
|
|
343
362
|
|
|
344
363
|
class CubicBezier {
|
|
345
364
|
p1;
|
|
346
365
|
p2;
|
|
347
|
-
|
|
366
|
+
accuracy;
|
|
367
|
+
cache = new Map;
|
|
368
|
+
constructor(p1, p2, accuracy = 4) {
|
|
348
369
|
this.p1 = p1;
|
|
349
370
|
this.p2 = p2;
|
|
371
|
+
this.accuracy = accuracy;
|
|
350
372
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
351
373
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
352
374
|
}
|
|
@@ -361,7 +383,15 @@ class CubicBezier {
|
|
|
361
383
|
return cubicCurve.solveY([this.p1, this.p2], t);
|
|
362
384
|
}
|
|
363
385
|
solveYForX(x) {
|
|
364
|
-
|
|
365
|
-
|
|
386
|
+
if (this.accuracy === -1)
|
|
387
|
+
return cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
388
|
+
else {
|
|
389
|
+
const roughX = Math.round(x * this.accuracy);
|
|
390
|
+
return this.cache.get(roughX) ?? (() => {
|
|
391
|
+
const y = cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
392
|
+
this.cache.set(roughX, y);
|
|
393
|
+
return y;
|
|
394
|
+
})();
|
|
395
|
+
}
|
|
366
396
|
}
|
|
367
397
|
}
|
package/dist/esm/index.js
CHANGED
|
@@ -226,7 +226,7 @@ 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
230
|
let tMin = 0;
|
|
231
231
|
let tMax = 1;
|
|
232
232
|
let tGuess;
|
|
@@ -241,6 +241,10 @@ var quadraticCurve;
|
|
|
241
241
|
}
|
|
242
242
|
return (tMin + tMax) / 2;
|
|
243
243
|
};
|
|
244
|
+
quadraticCurve.solveYForX = (p1, x, iterations = 15) => {
|
|
245
|
+
const t = quadraticCurve.solveTForX(p1, x, iterations);
|
|
246
|
+
return quadraticCurve.solveY(p1, t);
|
|
247
|
+
};
|
|
244
248
|
})(quadraticCurve ||= {});
|
|
245
249
|
var cubicCurve;
|
|
246
250
|
((cubicCurve) => {
|
|
@@ -258,7 +262,7 @@ var cubicCurve;
|
|
|
258
262
|
const t2 = t * t;
|
|
259
263
|
return 3 * oneMinusT * oneMinusT * t * p1y + 3 * oneMinusT * t2 * p2y + t2 * t;
|
|
260
264
|
};
|
|
261
|
-
cubicCurve.solveTForX = ([p1, p2], x, iterations =
|
|
265
|
+
cubicCurve.solveTForX = ([p1, p2], x, iterations = 20) => {
|
|
262
266
|
let tMin = 0;
|
|
263
267
|
let tMax = 1;
|
|
264
268
|
let tGuess;
|
|
@@ -273,12 +277,19 @@ var cubicCurve;
|
|
|
273
277
|
}
|
|
274
278
|
return (tMin + tMax) / 2;
|
|
275
279
|
};
|
|
280
|
+
cubicCurve.solveYForX = ([p1, p2], x, iterations = 20) => {
|
|
281
|
+
const t = cubicCurve.solveTForX([p1, p2], x, iterations);
|
|
282
|
+
return cubicCurve.solveY([p1, p2], t);
|
|
283
|
+
};
|
|
276
284
|
})(cubicCurve ||= {});
|
|
277
285
|
|
|
278
286
|
class QuadraticBezier {
|
|
279
287
|
p1;
|
|
280
|
-
|
|
288
|
+
accuracy;
|
|
289
|
+
cache = new Map;
|
|
290
|
+
constructor(p1, accuracy = 4) {
|
|
281
291
|
this.p1 = p1;
|
|
292
|
+
this.accuracy = accuracy;
|
|
282
293
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
283
294
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
284
295
|
}
|
|
@@ -290,17 +301,28 @@ class QuadraticBezier {
|
|
|
290
301
|
return quadraticCurve.solveY(this.p1, t);
|
|
291
302
|
}
|
|
292
303
|
solveYForX(x) {
|
|
293
|
-
|
|
294
|
-
|
|
304
|
+
if (this.accuracy === -1)
|
|
305
|
+
return quadraticCurve.solveYForX(this.p1, x);
|
|
306
|
+
else {
|
|
307
|
+
const roughX = Math.round(x * this.accuracy);
|
|
308
|
+
return this.cache.get(roughX) ?? (() => {
|
|
309
|
+
const y = quadraticCurve.solveYForX(this.p1, x);
|
|
310
|
+
this.cache.set(roughX, y);
|
|
311
|
+
return y;
|
|
312
|
+
})();
|
|
313
|
+
}
|
|
295
314
|
}
|
|
296
315
|
}
|
|
297
316
|
|
|
298
317
|
class CubicBezier {
|
|
299
318
|
p1;
|
|
300
319
|
p2;
|
|
301
|
-
|
|
320
|
+
accuracy;
|
|
321
|
+
cache = new Map;
|
|
322
|
+
constructor(p1, p2, accuracy = 4) {
|
|
302
323
|
this.p1 = p1;
|
|
303
324
|
this.p2 = p2;
|
|
325
|
+
this.accuracy = accuracy;
|
|
304
326
|
if (this.p1[0] < 0 || this.p1[0] > 1) {
|
|
305
327
|
throw new BezierError("控制点P1的x坐标必须在[0, 1]之间");
|
|
306
328
|
}
|
|
@@ -315,8 +337,16 @@ class CubicBezier {
|
|
|
315
337
|
return cubicCurve.solveY([this.p1, this.p2], t);
|
|
316
338
|
}
|
|
317
339
|
solveYForX(x) {
|
|
318
|
-
|
|
319
|
-
|
|
340
|
+
if (this.accuracy === -1)
|
|
341
|
+
return cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
342
|
+
else {
|
|
343
|
+
const roughX = Math.round(x * this.accuracy);
|
|
344
|
+
return this.cache.get(roughX) ?? (() => {
|
|
345
|
+
const y = cubicCurve.solveYForX([this.p1, this.p2], x);
|
|
346
|
+
this.cache.set(roughX, y);
|
|
347
|
+
return y;
|
|
348
|
+
})();
|
|
349
|
+
}
|
|
320
350
|
}
|
|
321
351
|
}
|
|
322
352
|
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 readonly 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 readonly 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
|
*/
|