@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 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 = 8) => {
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 = 12) => {
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
- constructor(p1) {
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
- const t = quadraticCurve.solveTForX(this.p1, x);
340
- return this.solveY(t);
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
- constructor(p1, p2) {
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
- const t = cubicCurve.solveTForX([this.p1, this.p2], x);
365
- return this.solveY(t);
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 = 8) => {
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 = 12) => {
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
- constructor(p1) {
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
- const t = quadraticCurve.solveTForX(this.p1, x);
294
- return this.solveY(t);
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
- constructor(p1, p2) {
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
- const t = cubicCurve.solveTForX([this.p1, this.p2], x);
319
- return this.solveY(t);
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 {
@@ -1,61 +1,84 @@
1
1
  type Point = [number, number];
2
2
  export declare namespace quadraticCurve {
3
3
  /**
4
- * [二次] 给定控制点 P1 和 t (时间),计算 x 坐标
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
- * [二次] 给定控制点 P1 和 t (时间),计算 y 坐标
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
- * [二次] 给定控制点 P1 和 x (坐标),反向求解 t (时间)
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
- * [三次] 给定控制点 P1, P2 和 t (时间),计算 x 坐标
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
- * [三次] 给定控制点 P1, P2 和 t (时间),计算 y 坐标
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
- * [三次] 给定控制点 P1, P2 和 x (坐标),反向求解 t (时间)
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
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ceale/util",
3
3
  "author": "Ceale",
4
- "version": "1.10.0",
4
+ "version": "1.11.0",
5
5
  "module": "index.ts",
6
6
  "type": "module",
7
7
  "main": "dist/esm/index.js",