|
1 | 1 | import "../color/color"; |
2 | | -import "../color/hcl"; |
3 | | -import "../color/hsl"; |
4 | | -import "../color/lab"; |
5 | 2 | import "../color/rgb"; |
6 | | -import "../math/transform"; |
| 3 | +import "rgb"; |
| 4 | +import "transform"; |
| 5 | +import "object"; |
| 6 | +import "array"; |
| 7 | +import "number"; |
| 8 | +import "string"; |
7 | 9 |
|
8 | | -d3.interpolate = function(a, b) { |
| 10 | +d3.interpolate = d3_interpolate; |
| 11 | + |
| 12 | +function d3_interpolate(a, b) { |
9 | 13 | var i = d3.interpolators.length, f; |
10 | 14 | while (--i >= 0 && !(f = d3.interpolators[i](a, b))); |
11 | 15 | return f; |
12 | | -}; |
13 | | - |
14 | | -d3.interpolateNumber = function(a, b) { |
15 | | - b -= a; |
16 | | - return function(t) { return a + b * t; }; |
17 | | -}; |
18 | | - |
19 | | -d3.interpolateRound = function(a, b) { |
20 | | - b -= a; |
21 | | - return function(t) { return Math.round(a + b * t); }; |
22 | | -}; |
23 | | - |
24 | | -d3.interpolateString = function(a, b) { |
25 | | - var m, // current match |
26 | | - i, // current index |
27 | | - j, // current index (for coalescing) |
28 | | - s0 = 0, // start index of current string prefix |
29 | | - s1 = 0, // end index of current string prefix |
30 | | - s = [], // string constants and placeholders |
31 | | - q = [], // number interpolators |
32 | | - n, // q.length |
33 | | - o; |
34 | | - |
35 | | - // Reset our regular expression! |
36 | | - d3_interpolate_number.lastIndex = 0; |
37 | | - |
38 | | - // Find all numbers in b. |
39 | | - for (i = 0; m = d3_interpolate_number.exec(b); ++i) { |
40 | | - if (m.index) s.push(b.substring(s0, s1 = m.index)); |
41 | | - q.push({i: s.length, x: m[0]}); |
42 | | - s.push(null); |
43 | | - s0 = d3_interpolate_number.lastIndex; |
44 | | - } |
45 | | - if (s0 < b.length) s.push(b.substring(s0)); |
46 | | - |
47 | | - // Find all numbers in a. |
48 | | - for (i = 0, n = q.length; (m = d3_interpolate_number.exec(a)) && i < n; ++i) { |
49 | | - o = q[i]; |
50 | | - if (o.x == m[0]) { // The numbers match, so coalesce. |
51 | | - if (o.i) { |
52 | | - if (s[o.i + 1] == null) { // This match is followed by another number. |
53 | | - s[o.i - 1] += o.x; |
54 | | - s.splice(o.i, 1); |
55 | | - for (j = i + 1; j < n; ++j) q[j].i--; |
56 | | - } else { // This match is followed by a string, so coalesce twice. |
57 | | - s[o.i - 1] += o.x + s[o.i + 1]; |
58 | | - s.splice(o.i, 2); |
59 | | - for (j = i + 1; j < n; ++j) q[j].i -= 2; |
60 | | - } |
61 | | - } else { |
62 | | - if (s[o.i + 1] == null) { // This match is followed by another number. |
63 | | - s[o.i] = o.x; |
64 | | - } else { // This match is followed by a string, so coalesce twice. |
65 | | - s[o.i] = o.x + s[o.i + 1]; |
66 | | - s.splice(o.i + 1, 1); |
67 | | - for (j = i + 1; j < n; ++j) q[j].i--; |
68 | | - } |
69 | | - } |
70 | | - q.splice(i, 1); |
71 | | - n--; |
72 | | - i--; |
73 | | - } else { |
74 | | - o.x = d3.interpolateNumber(parseFloat(m[0]), parseFloat(o.x)); |
75 | | - } |
76 | | - } |
77 | | - |
78 | | - // Remove any numbers in b not found in a. |
79 | | - while (i < n) { |
80 | | - o = q.pop(); |
81 | | - if (s[o.i + 1] == null) { // This match is followed by another number. |
82 | | - s[o.i] = o.x; |
83 | | - } else { // This match is followed by a string, so coalesce twice. |
84 | | - s[o.i] = o.x + s[o.i + 1]; |
85 | | - s.splice(o.i + 1, 1); |
86 | | - } |
87 | | - n--; |
88 | | - } |
89 | | - |
90 | | - // Special optimization for only a single match. |
91 | | - if (s.length === 1) { |
92 | | - return s[0] == null ? q[0].x : function() { return b; }; |
93 | | - } |
94 | | - |
95 | | - // Otherwise, interpolate each of the numbers and rejoin the string. |
96 | | - return function(t) { |
97 | | - for (i = 0; i < n; ++i) s[(o = q[i]).i] = o.x(t); |
98 | | - return s.join(""); |
99 | | - }; |
100 | | -}; |
101 | | - |
102 | | -d3.interpolateTransform = function(a, b) { |
103 | | - var s = [], // string constants and placeholders |
104 | | - q = [], // number interpolators |
105 | | - n, |
106 | | - A = d3.transform(a), |
107 | | - B = d3.transform(b), |
108 | | - ta = A.translate, |
109 | | - tb = B.translate, |
110 | | - ra = A.rotate, |
111 | | - rb = B.rotate, |
112 | | - wa = A.skew, |
113 | | - wb = B.skew, |
114 | | - ka = A.scale, |
115 | | - kb = B.scale; |
116 | | - |
117 | | - if (ta[0] != tb[0] || ta[1] != tb[1]) { |
118 | | - s.push("translate(", null, ",", null, ")"); |
119 | | - q.push({i: 1, x: d3.interpolateNumber(ta[0], tb[0])}, {i: 3, x: d3.interpolateNumber(ta[1], tb[1])}); |
120 | | - } else if (tb[0] || tb[1]) { |
121 | | - s.push("translate(" + tb + ")"); |
122 | | - } else { |
123 | | - s.push(""); |
124 | | - } |
125 | | - |
126 | | - if (ra != rb) { |
127 | | - if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; // shortest path |
128 | | - q.push({i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3.interpolateNumber(ra, rb)}); |
129 | | - } else if (rb) { |
130 | | - s.push(s.pop() + "rotate(" + rb + ")"); |
131 | | - } |
132 | | - |
133 | | - if (wa != wb) { |
134 | | - q.push({i: s.push(s.pop() + "skewX(", null, ")") - 2, x: d3.interpolateNumber(wa, wb)}); |
135 | | - } else if (wb) { |
136 | | - s.push(s.pop() + "skewX(" + wb + ")"); |
137 | | - } |
138 | | - |
139 | | - if (ka[0] != kb[0] || ka[1] != kb[1]) { |
140 | | - n = s.push(s.pop() + "scale(", null, ",", null, ")"); |
141 | | - q.push({i: n - 4, x: d3.interpolateNumber(ka[0], kb[0])}, {i: n - 2, x: d3.interpolateNumber(ka[1], kb[1])}); |
142 | | - } else if (kb[0] != 1 || kb[1] != 1) { |
143 | | - s.push(s.pop() + "scale(" + kb + ")"); |
144 | | - } |
145 | | - |
146 | | - n = q.length; |
147 | | - return function(t) { |
148 | | - var i = -1, o; |
149 | | - while (++i < n) s[(o = q[i]).i] = o.x(t); |
150 | | - return s.join(""); |
151 | | - }; |
152 | | -}; |
153 | | - |
154 | | -d3.interpolateRgb = function(a, b) { |
155 | | - a = d3.rgb(a); |
156 | | - b = d3.rgb(b); |
157 | | - var ar = a.r, |
158 | | - ag = a.g, |
159 | | - ab = a.b, |
160 | | - br = b.r - ar, |
161 | | - bg = b.g - ag, |
162 | | - bb = b.b - ab; |
163 | | - return function(t) { |
164 | | - return "#" |
165 | | - + d3_rgb_hex(Math.round(ar + br * t)) |
166 | | - + d3_rgb_hex(Math.round(ag + bg * t)) |
167 | | - + d3_rgb_hex(Math.round(ab + bb * t)); |
168 | | - }; |
169 | | -}; |
170 | | - |
171 | | -// interpolates HSL space, but outputs RGB string (for compatibility) |
172 | | -d3.interpolateHsl = function(a, b) { |
173 | | - a = d3.hsl(a); |
174 | | - b = d3.hsl(b); |
175 | | - var h0 = a.h, |
176 | | - s0 = a.s, |
177 | | - l0 = a.l, |
178 | | - h1 = b.h - h0, |
179 | | - s1 = b.s - s0, |
180 | | - l1 = b.l - l0; |
181 | | - if (h1 > 180) h1 -= 360; else if (h1 < -180) h1 += 360; // shortest path |
182 | | - return function(t) { |
183 | | - return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t) + ""; |
184 | | - }; |
185 | | -}; |
186 | | - |
187 | | -d3.interpolateLab = function(a, b) { |
188 | | - a = d3.lab(a); |
189 | | - b = d3.lab(b); |
190 | | - var al = a.l, |
191 | | - aa = a.a, |
192 | | - ab = a.b, |
193 | | - bl = b.l - al, |
194 | | - ba = b.a - aa, |
195 | | - bb = b.b - ab; |
196 | | - return function(t) { |
197 | | - return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; |
198 | | - }; |
199 | | -}; |
200 | | - |
201 | | -d3.interpolateHcl = function(a, b) { |
202 | | - a = d3.hcl(a); |
203 | | - b = d3.hcl(b); |
204 | | - var ah = a.h, |
205 | | - ac = a.c, |
206 | | - al = a.l, |
207 | | - bh = b.h - ah, |
208 | | - bc = b.c - ac, |
209 | | - bl = b.l - al; |
210 | | - if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; // shortest path |
211 | | - return function(t) { |
212 | | - return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; |
213 | | - }; |
214 | | -}; |
215 | | - |
216 | | -d3.interpolateArray = function(a, b) { |
217 | | - var x = [], |
218 | | - c = [], |
219 | | - na = a.length, |
220 | | - nb = b.length, |
221 | | - n0 = Math.min(a.length, b.length), |
222 | | - i; |
223 | | - for (i = 0; i < n0; ++i) x.push(d3.interpolate(a[i], b[i])); |
224 | | - for (; i < na; ++i) c[i] = a[i]; |
225 | | - for (; i < nb; ++i) c[i] = b[i]; |
226 | | - return function(t) { |
227 | | - for (i = 0; i < n0; ++i) c[i] = x[i](t); |
228 | | - return c; |
229 | | - }; |
230 | | -}; |
231 | | - |
232 | | -d3.interpolateObject = function(a, b) { |
233 | | - var i = {}, |
234 | | - c = {}, |
235 | | - k; |
236 | | - for (k in a) { |
237 | | - if (k in b) { |
238 | | - i[k] = d3_interpolateByName(k)(a[k], b[k]); |
239 | | - } else { |
240 | | - c[k] = a[k]; |
241 | | - } |
242 | | - } |
243 | | - for (k in b) { |
244 | | - if (!(k in a)) { |
245 | | - c[k] = b[k]; |
246 | | - } |
247 | | - } |
248 | | - return function(t) { |
249 | | - for (k in i) c[k] = i[k](t); |
250 | | - return c; |
251 | | - }; |
252 | | -}; |
253 | | - |
254 | | -var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; |
| 16 | +} |
255 | 17 |
|
256 | 18 | function d3_interpolateByName(name) { |
257 | 19 | return name == "transform" |
258 | | - ? d3.interpolateTransform |
259 | | - : d3.interpolate; |
| 20 | + ? d3_interpolateTransform |
| 21 | + : d3_interpolate; |
260 | 22 | } |
261 | 23 |
|
262 | 24 | d3.interpolators = [ |
263 | | - d3.interpolateObject, |
264 | | - function(a, b) { return Array.isArray(b) && d3.interpolateArray(a, b); }, |
265 | | - function(a, b) { return (typeof a === "string" || typeof b === "string") && d3.interpolateString(a + "", b + ""); }, |
266 | | - function(a, b) { return (typeof b === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Color) && d3.interpolateRgb(a, b); }, |
267 | | - function(a, b) { return !isNaN(a = +a) && !isNaN(b = +b) && d3.interpolateNumber(a, b); } |
| 25 | + d3_interpolateObject, |
| 26 | + function(a, b) { return Array.isArray(b) && d3_interpolateArray(a, b); }, |
| 27 | + function(a, b) { return (typeof a === "string" || typeof b === "string") && d3_interpolateString(a + "", b + ""); }, |
| 28 | + function(a, b) { return (typeof b === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Color) && d3_interpolateRgb(a, b); }, |
| 29 | + function(a, b) { return !isNaN(a = +a) && !isNaN(b = +b) && d3_interpolateNumber(a, b); } |
268 | 30 | ]; |
0 commit comments