tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_distance_of_transform.html (15459B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <script src='/resources/testharness.js'></script>
      4 <script src='/resources/testharnessreport.js'></script>
      5 <script src='../testcommon.js'></script>
      6 <div id='log'></div>
      7 <script type='text/javascript'>
      8 'use strict';
      9 
     10 // We don't have an official spec to define the distance between two transform
     11 // lists, but we still need this for DevTools, so Gecko and Servo backend use
     12 // the similar rules to define the distance. If there is a spec for it, we have
     13 // to update this test file.
     14 
     15 const EPSILON = 0.00001;
     16 
     17 // |v| should be a unit vector (i.e. having length 1)
     18 function getQuaternion(v, angle) {
     19  return [
     20    v[0] * Math.sin(angle / 2.0),
     21    v[1] * Math.sin(angle / 2.0),
     22    v[2] * Math.sin(angle / 2.0),
     23    Math.cos(angle / 2.0)
     24  ];
     25 }
     26 
     27 function computeRotateDistance(q1, q2) {
     28  const dot = q1.reduce((sum, e, i) => sum + e * q2[i], 0);
     29  return Math.acos(Math.min(Math.max(dot, -1.0), 1.0)) * 2.0;
     30 }
     31 
     32 function createMatrixFromArray(array) {
     33  return (array.length === 16 ? 'matrix3d' : 'matrix') + `(${array.join()})`;
     34 }
     35 
     36 function rotate3dToMatrix(x, y, z, radian) {
     37  var sc = Math.sin(radian / 2) * Math.cos(radian / 2);
     38  var sq = Math.sin(radian / 2) * Math.sin(radian / 2);
     39 
     40  // Normalize the vector.
     41  var length = Math.sqrt(x*x + y*y + z*z);
     42  x /= length;
     43  y /= length;
     44  z /= length;
     45 
     46  return [
     47    1 - 2 * (y*y + z*z) * sq,
     48    2 * (x * y * sq + z * sc),
     49    2 * (x * z * sq - y * sc),
     50    0,
     51    2 * (x * y * sq - z * sc),
     52    1 - 2 * (x*x + z*z) * sq,
     53    2 * (y * z * sq + x * sc),
     54    0,
     55    2 * (x * z * sq + y * sc),
     56    2 * (y * z * sq - x * sc),
     57    1 - 2 * (x*x + y*y) * sq,
     58    0,
     59    0,
     60    0,
     61    0,
     62    1
     63  ];
     64 }
     65 
     66 test(function(t) {
     67  var target = addDiv(t);
     68  var dist = getDistance(target, 'transform', 'none', 'none');
     69  assert_equals(dist, 0, 'distance of translate');
     70 }, 'Test distance of none and none');
     71 
     72 test(function(t) {
     73  var target = addDiv(t);
     74  var dist = getDistance(target, 'transform', 'translate(100px)', 'none');
     75  assert_equals(dist, 100, 'distance of translate');
     76 }, 'Test distance of translate function and none');
     77 
     78 test(function(t) {
     79  var target = addDiv(t);
     80  var dist =
     81    getDistance(target, 'transform', 'translate(100px)', 'translate(200px)');
     82  assert_equals(dist, 200 - 100, 'distance of translate');
     83 }, 'Test distance of translate functions');
     84 
     85 test(function(t) {
     86  var target = addDiv(t);
     87  var dist =
     88    getDistance(target, 'transform', 'translate3d(100px, 0, 50px)', 'none');
     89  assert_equals(dist, Math.sqrt(100 * 100 + 50 * 50),
     90                'distance of translate3d');
     91 }, 'Test distance of translate3d function and none');
     92 
     93 test(function(t) {
     94  var target = addDiv(t);
     95  var dist =
     96    getDistance(target, 'transform',
     97                'translate3d(100px, 0, 50px)',
     98                'translate3d(200px, 80px, 0)');
     99  assert_equals(dist, Math.sqrt(100 * 100 + 80 * 80 + 50 * 50),
    100                'distance of translate');
    101 }, 'Test distance of translate3d functions');
    102 
    103 test(function(t) {
    104  var target = addDiv(t);
    105  var dist = getDistance(target, 'transform', 'scale(1.5)', 'none');
    106  assert_equals(dist, Math.sqrt(0.5 * 0.5 + 0.5 * 0.5), 'distance of scale');
    107 }, 'Test distance of scale function and none');
    108 
    109 test(function(t) {
    110  var target = addDiv(t);
    111  var dist = getDistance(target, 'transform', 'scale(1.5)', 'scale(2.0)');
    112  assert_equals(dist, Math.sqrt(0.5 * 0.5 + 0.5 * 0.5), 'distance of scale');
    113 }, 'Test distance of scale functions');
    114 
    115 test(function(t) {
    116  var target = addDiv(t);
    117  var dist = getDistance(target, 'transform',
    118                         'scale3d(1.5, 1.5, 1.5)',
    119                         'none');
    120  assert_equals(dist,
    121                Math.sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5),
    122                'distance of scale3d');
    123 }, 'Test distance of scale3d function and none');
    124 
    125 test(function(t) {
    126  var target = addDiv(t);
    127  var dist = getDistance(target, 'transform',
    128                         'scale3d(1.5, 1.5, 1.5)',
    129                         'scale3d(2.0, 2.0, 1.0)');
    130  assert_equals(dist,
    131                Math.sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5),
    132                'distance of scale3d');
    133 }, 'Test distance of scale3d functions');
    134 
    135 test(function(t) {
    136  var target = addDiv(t);
    137  var dist =
    138    getDistance(target, 'transform', 'rotate(45deg)', 'rotate(90deg)');
    139  assert_approx_equals(dist, Math.PI / 2.0 - Math.PI / 4.0, EPSILON, 'distance of rotate');
    140 }, 'Test distance of rotate functions');
    141 
    142 test(function(t) {
    143  var target = addDiv(t);
    144  var dist =
    145    getDistance(target, 'transform', 'rotate(45deg)', 'none');
    146  assert_approx_equals(dist, Math.PI / 4.0, EPSILON, 'distance of rotate');
    147 }, 'Test distance of rotate function and none');
    148 
    149 test(function(t) {
    150  var target = addDiv(t);
    151  var dist = getDistance(target, 'transform',
    152                         'rotate3d(0, 1, 0, 90deg)',
    153                         'none');
    154  assert_approx_equals(dist, Math.PI / 2, EPSILON, 'distance of rotate3d');
    155 }, 'Test distance of rotate3d function and none');
    156 
    157 test(function(t) {
    158  var target = addDiv(t);
    159  var dist = getDistance(target, 'transform',
    160                         'rotate3d(0, 0, 1, 90deg)',
    161                         'rotate3d(1, 0, 0, 90deg)');
    162  let q1 = getQuaternion([0, 0, 1], Math.PI / 2.0);
    163  let q2 = getQuaternion([1, 0, 0], Math.PI / 2.0);
    164  assert_approx_equals(dist, computeRotateDistance(q1, q2), EPSILON, 'distance of rotate3d');
    165 }, 'Test distance of rotate3d functions');
    166 
    167 test(function(t) {
    168  var target = addDiv(t);
    169  var dist = getDistance(target, 'transform',
    170                         'rotate3d(0, 0, 1, 90deg)',
    171                         'rotate3d(0, 0, 0, 90deg)');
    172  assert_approx_equals(dist, Math.PI / 2, EPSILON, 'distance of rotate3d');
    173 }, 'Test distance of rotate3d functions whose direction vector cannot be ' +
    174   'normalized');
    175 
    176 test(function(t) {
    177  var target = addDiv(t);
    178  var dist = getDistance(target, 'transform', 'skew(1rad, 0.5rad)', 'none');
    179  assert_approx_equals(dist, Math.sqrt(1 * 1 + 0.5 * 0.5), EPSILON, 'distance of skew');
    180 }, 'Test distance of skew function and none');
    181 
    182 test(function(t) {
    183  var target = addDiv(t);
    184  var dist = getDistance(target, 'transform',
    185                         'skew(1rad, 0.5rad)',
    186                         'skew(-1rad, 0)');
    187  assert_approx_equals(dist, Math.sqrt(2 * 2 + 0.5 * 0.5), EPSILON, 'distance of skew');
    188 }, 'Test distance of skew functions');
    189 
    190 test(function(t) {
    191  var target = addDiv(t);
    192  var dist = getDistance(target, 'transform',
    193                         'perspective(128px)',
    194                         'none');
    195  assert_equals(dist, Infinity, 'distance of perspective');
    196 }, 'Test distance of perspective function and none');
    197 
    198 test(function(t) {
    199  var target = addDiv(t);
    200  // perspective(0) is treated as perspective(inf) because perspective length
    201  // should be greater than or equal to zero.
    202  var dist = getDistance(target, 'transform',
    203                         'perspective(128px)',
    204                         'perspective(0)');
    205  assert_equals(dist, 128, 'distance of perspective');
    206 }, 'Test distance of perspective function and an invalid perspective');
    207 
    208 test(function(t) {
    209  var target = addDiv(t);
    210  var dist = getDistance(target, 'transform',
    211                         'perspective(128px)',
    212                         'perspective(1024px)');
    213  assert_equals(dist, 1024 - 128, 'distance of perspective');
    214 }, 'Test distance of perspective functions');
    215 
    216 test(function(t) {
    217  var target = addDiv(t);
    218  var sin_30 = Math.sin(Math.PI / 6);
    219  var cos_30 = Math.cos(Math.PI / 6);
    220  // matrix => translate(100, 0) rotate(30deg).
    221  var matrix = createMatrixFromArray([ cos_30, sin_30,
    222                                      -sin_30, cos_30,
    223                                       100, 0 ]);
    224  var dist = getDistance(target, 'transform', matrix, 'none');
    225  assert_approx_equals(dist,
    226                       Math.sqrt(100 * 100 + (Math.PI / 6) * (Math.PI / 6)),
    227                       EPSILON,
    228                       'distance of matrix');
    229 }, 'Test distance of matrix function and none');
    230 
    231 test(function(t) {
    232  var target = addDiv(t);
    233  var sin_30 = Math.sin(Math.PI / 6);
    234  var cos_30 = Math.cos(Math.PI / 6);
    235  // matrix1 => translate(100, 0) rotate(30deg).
    236  var matrix1 = createMatrixFromArray([ cos_30, sin_30,
    237                                       -sin_30, cos_30,
    238                                        100, 0 ]);
    239  // matrix2 => translate(0, 100) scale(0.5).
    240  var matrix2 = createMatrixFromArray([ 0.5, 0, 0, 0.5, 0, 100 ]);
    241  var dist = getDistance(target, 'transform', matrix1, matrix2);
    242  assert_approx_equals(dist,
    243                       Math.sqrt(100 * 100 + 100 * 100 +          // translate
    244                                 (Math.PI / 6) * (Math.PI / 6) +  // rotate
    245                                 0.5 * 0.5 + 0.5 * 0.5),          // scale
    246                       EPSILON,
    247                       'distance of matrix');
    248 }, 'Test distance of matrix functions');
    249 
    250 test(function(t) {
    251  var target = addDiv(t);
    252  var matrix = createMatrixFromArray(rotate3dToMatrix(0, 1, 0, Math.PI / 6));
    253  var dist = getDistance(target, 'transform', matrix, 'none');
    254  assert_approx_equals(dist, Math.PI / 6, EPSILON, 'distance of matrix3d');
    255 }, 'Test distance of matrix3d function and none');
    256 
    257 test(function(t) {
    258  var target = addDiv(t);
    259  // matrix1 => rotate3d(0, 1, 0, 30deg).
    260  var matrix1 = createMatrixFromArray(rotate3dToMatrix(0, 1, 0, Math.PI / 6));
    261  // matrix1 => translate3d(100, 0, 0) scale3d(0.5, 0.5, 0.5).
    262  var matrix2 = createMatrixFromArray([ 0.5, 0, 0, 0,
    263                                        0, 0.5, 0, 0,
    264                                        0, 0, 0.5, 0,
    265                                        100, 0, 0, 1 ]);
    266  var dist = getDistance(target, 'transform', matrix1, matrix2);
    267  assert_approx_equals(dist,
    268                       Math.sqrt(100 * 100 +                      // translate
    269                                 0.5 * 0.5 * 3 +                  // scale
    270                                 (Math.PI / 6) * (Math.PI / 6)),  // rotate
    271                       EPSILON,
    272                       'distance of matrix');
    273 }, 'Test distance of matrix3d functions');
    274 
    275 test(function(t) {
    276  var target = addDiv(t);
    277  var cos_180 = Math.cos(Math.PI);
    278  var sin_180 = Math.sin(Math.PI);
    279  // matrix1 => translate3d(100px, 50px, -10px) skew(45deg).
    280  var matrix1 = createMatrixFromArray([ 1, 0, 0, 0,
    281                                        Math.tan(Math.PI/4.0), 1, 0, 0,
    282                                        0, 0, 1, 0,
    283                                        100, 50, -10, 1]);
    284  // matrix2 => translate3d(1000px, 0, 0) rotate3d(1, 0, 0, 180deg).
    285  var matrix2 = createMatrixFromArray([ 1, 0, 0, 0,
    286                                        0, cos_180, sin_180, 0,
    287                                        0, -sin_180, cos_180, 0,
    288                                        1000, 0, 0, 1 ]);
    289  var dist = getDistance(target, 'transform', matrix1, matrix2);
    290  assert_approx_equals(dist,
    291                       Math.sqrt(900 * 900 + 50 * 50 + 10 * 10 +  // translate
    292                                 Math.PI * Math.PI +              // rotate
    293                                 (Math.PI / 4) * (Math.PI / 4)),  // skew angle
    294                       EPSILON,
    295                       'distance of matrix');
    296 }, 'Test distance of matrix3d functions with skew factors');
    297 
    298 test(function(t) {
    299  var target = addDiv(t);
    300  var dist =
    301    getDistance(target, 'transform',
    302                'rotate(180deg) translate(1000px)',
    303                'rotate(360deg) translate(0px)');
    304  assert_approx_equals(dist, Math.sqrt(1000 * 1000 + Math.PI * Math.PI), EPSILON,
    305                       'distance of transform lists');
    306 }, 'Test distance of transform lists');
    307 
    308 test(function(t) {
    309  var target = addDiv(t);
    310  var dist = getDistance(target, 'transform',
    311                         'translate(100px) rotate(180deg)',
    312                         'translate(50px) rotate(90deg) scale(5) skew(1rad)');
    313  assert_approx_equals(dist,
    314                       Math.sqrt(50 * 50 +
    315                                 Math.PI / 2 * Math.PI / 2 +
    316                                 4 * 4 * 2 +
    317                                 1 * 1),
    318                       EPSILON,
    319                       'distance of transform lists');
    320 }, 'Test distance of transform lists where one has extra items');
    321 
    322 test(function(t) {
    323  var target = addDiv(t);
    324  var dist = getDistance(target, 'transform',
    325                         'translate(1000px) rotate3d(1, 0, 0, 180deg)',
    326                         'translate(1000px) scale3d(2.5, 0.5, 1)');
    327  assert_equals(dist, Math.sqrt(Math.PI * Math.PI + 1.5 * 1.5 + 0.5 * 0.5),
    328                'distance of transform lists');
    329 }, 'Test distance of mismatched transform lists');
    330 
    331 test(function(t) {
    332  var target = addDiv(t);
    333  var dist = getDistance(target, 'transform',
    334                         'translate(100px) skew(1rad)',
    335                         'translate(1000px) rotate3d(0, 1, 0, -2rad)');
    336  assert_approx_equals(dist,
    337                       Math.sqrt(900 * 900 + 1 * 1 + 2 * 2),
    338                       EPSILON,
    339                       'distance of transform lists');
    340 }, 'Test distance of mismatched transform lists with skew function');
    341 
    342 
    343 // Individual transforms
    344 test(function(t) {
    345  var target = addDiv(t);
    346  var dist = getDistance(target, 'translate', '50px', 'none');
    347  assert_equals(dist, Math.sqrt(50 * 50), 'distance of 2D translate and none');
    348 }, 'Test distance of 2D translate property with none');
    349 
    350 test(function(t) {
    351  var target = addDiv(t);
    352  var dist = getDistance(target, 'translate', '10px 30px', '50px');
    353  assert_equals(dist, Math.sqrt(40 * 40 + 30 * 30), 'distance of 2D translate');
    354 }, 'Test distance of 2D translate property');
    355 
    356 test(function(t) {
    357  var target = addDiv(t);
    358  var dist = getDistance(target, 'translate', '10px 30px 50px', '50px');
    359  assert_equals(dist, Math.sqrt(40 * 40 + 30 * 30 + 50 * 50),
    360                'distance of 3D translate');
    361 }, 'Test distance of 3D translate property');
    362 
    363 test(function(t) {
    364  var target = addDiv(t);
    365  var dist = getDistance(target, 'scale', '2', 'none');
    366  assert_equals(dist, Math.sqrt(1 + 1), 'distance of 2D scale and none');
    367 }, 'Test distance of 2D scale property with none');
    368 
    369 test(function(t) {
    370  var target = addDiv(t);
    371  var dist = getDistance(target, 'scale', '3', '1 1');
    372  assert_equals(dist, Math.sqrt(2 * 2 + 2 * 2), 'distance of 2D scale');
    373 }, 'Test distance of 2D scale property');
    374 
    375 test(function(t) {
    376  var target = addDiv(t);
    377  var dist = getDistance(target, 'scale', '3 2 2', '1 1');
    378  assert_equals(dist, Math.sqrt(2 * 2 + 1 * 1 + 1 * 1),
    379                'distance of 3D scale');
    380 }, 'Test distance of 3D scale property');
    381 
    382 test(function(t) {
    383  var target = addDiv(t);
    384  var dist = getDistance(target, 'rotate', '180deg', 'none');
    385  assert_equals(dist, Math.PI, 'distance of 2D rotate and none');
    386 }, 'Test distance of 2D rotate property with none');
    387 
    388 test(function(t) {
    389  var target = addDiv(t);
    390  var dist = getDistance(target, 'rotate', '180deg', '90deg');
    391  assert_equals(dist, Math.PI / 2.0, 'distance of 2D rotate');
    392 }, 'Test distance of 2D rotate property');
    393 
    394 test(function(t) {
    395  var target = addDiv(t);
    396  var dist = getDistance(target, 'rotate', 'z 90deg', 'x 90deg');
    397  let q1 = getQuaternion([0, 0, 1], Math.PI / 2.0);
    398  let q2 = getQuaternion([1, 0, 0], Math.PI / 2.0);
    399  assert_approx_equals(dist, computeRotateDistance(q1, q2), EPSILON,
    400                       'distance of 3D rotate');
    401 }, 'Test distance of 3D rotate property');
    402 
    403 </script>
    404 </html>