DOMMatrix-003.html (11694B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Geometry Interfaces: Test DOMMatrix non-mutating methods</title> 5 <link href="mailto:peter.hall@algomi.com" rel="author" title="Peter Hall"> 6 <link rel="help" href="https://drafts.fxtf.org/geometry-1/#DOMMatrix"> 7 <script src="support/dommatrix-test-util.js"></script> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 </head> 11 <body> 12 <p>Test DOMMatrix non-mutating methods</p> 13 <div id="log"></div> 14 <script> 15 var epsilon = 0.0000000005; 16 17 function initialMatrix(){ 18 return { 19 m11:1, m12:-0.5, m13: 0.5, m14:0, 20 m21:0.5, m22:2, m23: -0.5, m24:0, 21 m31:0, m32:0, m33: 1, m34:0, 22 m41:10, m42:20, m43: 10, m44:1, 23 is2D: false 24 }; 25 } 26 27 function initialDOMMatrix() { 28 return DOMMatrixReadOnly.fromMatrix(initialMatrix()) 29 } 30 31 function identity() { 32 return new DOMMatrix( 33 [1, 0, 0, 0, 34 0, 1, 0 ,0, 35 0, 0, 1, 0, 36 0, 0, 0, 1]); 37 } 38 39 function update(matrix, f) { 40 f(matrix); 41 return matrix; 42 } 43 44 function deg2rad(degrees) { 45 return degrees * Math.PI / 180; 46 } 47 48 function getRotationMatrix(x, y, z, alpha_in_degrees) { 49 // Vector normalizing 50 var nx = x; 51 var ny = y; 52 var nz = z; 53 var length = Math.sqrt(x * x + y * y + z * z); 54 if (length) { 55 nx = x / length; 56 ny = y / length; 57 nz = z / length; 58 } 59 60 // The 3D rotation matrix is described in CSS Transforms with alpha. 61 // Please see: https://drafts.csswg.org/css-transforms-2/#Rotate3dDefined 62 var alpha_in_radians = deg2rad(alpha_in_degrees / 2); 63 var sc = Math.sin(alpha_in_radians) * Math.cos(alpha_in_radians); 64 var sq = Math.sin(alpha_in_radians) * Math.sin(alpha_in_radians); 65 66 var m11 = 1 - 2 * (ny * ny + nz * nz) * sq; 67 var m12 = 2 * (nx * ny * sq + nz * sc); 68 var m13 = 2 * (nx * nz * sq - ny * sc); 69 var m14 = 0; 70 var m21 = 2 * (nx * ny * sq - nz * sc); 71 var m22 = 1 - 2 * (nx * nx + nz * nz) * sq; 72 var m23 = 2 * (ny * nz * sq + nx * sc); 73 var m24 = 0; 74 var m31 = 2 * (nx * nz * sq + ny * sc); 75 var m32 = 2 * (ny * nz * sq - nx * sc); 76 var m33 = 1 - 2 * (nx * nx + ny * ny) * sq; 77 var m34 = 0; 78 var m41 = 0; 79 var m42 = 0; 80 var m43 = 0; 81 var m44 = 1; 82 83 return new DOMMatrix([ 84 m11, m12, m13, m14, 85 m21, m22, m23, m24, 86 m31, m32, m33, m34, 87 m41, m42, m43, m44]); 88 } 89 90 function getMatrixTransform(matrix, point) { 91 var x = point.x * matrix.m11 + point.y * matrix.m21 + point.z * matrix.m31 + point.w * matrix.m41; 92 var y = point.x * matrix.m12 + point.y * matrix.m22 + point.z * matrix.m32 + point.w * matrix.m42; 93 var w = point.x * matrix.m13 + point.y * matrix.m23 + point.z * matrix.m33 + point.w * matrix.m43; 94 var z = point.x * matrix.m14 + point.y * matrix.m24 + point.z * matrix.m34 + point.w * matrix.m44; 95 return new DOMPoint(x, y, w, z) 96 } 97 98 test(function() { 99 var tx = 1; 100 var ty = 5; 101 var tz = 3; 102 var result = initialDOMMatrix().translate(tx, ty, tz); 103 var expected = update(initialMatrix(), function(m) { 104 m.m41 += tx * m.m11 + ty * m.m21 + tz * m.m31; 105 m.m42 += tx * m.m12 + ty * m.m22 + tz * m.m32; 106 m.m43 += tx * m.m13 + ty * m.m23 + tz * m.m33; 107 m.m44 += tx * m.m14 + ty * m.m24 + tz * m.m34; 108 }); 109 checkMatrix(result, expected, { epsilon }); 110 },"test translate()"); 111 112 test(function() { 113 var sx = 2; 114 var sy = 5; 115 var sz = 3; 116 var result = initialDOMMatrix().scale(sx, sy, sz); 117 var expected = update(initialMatrix(), function(m) { 118 m.m11 *= sx; 119 m.m12 *= sx; 120 m.m13 *= sx; 121 m.m14 *= sx; 122 m.m21 *= sy; 123 m.m22 *= sy; 124 m.m23 *= sy; 125 m.m24 *= sy; 126 m.m31 *= sz; 127 m.m32 *= sz; 128 m.m33 *= sz; 129 m.m34 *= sz; 130 }); 131 checkMatrix(result, expected, { epsilon }); 132 },"test scale() without offsets"); 133 134 test(function() { 135 var result = initialDOMMatrix().scale(2, 5, 3, 11, 7, 13); 136 var expected = initialDOMMatrix() 137 .translate(11, 7, 13) 138 .scale(2, 5, 3) 139 .translate(-11, -7, -13); 140 checkMatrix(result, expected, { epsilon }); 141 },"test scale() with offsets"); 142 143 test(function() { 144 var result = new DOMMatrixReadOnly([1, 2, 3, 4, 5, 6]) 145 .scale(1, 1, 1, 1, 1, 1); 146 var expected = new DOMMatrixReadOnly([1, 2, 0, 0, 3, 4, 0, 0, 0, 0, 1, 0, 5, 6, 0, 1]); 147 checkMatrix(result, expected, { epsilon }); 148 },"test scale() with identity scale and nonzero originZ"); 149 150 test(function() { 151 var result = initialDOMMatrix().scaleNonUniform(); 152 var expected = initialDOMMatrix() 153 .scale(1, 1, 1, 0, 0, 0); 154 checkMatrix(result, expected, { epsilon }); 155 },"test scaleNonUniform()"); 156 157 test(function() { 158 var result = initialDOMMatrix().scaleNonUniform(6); 159 var expected = initialDOMMatrix() 160 .scale(6, 1, 1, 0, 0, 0); 161 checkMatrix(result, expected, { epsilon }); 162 },"test scaleNonUniform() with sx"); 163 164 test(function() { 165 var result = initialDOMMatrix().scaleNonUniform(5, 7); 166 var expected = initialDOMMatrix() 167 .scale(5, 7, 1, 0, 0, 0); 168 checkMatrix(result, expected, { epsilon }); 169 },"test scaleNonUniform() with sx, sy"); 170 171 test(function() { 172 var result = initialDOMMatrix().scale3d(7, 5, 2, 3); 173 var expected = initialDOMMatrix() 174 .translate(5, 2, 3) 175 .scale(7, 7, 7) 176 .translate(-5, -2, -3); 177 checkMatrix(result, expected, { epsilon }); 178 },"test scale3d()"); 179 180 test(function() { 181 var result = initialDOMMatrix().rotate(-90); 182 var expected = initialDOMMatrix().multiply(getRotationMatrix(0, 0, 1, -90)); 183 checkMatrix(result, expected, { epsilon }); 184 },"test rotate() 2d"); 185 186 test(function() { 187 var result = initialDOMMatrix().rotate(180, 180, 90); 188 var expected = initialDOMMatrix().rotate(0,0,-90); 189 checkMatrix(result, expected, { epsilon }); 190 },"test rotate()"); 191 192 test(function() { 193 var result = initialDOMMatrix().rotate(90, 90, 90); 194 var expected = initialDOMMatrix() 195 .rotate(0, 0, 90) 196 .rotate(0, 90, 0) 197 .rotate(90, 0, 0); 198 checkMatrix(result, expected, { epsilon }); 199 },"test rotate() order"); 200 201 test(function() { 202 var result = initialDOMMatrix().rotateFromVector(1, 1); 203 var expected = initialDOMMatrix().rotate(45); 204 checkMatrix(result, expected, { epsilon }); 205 },"test rotateFromVector()"); 206 207 test(function() { 208 var result = initialDOMMatrix().rotateFromVector(0, 1); 209 var expected = initialDOMMatrix().rotate(90); 210 checkMatrix(result, expected, { epsilon }); 211 },"test rotateFromVector() with x being zero"); 212 213 test(function() { 214 var result = initialDOMMatrix().rotateFromVector(1, 0); 215 var expected = initialDOMMatrix() 216 checkMatrix(result, expected, { epsilon }); 217 },"test rotateFromVector() with y being zero"); 218 219 test(function() { 220 var result = initialDOMMatrix().rotateFromVector(0, 0); 221 var expected = initialDOMMatrix() 222 checkMatrix(result, expected, { epsilon }); 223 },"test rotateFromVector() with two zeros"); 224 225 test(function() { 226 var result = initialDOMMatrix().rotateAxisAngle(3, 3, 3, 120); 227 var expected = initialDOMMatrix().multiply(getRotationMatrix(3, 3, 3, 120)); 228 checkMatrix(result, expected, { epsilon }); 229 },"test rotateAxisAngle() "); 230 231 test(function() { 232 var result = new DOMMatrix([1, 1, 1, 1, 1, 1]).rotateAxisAngle(0, 0, 3, 90); 233 var expected = new DOMMatrix([1, 1, -1, -1, 1, 1]); 234 checkMatrix(result, expected, { epsilon }); 235 },"test rotateAxisAngle() on 2D matrix with 2D rotation"); 236 237 test(function() { 238 var angleDeg = 75; 239 var result = initialDOMMatrix().skewX(angleDeg); 240 var tangent = Math.tan(angleDeg * Math.PI/180); 241 var skew = new DOMMatrix([ 242 1, 0, 0, 0, 243 tangent, 1, 0, 0, 244 0, 0, 1, 0, 245 0, 0, 0, 1]) 246 var expected = initialDOMMatrix().multiply(skew); 247 checkMatrix(result, expected, { epsilon }); 248 },"test skewX()"); 249 250 test(function() { 251 var angleDeg = 18; 252 var result = initialDOMMatrix().skewY(angleDeg); 253 var tangent = Math.tan(angleDeg * Math.PI/180); 254 var skew = new DOMMatrix([ 255 1, tangent, 0, 0, 256 0, 1, 0, 0, 257 0, 0, 1, 0, 258 0, 0, 0, 1]) 259 var expected = initialDOMMatrix().multiply(skew); 260 checkMatrix(result, result, { epsilon }); 261 },"test skewY()"); 262 263 test(function() { 264 var result = initialDOMMatrix().multiply(initialDOMMatrix().inverse()); 265 checkMatrix(result, identity(), { epsilon }); 266 },"test multiply with inverse is identity"); 267 268 test(function() { 269 var result = initialDOMMatrix().flipX(); 270 var expected = initialDOMMatrix().multiply(new DOMMatrix([-1, 0, 0, 1, 0, 0])); 271 checkMatrix(result, expected, { epsilon }); 272 },"test flipX()"); 273 274 test(function() { 275 var result = initialDOMMatrix().flipY(); 276 var expected = initialDOMMatrix().multiply(new DOMMatrix([1, 0, 0, -1, 0, 0])); 277 checkMatrix(result, expected, { epsilon }); 278 },"test flipY()"); 279 280 test(function() { 281 var point = new DOMPointReadOnly(1, 2, 3, 4); 282 var matrix = new DOMMatrix([1, 2, 3, 4, 5, 6]); 283 var result = matrix.transformPoint(point); 284 var expected = getMatrixTransform(matrix, point); 285 checkDOMPoint(result, expected); 286 },"test transformPoint() - 2d matrix"); 287 288 test(function() { 289 var point = new DOMPointReadOnly(1, 2, 3, 4); 290 var matrix = new DOMMatrix([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]); 291 var result = matrix.transformPoint(point); 292 var expected = getMatrixTransform(matrix, point); 293 checkDOMPoint(result, expected); 294 },"test transformPoint() - 3d matrix"); 295 296 function checkDOMPoint(p, exp) { 297 assert_equals(p.x, exp.x, "x is not matched"); 298 assert_equals(p.y, exp.y, "y is not matched"); 299 assert_equals(p.z, exp.z, "z is not matched"); 300 assert_equals(p.w, exp.w, "w is not matched"); 301 } 302 303 </script> 304 </body> 305 </html>