Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/common/Geometry.js

Issue 2626143004: DevTools: move from Common module - Geometry and CSSShadowModel (Closed)
Patch Set: minimize test diff Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 Common.Geometry = {};
31
32 /**
33 * @type {number}
34 */
35 Common.Geometry._Eps = 1e-5;
36
37 /**
38 * @unrestricted
39 */
40 Common.Geometry.Vector = class {
41 /**
42 * @param {number} x
43 * @param {number} y
44 * @param {number} z
45 */
46 constructor(x, y, z) {
47 this.x = x;
48 this.y = y;
49 this.z = z;
50 }
51
52 /**
53 * @return {number}
54 */
55 length() {
56 return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
57 }
58
59 normalize() {
60 var length = this.length();
61 if (length <= Common.Geometry._Eps)
62 return;
63
64 this.x /= length;
65 this.y /= length;
66 this.z /= length;
67 }
68 };
69
70 /**
71 * @unrestricted
72 */
73 Common.Geometry.Point = class {
74 /**
75 * @param {number} x
76 * @param {number} y
77 */
78 constructor(x, y) {
79 this.x = x;
80 this.y = y;
81 }
82
83 /**
84 * @param {!Common.Geometry.Point} p
85 * @return {number}
86 */
87 distanceTo(p) {
88 return Math.sqrt(Math.pow(p.x - this.x, 2) + Math.pow(p.y - this.y, 2));
89 }
90
91 /**
92 * @param {!Common.Geometry.Point} line
93 * @return {!Common.Geometry.Point}
94 */
95 projectOn(line) {
96 if (line.x === 0 && line.y === 0)
97 return new Common.Geometry.Point(0, 0);
98 return line.scale((this.x * line.x + this.y * line.y) / (Math.pow(line.x, 2) + Math.pow(line.y, 2)));
99 }
100
101 /**
102 * @param {number} scalar
103 * @return {!Common.Geometry.Point}
104 */
105 scale(scalar) {
106 return new Common.Geometry.Point(this.x * scalar, this.y * scalar);
107 }
108
109 /**
110 * @override
111 * @return {string}
112 */
113 toString() {
114 return Math.round(this.x * 100) / 100 + ', ' + Math.round(this.y * 100) / 10 0;
115 }
116 };
117
118 /**
119 * @unrestricted
120 */
121 Common.Geometry.CubicBezier = class {
122 /**
123 * @param {!Common.Geometry.Point} point1
124 * @param {!Common.Geometry.Point} point2
125 */
126 constructor(point1, point2) {
127 this.controlPoints = [point1, point2];
128 }
129
130 /**
131 * @param {string} text
132 * @return {?Common.Geometry.CubicBezier}
133 */
134 static parse(text) {
135 var keywordValues = Common.Geometry.CubicBezier.KeywordValues;
136 var value = text.toLowerCase().replace(/\s+/g, '');
137 if (Object.keys(keywordValues).indexOf(value) !== -1)
138 return Common.Geometry.CubicBezier.parse(keywordValues[value]);
139 var bezierRegex = /^cubic-bezier\(([^,]+),([^,]+),([^,]+),([^,]+)\)$/;
140 var match = value.match(bezierRegex);
141 if (match) {
142 var control1 = new Common.Geometry.Point(parseFloat(match[1]), parseFloat( match[2]));
143 var control2 = new Common.Geometry.Point(parseFloat(match[3]), parseFloat( match[4]));
144 return new Common.Geometry.CubicBezier(control1, control2);
145 }
146 return null;
147 }
148
149 /**
150 * @param {number} t
151 * @return {!Common.Geometry.Point}
152 */
153 evaluateAt(t) {
154 /**
155 * @param {number} v1
156 * @param {number} v2
157 * @param {number} t
158 */
159 function evaluate(v1, v2, t) {
160 return 3 * (1 - t) * (1 - t) * t * v1 + 3 * (1 - t) * t * t * v2 + Math.po w(t, 3);
161 }
162
163 var x = evaluate(this.controlPoints[0].x, this.controlPoints[1].x, t);
164 var y = evaluate(this.controlPoints[0].y, this.controlPoints[1].y, t);
165 return new Common.Geometry.Point(x, y);
166 }
167
168 /**
169 * @return {string}
170 */
171 asCSSText() {
172 var raw = 'cubic-bezier(' + this.controlPoints.join(', ') + ')';
173 var keywordValues = Common.Geometry.CubicBezier.KeywordValues;
174 for (var keyword in keywordValues) {
175 if (raw === keywordValues[keyword])
176 return keyword;
177 }
178 return raw;
179 }
180 };
181
182 /** @type {!RegExp} */
183 Common.Geometry.CubicBezier.Regex = /((cubic-bezier\([^)]+\))|\b(linear|ease-in- out|ease-in|ease-out|ease)\b)/g;
184
185 Common.Geometry.CubicBezier.KeywordValues = {
186 'linear': 'cubic-bezier(0, 0, 1, 1)',
187 'ease': 'cubic-bezier(0.25, 0.1, 0.25, 1)',
188 'ease-in': 'cubic-bezier(0.42, 0, 1, 1)',
189 'ease-in-out': 'cubic-bezier(0.42, 0, 0.58, 1)',
190 'ease-out': 'cubic-bezier(0, 0, 0.58, 1)'
191 };
192
193
194 /**
195 * @unrestricted
196 */
197 Common.Geometry.EulerAngles = class {
198 /**
199 * @param {number} alpha
200 * @param {number} beta
201 * @param {number} gamma
202 */
203 constructor(alpha, beta, gamma) {
204 this.alpha = alpha;
205 this.beta = beta;
206 this.gamma = gamma;
207 }
208
209 /**
210 * @param {!CSSMatrix} rotationMatrix
211 * @return {!Common.Geometry.EulerAngles}
212 */
213 static fromRotationMatrix(rotationMatrix) {
214 var beta = Math.atan2(rotationMatrix.m23, rotationMatrix.m33);
215 var gamma = Math.atan2(
216 -rotationMatrix.m13,
217 Math.sqrt(rotationMatrix.m11 * rotationMatrix.m11 + rotationMatrix.m12 * rotationMatrix.m12));
218 var alpha = Math.atan2(rotationMatrix.m12, rotationMatrix.m11);
219 return new Common.Geometry.EulerAngles(
220 Common.Geometry.radiansToDegrees(alpha), Common.Geometry.radiansToDegree s(beta),
221 Common.Geometry.radiansToDegrees(gamma));
222 }
223
224 /**
225 * @return {string}
226 */
227 toRotate3DString() {
228 var gammaAxisY = -Math.sin(Common.Geometry.degreesToRadians(this.beta));
229 var gammaAxisZ = Math.cos(Common.Geometry.degreesToRadians(this.beta));
230 var axis = {alpha: [0, 1, 0], beta: [-1, 0, 0], gamma: [0, gammaAxisY, gamma AxisZ]};
231 return 'rotate3d(' + axis.alpha.join(',') + ',' + this.alpha + 'deg) ' +
232 'rotate3d(' + axis.beta.join(',') + ',' + this.beta + 'deg) ' +
233 'rotate3d(' + axis.gamma.join(',') + ',' + this.gamma + 'deg)';
234 }
235 };
236
237
238 /**
239 * @param {!Common.Geometry.Vector} u
240 * @param {!Common.Geometry.Vector} v
241 * @return {number}
242 */
243 Common.Geometry.scalarProduct = function(u, v) {
244 return u.x * v.x + u.y * v.y + u.z * v.z;
245 };
246
247 /**
248 * @param {!Common.Geometry.Vector} u
249 * @param {!Common.Geometry.Vector} v
250 * @return {!Common.Geometry.Vector}
251 */
252 Common.Geometry.crossProduct = function(u, v) {
253 var x = u.y * v.z - u.z * v.y;
254 var y = u.z * v.x - u.x * v.z;
255 var z = u.x * v.y - u.y * v.x;
256 return new Common.Geometry.Vector(x, y, z);
257 };
258
259 /**
260 * @param {!Common.Geometry.Vector} u
261 * @param {!Common.Geometry.Vector} v
262 * @return {!Common.Geometry.Vector}
263 */
264 Common.Geometry.subtract = function(u, v) {
265 var x = u.x - v.x;
266 var y = u.y - v.y;
267 var z = u.z - v.z;
268 return new Common.Geometry.Vector(x, y, z);
269 };
270
271 /**
272 * @param {!Common.Geometry.Vector} v
273 * @param {!CSSMatrix} m
274 * @return {!Common.Geometry.Vector}
275 */
276 Common.Geometry.multiplyVectorByMatrixAndNormalize = function(v, m) {
277 var t = v.x * m.m14 + v.y * m.m24 + v.z * m.m34 + m.m44;
278 var x = (v.x * m.m11 + v.y * m.m21 + v.z * m.m31 + m.m41) / t;
279 var y = (v.x * m.m12 + v.y * m.m22 + v.z * m.m32 + m.m42) / t;
280 var z = (v.x * m.m13 + v.y * m.m23 + v.z * m.m33 + m.m43) / t;
281 return new Common.Geometry.Vector(x, y, z);
282 };
283
284 /**
285 * @param {!Common.Geometry.Vector} u
286 * @param {!Common.Geometry.Vector} v
287 * @return {number}
288 */
289 Common.Geometry.calculateAngle = function(u, v) {
290 var uLength = u.length();
291 var vLength = v.length();
292 if (uLength <= Common.Geometry._Eps || vLength <= Common.Geometry._Eps)
293 return 0;
294 var cos = Common.Geometry.scalarProduct(u, v) / uLength / vLength;
295 if (Math.abs(cos) > 1)
296 return 0;
297 return Common.Geometry.radiansToDegrees(Math.acos(cos));
298 };
299
300 /**
301 * @param {number} deg
302 * @return {number}
303 */
304 Common.Geometry.degreesToRadians = function(deg) {
305 return deg * Math.PI / 180;
306 };
307
308 /**
309 * @param {number} rad
310 * @return {number}
311 */
312 Common.Geometry.radiansToDegrees = function(rad) {
313 return rad * 180 / Math.PI;
314 };
315
316 /**
317 * @param {!CSSMatrix} matrix
318 * @param {!Array.<number>} points
319 * @param {{minX: number, maxX: number, minY: number, maxY: number}=} aggregateB ounds
320 * @return {!{minX: number, maxX: number, minY: number, maxY: number}}
321 */
322 Common.Geometry.boundsForTransformedPoints = function(matrix, points, aggregateB ounds) {
323 if (!aggregateBounds)
324 aggregateBounds = {minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -I nfinity};
325 if (points.length % 3)
326 console.assert('Invalid size of points array');
327 for (var p = 0; p < points.length; p += 3) {
328 var vector = new Common.Geometry.Vector(points[p], points[p + 1], points[p + 2]);
329 vector = Common.Geometry.multiplyVectorByMatrixAndNormalize(vector, matrix);
330 aggregateBounds.minX = Math.min(aggregateBounds.minX, vector.x);
331 aggregateBounds.maxX = Math.max(aggregateBounds.maxX, vector.x);
332 aggregateBounds.minY = Math.min(aggregateBounds.minY, vector.y);
333 aggregateBounds.maxY = Math.max(aggregateBounds.maxY, vector.y);
334 }
335 return aggregateBounds;
336 };
337
338 /**
339 * @unrestricted
340 */
341 var Size = class {
342 /**
343 * @param {number} width
344 * @param {number} height
345 */
346 constructor(width, height) {
347 this.width = width;
348 this.height = height;
349 }
350 };
351
352 /**
353 * @param {?Size} size
354 * @return {boolean}
355 */
356 Size.prototype.isEqual = function(size) {
357 return !!size && this.width === size.width && this.height === size.height;
358 };
359
360 /**
361 * @param {!Size|number} size
362 * @return {!Size}
363 */
364 Size.prototype.widthToMax = function(size) {
365 return new Size(Math.max(this.width, (typeof size === 'number' ? size : size.w idth)), this.height);
366 };
367
368 /**
369 * @param {!Size|number} size
370 * @return {!Size}
371 */
372 Size.prototype.addWidth = function(size) {
373 return new Size(this.width + (typeof size === 'number' ? size : size.width), t his.height);
374 };
375
376 /**
377 * @param {!Size|number} size
378 * @return {!Size}
379 */
380 Size.prototype.heightToMax = function(size) {
381 return new Size(this.width, Math.max(this.height, (typeof size === 'number' ? size : size.height)));
382 };
383
384 /**
385 * @param {!Size|number} size
386 * @return {!Size}
387 */
388 Size.prototype.addHeight = function(size) {
389 return new Size(this.width, this.height + (typeof size === 'number' ? size : s ize.height));
390 };
391
392 /**
393 * @unrestricted
394 */
395 var Insets = class {
396 /**
397 * @param {number} left
398 * @param {number} top
399 * @param {number} right
400 * @param {number} bottom
401 */
402 constructor(left, top, right, bottom) {
403 this.left = left;
404 this.top = top;
405 this.right = right;
406 this.bottom = bottom;
407 }
408
409 /**
410 * @param {?Insets} insets
411 * @return {boolean}
412 */
413 isEqual(insets) {
414 return !!insets && this.left === insets.left && this.top === insets.top && t his.right === insets.right &&
415 this.bottom === insets.bottom;
416 }
417 };
418
419 /**
420 * @unrestricted
421 */
422 Common.Rect = class {
423 /**
424 * @param {number} left
425 * @param {number} top
426 * @param {number} width
427 * @param {number} height
428 */
429 constructor(left, top, width, height) {
430 this.left = left;
431 this.top = top;
432 this.width = width;
433 this.height = height;
434 }
435
436 /**
437 * @param {?Common.Rect} rect
438 * @return {boolean}
439 */
440 isEqual(rect) {
441 return !!rect && this.left === rect.left && this.top === rect.top && this.wi dth === rect.width &&
442 this.height === rect.height;
443 }
444
445 /**
446 * @param {number} scale
447 * @return {!Common.Rect}
448 */
449 scale(scale) {
450 return new Common.Rect(this.left * scale, this.top * scale, this.width * sca le, this.height * scale);
451 }
452
453 /**
454 * @return {!Size}
455 */
456 size() {
457 return new Size(this.width, this.height);
458 }
459 };
460
461 /**
462 * @unrestricted
463 */
464 var Constraints = class {
465 /**
466 * @param {!Size=} minimum
467 * @param {?Size=} preferred
468 */
469 constructor(minimum, preferred) {
470 /**
471 * @type {!Size}
472 */
473 this.minimum = minimum || new Size(0, 0);
474
475 /**
476 * @type {!Size}
477 */
478 this.preferred = preferred || this.minimum;
479
480 if (this.minimum.width > this.preferred.width || this.minimum.height > this. preferred.height)
481 throw new Error('Minimum size is greater than preferred.');
482 }
483 };
484
485 /**
486 * @param {?Constraints} constraints
487 * @return {boolean}
488 */
489 Constraints.prototype.isEqual = function(constraints) {
490 return !!constraints && this.minimum.isEqual(constraints.minimum) && this.pref erred.isEqual(constraints.preferred);
491 };
492
493 /**
494 * @param {!Constraints|number} value
495 * @return {!Constraints}
496 */
497 Constraints.prototype.widthToMax = function(value) {
498 if (typeof value === 'number')
499 return new Constraints(this.minimum.widthToMax(value), this.preferred.widthT oMax(value));
500 return new Constraints(this.minimum.widthToMax(value.minimum), this.preferred. widthToMax(value.preferred));
501 };
502
503 /**
504 * @param {!Constraints|number} value
505 * @return {!Constraints}
506 */
507 Constraints.prototype.addWidth = function(value) {
508 if (typeof value === 'number')
509 return new Constraints(this.minimum.addWidth(value), this.preferred.addWidth (value));
510 return new Constraints(this.minimum.addWidth(value.minimum), this.preferred.ad dWidth(value.preferred));
511 };
512
513 /**
514 * @param {!Constraints|number} value
515 * @return {!Constraints}
516 */
517 Constraints.prototype.heightToMax = function(value) {
518 if (typeof value === 'number')
519 return new Constraints(this.minimum.heightToMax(value), this.preferred.heigh tToMax(value));
520 return new Constraints(this.minimum.heightToMax(value.minimum), this.preferred .heightToMax(value.preferred));
521 };
522
523 /**
524 * @param {!Constraints|number} value
525 * @return {!Constraints}
526 */
527 Constraints.prototype.addHeight = function(value) {
528 if (typeof value === 'number')
529 return new Constraints(this.minimum.addHeight(value), this.preferred.addHeig ht(value));
530 return new Constraints(this.minimum.addHeight(value.minimum), this.preferred.a ddHeight(value.preferred));
531 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698