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>