UNPKG

3.75 kBJavaScriptView Raw
1/*
2Copyright 2019 Adobe. All rights reserved.
3This file is licensed to you under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License. You may obtain a copy
5of the License at http://www.apache.org/licenses/LICENSE-2.0
6
7Unless required by applicable law or agreed to in writing, software distributed under
8the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9OF ANY KIND, either express or implied. See the License for the specific language
10governing permissions and limitations under the License.
11*/
12
13const base3 = (t, p1, p2, p3, p4) => {
14 const t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4,
15 t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3;
16 return t * t2 - 3 * p1 + 3 * p2;
17};
18
19const belzen = exports.bezlen = (x1, y1, x2, y2, x3, y3, x4, y4, z) => {
20 if (z == null) {
21 z = 1;
22 }
23 z = z > 1 ? 1 : z < 0 ? 0 : z;
24 var z2 = z / 2,
25 n = 12,
26 Tvalues = [-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],
27 Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472],
28 sum = 0;
29 for (var i = 0; i < n; i++) {
30 var ct = z2 * Tvalues[i] + z2,
31 xbase = base3(ct, x1, x2, x3, x4),
32 ybase = base3(ct, y1, y2, y3, y4),
33 comb = xbase * xbase + ybase * ybase;
34 sum += Cvalues[i] * Math.sqrt(comb);
35 }
36 return z2 * sum;
37};
38
39const findDotsAtSegment = exports.findDotsAtSegment = (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) => {
40 const t1 = 1 - t,
41 t12 = t1 * t1,
42 t13 = t12 * t1,
43 t2 = t * t,
44 t3 = t2 * t,
45 x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x,
46 y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y;
47 return {
48 x: x,
49 y: y
50 };
51};
52
53const catmullRom2bezier = exports.catmullRom2bezier = (crp, z) => {
54 const d = [];
55 let end = {x: +crp[0], y: +crp[1]};
56 for (let i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) {
57 const p = [
58 {x: +crp[i - 2], y: +crp[i - 1]},
59 {x: +crp[i], y: +crp[i + 1]},
60 {x: +crp[i + 2], y: +crp[i + 3]},
61 {x: +crp[i + 4], y: +crp[i + 5]}
62 ];
63 if (z) {
64 if (!i) {
65 p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]};
66 } else if (iLen - 4 == i) {
67 p[3] = {x: +crp[0], y: +crp[1]};
68 } else if (iLen - 2 == i) {
69 p[2] = {x: +crp[0], y: +crp[1]};
70 p[3] = {x: +crp[2], y: +crp[3]};
71 }
72 } else {
73 if (iLen - 4 == i) {
74 p[3] = p[2];
75 } else if (!i) {
76 p[0] = {x: +crp[i], y: +crp[i + 1]};
77 }
78 }
79 d.push([
80 end.x,
81 end.y,
82 (-p[0].x + 6 * p[1].x + p[2].x) / 6,
83 (-p[0].y + 6 * p[1].y + p[2].y) / 6,
84 (p[1].x + 6 * p[2].x - p[3].x) / 6,
85 (p[1].y + 6 * p[2].y - p[3].y) / 6,
86 p[2].x,
87 p[2].y
88 ]);
89 end = p[2];
90 }
91
92 return d;
93};
94
95const prepareCurve = exports.prepareCurve = (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) => {
96 const len = Math.floor(bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) * .75);
97 const map = new Map;
98 for (let i = 0; i <= len; i++) {
99 const t = i / len;
100 map.set(t, findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t));
101 }
102 return x => {
103 const keys = Array.from(map.keys());
104 let p = map.get(keys[0]);
105 const last = map.get(keys[keys.length - 1]);
106 if (x < p.x || x > last.x) {
107 return null;
108 }
109 for (let i = 0; i < keys.length; i++) {
110 const value = map.get(keys[i]);
111 if (value.x >= x) {
112 const x1 = p.x;
113 const x2 = value.x;
114 const y1 = p.y;
115 const y2 = value.y;
116 if (!i) {
117 return y2;
118 }
119 return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
120 }
121 p = value;
122 }
123 };
124};