tor-browser

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

rotate-composition.html (6259B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title> rotate composition</title>
      4 <link rel="help" href="https://drafts.csswg.org/css-transforms-2/#propdef-rotate">
      5 <meta name="assert" content="rotate supports animation">
      6 
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <script src="/css/support/interpolation-testcommon.js"></script>
     10 
     11 <body>
     12 <script>
     13 // Numerical precision may cause an axis aligned rotation to appear slightly
     14 // misaligned. Convert to (x, y, z, angle) form with rounding for comparison.
     15 function parseRotation(args) {
     16  const array = args.split(' ');
     17  if (array.length == 1) {
     18    // Angle or 'none'.
     19    return !!parseFloat(args) ? roundNumbers('0 0 1 ' + args) : args;
     20  }
     21  if (array.length == 2) {
     22    // Axis name + angle
     23    let axis = array[0];
     24    let angle = array[1];
     25    switch (array[0]) {
     26      case 'x':
     27        axis = '1 0 0 ';
     28        break;
     29      case 'y':
     30        axis = '0 1 0';
     31        break;
     32      case 'z':
     33        axis = '0 0 1';
     34        break;
     35    }
     36    return roundNumbers(axis + ' ' + angle);
     37  }
     38  if (array.length == 4) {
     39    // Axis as [x,y,z] triplet + angle.
     40    // Normalize the axis (if possible) for comparison.
     41    let x = parseFloat(array[0]);
     42    let y = parseFloat(array[1]);
     43    let z = parseFloat(array[2]);
     44    const angle = array[3];
     45    const length = Math.sqrt(x*x + y*y + z*z);
     46    if (length > 1e-4) {
     47      x /= length;
     48      y /= length;
     49      z /= length;
     50    }
     51    return roundNumbers(`${x} ${y} ${z} ${angle}`);
     52  }
     53  return args;
     54 }
     55 
     56 function compareRotations(actual, expected) {
     57  assert_equals(parseRotation(actual), parseRotation(expected));
     58 }
     59 
     60 test_composition({
     61  property: 'rotate',
     62  underlying: '100deg',
     63  addFrom: '10deg',
     64  addTo: '30deg',
     65  comparisonFunction: compareRotations
     66 }, [
     67  {at: -1, expect: '90deg'},
     68  {at: 0, expect: '110deg'},
     69  {at: 0.25, expect: '115deg'},
     70  {at: 0.75, expect: '125deg'},
     71  {at: 1, expect: '130deg'},
     72  {at: 2, expect: '150deg'},
     73 ]);
     74 
     75 test_composition({
     76  property: 'rotate',
     77  underlying: '1 0 0 200deg',
     78  addFrom: '1 0 0 -100deg',
     79  replaceTo: '1 0 0 40deg',
     80  comparisonFunction: compareRotations
     81 }, [
     82  {at: -1, expect: '1 0 0 160deg'},
     83  {at: 0, expect: '1 0 0 100deg'},
     84  {at: 0.25, expect: '1 0 0 85deg'},
     85  {at: 0.75, expect: '1 0 0 55deg'},
     86  {at: 1, expect: '1 0 0 40deg'},
     87  {at: 2, expect: '1 0 0 -20deg'},
     88 ]);
     89 
     90 test_composition({
     91  property: 'rotate',
     92  underlying: '0 1 0 -40deg',
     93  replaceFrom: '0 1 0 50deg',
     94  addTo: '0 1 0 10deg',
     95  comparisonFunction: compareRotations
     96 }, [
     97  {at: -1, expect: '0 1 0 130deg'},
     98  {at: 0, expect: '0 1 0 50deg'},
     99  {at: 0.25, expect: '0 1 0 30deg'},
    100  {at: 0.75, expect: '0 1 0 -10deg'},
    101  {at: 1, expect: '0 1 0 -30deg'},
    102  {at: 2, expect: '0 1 0 -110deg'},
    103 ]);
    104 
    105 test_composition({
    106  property: 'rotate',
    107  underlying: '1 2 3 40deg',
    108  addFrom: '2 4 6 10deg',
    109  addTo: '3 6 9 50deg',
    110  comparisonFunction: compareRotations
    111 }, [
    112  {at: -1, expect: '0.27 0.53 0.8 10deg'},
    113  {at: 0, expect: '0.27 0.53 0.8 50deg'},
    114  {at: 0.25, expect: '0.27 0.53 0.8 60deg'},
    115  {at: 0.75, expect: '0.27 0.53 0.8 80deg'},
    116  {at: 1, expect: '0.27 0.53 0.8 90deg'},
    117  {at: 2, expect: '0.27 0.53 0.8 130deg'},
    118 ]);
    119 
    120 test_composition({
    121  property: 'rotate',
    122  underlying: '1 2 3 270deg',
    123  addFrom: '1 2 3 90deg',
    124  replaceTo: '0 1 0 100deg',
    125  comparisonFunction: compareRotations
    126 }, [
    127  {at: -1, expect: '0 -1 0 100deg'},
    128  {at: 0, expect: '0deg'},
    129  {at: 0.25, expect: 'y 25deg'},
    130  {at: 0.75, expect: 'y 75deg'},
    131  {at: 1, expect: 'y 100deg'},
    132  // Accept both the SLERP and the common axis solution, which are equivalent.
    133  {at: 2, expect: '0 -1 0 160deg', option: 'y 200deg'},
    134 ]);
    135 
    136 test_composition({
    137  property: 'rotate',
    138  underlying: '1 2 3 90deg',
    139  addFrom: '2 4 6 270deg',
    140  replaceTo: '0 1 0 100deg',
    141  comparisonFunction: compareRotations
    142 }, [
    143  {at: -1, expect: '0 -1 0 100deg'},
    144  {at: 0, expect: '0deg'},
    145  {at: 0.25, expect: 'y 25deg'},
    146  {at: 0.75, expect: 'y 75deg'},
    147  {at: 1, expect: 'y 100deg'},
    148  // Accept both the SLERP and the common axis solution, which are equivalent.
    149  {at: 2, expect: '0 -1 0 160deg', option: 'y 200deg'},
    150 ]);
    151 
    152 test_composition({
    153  property: 'rotate',
    154  underlying: '1 0 0 0deg',
    155  addFrom: '1 1 0 90deg',
    156  replaceTo: '0 1 1 135deg',
    157  comparisonFunction: compareRotations
    158 }, [
    159  {at: -1, expect: '0.67 -0.06 -0.74 124.97deg'},
    160  {at: 0, expect: '0.71 0.71 0 90deg'},
    161  {at: 0.25, expect: '0.54 0.8 0.26 94.83deg'},
    162  {at: 0.75, expect: '0.17 0.78 0.61 118.68deg'},
    163  {at: 1, expect: '0 0.71 0.71 135deg'},
    164  {at: 2, expect: '-0.52 0.29 0.81 208.96deg'},
    165 ]);
    166 
    167 test_composition({
    168  property: 'rotate',
    169  underlying: 'none',
    170  addFrom: 'none',
    171  replaceTo: '0 1 0 100deg',
    172  comparisonFunction: compareRotations
    173 }, [
    174  {at: -1, expect: 'y -100deg'},
    175  {at: 0, expect: 'y 0deg'},
    176  {at: 0.25, expect: 'y 25deg'},
    177  {at: 0.75, expect: 'y 75deg'},
    178  {at: 1, expect: 'y 100deg'},
    179  {at: 2, expect: 'y 200deg'},
    180 ]);
    181 
    182 test_composition({
    183  property: 'rotate',
    184  underlying: 'none',
    185  addFrom: '2 4 6 270deg',
    186  replaceTo: 'none',
    187  comparisonFunction: compareRotations
    188 }, [
    189  {at: -1, expect: '0.27 0.53 0.8 540deg'},
    190  {at: 0, expect: '0.27 0.53 0.8 270deg'},
    191  {at: 0.25, expect: '0.27 0.53 0.8 202.5deg'},
    192  {at: 0.75, expect: '0.27 0.53 0.8 67.5deg'},
    193  {at: 1, expect: '0.27 0.53 0.8 0deg'},
    194  {at: 2, expect: '0.27 0.53 0.8 -270deg'},
    195 ]);
    196 
    197 test_composition({
    198  property: 'rotate',
    199  underlying: '1 2 3 90deg',
    200  addFrom: 'none',
    201  replaceTo: '0 1 0 100deg',
    202  comparisonFunction: compareRotations
    203 }, [
    204  {at: -1, expect: '0.31 -0.22 0.92 131.66deg'},
    205  {at: 0, expect: '1 2 3 90deg'},
    206  {at: 0.25, expect: '0.21 0.73 0.64 86.72deg'},
    207  {at: 0.75, expect: '0.07 0.97 0.21 92.05deg'},
    208  {at: 1, expect: '0 1 0 100deg'},
    209  {at: 2, expect: '-0.2 0.79 -0.59 151.11deg'},
    210 ]);
    211 
    212 test_composition({
    213  property: 'rotate',
    214  underlying: '1 2 3 90deg',
    215  addFrom: '2 4 6 270deg',
    216  replaceTo: 'none',
    217  comparisonFunction: compareRotations
    218 }, [
    219  {at: -1, expect: '0.27 0.53 0.8 720deg'},
    220  {at: 0, expect: '0.27 0.53 0.8 360deg'},
    221  {at: 0.25, expect: '0.27 0.53 0.8 270deg'},
    222  {at: 0.75, expect: '0.27 0.53 0.8 90deg'},
    223  {at: 1, expect: '0.27 0.53 0.8 0deg'},
    224  {at: 2, expect: '0.27 0.53 0.8 -360deg'},
    225 ]);
    226 </script>
    227 </body>