ç©éµå¯ä»¥ç¨äºè¡¨ç¤ºç©ºé´ä¸ç对象ç忢ï¼å¹¶ä¸æ¯ Web 页é¢å¯è§åçéè¦å·¥å ·ãæ¬ææ¢ç´¢å¦ä½å建并é å CSS 忢å matrix3d åæ¢ç±»å使ç¨ç©éµã
è½ç¶æ¬æä¸ºäºä¾¿äºè§£éè使ç¨äº CSSï¼ç©éµå´æ¯è®¸å¤ææ¯ä¸çæ ¸å¿æ¦å¿µï¼å æ¬ WebGL åçè²å¨ãæ¬æä¹æ¯ MDN content kit çä¸é¨åã示ä¾ä½¿ç¨äºä¸ç»å ¨å±å¯¹è±¡ MDN ä¸çå·¥å ·å½æ°ã
ä»ä¹æ¯åæ¢ç©éµï¼è½ç¶åå¨è®¸å¤ç±»åçç©éµï¼ä½æä»¬æå ´è¶£çæ¯ä¸ç»´åæ¢ç©éµãè¿ç§ç©éµç±ä¸ä¸ª 4x4 æ¹éµï¼å ± 16 个å¼ç»æãå¨ JavaScript ä¸ï¼å¯ä»¥å¾æ¹ä¾¿çç¨æ°ç»è¡¨ç¤ºç©éµãæ¯å¦å ¸åçåä½ç©éµãåä½éµä¹ä¸ä¸ä¸ªç¹æè ç©éµï¼å ¶ç»æä¿æä¸åã
var identityMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
说å°ä¹æ³ï¼è¿ç§è¿ç®ç¨äºç©éµæ¯ä»ä¹æ ·çå¢ï¼æç®åçä¾åæ¯ç©éµä¹ä¸ä¸ªç¹ãä½ å¯è½æ³¨æå°ï¼ä¸ç»´ç©ºé´ä¸çç¹åä¸ä¸ª 4x4 ç©éµå¹¶ä¸å¹é ï¼ä¸ºæ¤æä»¬å ä¸äºé¢å¤ç第åç»´ Wãä¸è¬æ¥è¯´ï¼æ W 设为 1 å°±å¯ä»¥äºãW ç»´åº¦è¿æä¸äºé¢å¤çç¨éè¶ åºæ¬æç讨论èå´ã
注æç©éµåç¹ç坹齿¹å¼ï¼
[1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]
[4, 3, 2, 1] // å¨ [x, y, z, w] 夿±ç¹ç§¯
å®ä¹ç¸ä¹å½æ°
æä»¬å¨ç¤ºä¾ä»£ç ä¸å®ä¹äºä¸ä¸ªä¹æ³å½æ°ââmultiplyMatrixAndPoint()
ï¼
function multiplyMatrixAndPoint(matrix, point) {
// ç»ç©éµçæ¯ä¸é¨åä¸ä¸ªç®åçåéåï¼åæ°ï¼cï¼ä¸è¡æ°ï¼rï¼
var c0r0 = matrix[0],
c1r0 = matrix[1],
c2r0 = matrix[2],
c3r0 = matrix[3];
var c0r1 = matrix[4],
c1r1 = matrix[5],
c2r1 = matrix[6],
c3r1 = matrix[7];
var c0r2 = matrix[8],
c1r2 = matrix[9],
c2r2 = matrix[10],
c3r2 = matrix[11];
var c0r3 = matrix[12],
c1r3 = matrix[13],
c2r3 = matrix[14],
c3r3 = matrix[15];
// å®ä¹ç¹åæ
var x = point[0];
var y = point[1];
var z = point[2];
var w = point[3];
// ç¹åæ å第ä¸å对åºç¸ä¹ï¼åæ±å
var resultX = x * c0r0 + y * c0r1 + z * c0r2 + w * c0r3;
// ç¹åæ å第äºå对åºç¸ä¹ï¼åæ±å
var resultY = x * c1r0 + y * c1r1 + z * c1r2 + w * c1r3;
// ç¹åæ å第ä¸å对åºç¸ä¹ï¼åæ±å
var resultZ = x * c2r0 + y * c2r1 + z * c2r2 + w * c2r3;
// ç¹åæ å第åå对åºç¸ä¹ï¼åæ±å
var resultW = x * c3r0 + y * c3r1 + z * c3r2 + w * c3r3;
return [resultX, resultY, resultZ, resultW];
}
ç°å¨æä»¬å¯ä»¥ä½¿ç¨ä¸é¢ç彿°å°ä¸ä¸ªç¹ä¹ä¸ä¸ä¸ªç©éµãä¹ä»¥åä½éµå°ä¼è¿ååå¼ï¼
// identityResult çäº [4,3,2,1]
var identityResult = multiplyMatrixAndPoint(identityMatrix, [4, 3, 2, 1]);
è¿ååä¸ä¸ªç¹å¹¶æ²¡æä»ä¹ç¨å¤ï¼ä½è¿æä¸äºå ¶ä»çç©éµå¯ä»¥ä½ç¨äºç¹ï¼è¿åæç¨çç»æãæ¥ä¸æ¥æä»¬å°æ¼ç¤ºå ¶ä¸ä¸äºç©éµã
两个ç©éµç¸ä¹é¤äºæç©éµåç¹ç¸ä¹ï¼ä½ ä¹å¯ä»¥æä¸¤ä¸ªç©éµç¸ä¹ãä¹åç彿°å¯ä»¥å¸®å©æä»¬ç®åè¿ä¸ªè¿ç¨ï¼
function multiplyMatrices(matrixA, matrixB) {
// å°ç¬¬äºä¸ªç©éµæååç
var column0 = [matrixB[0], matrixB[4], matrixB[8], matrixB[12]];
var column1 = [matrixB[1], matrixB[5], matrixB[9], matrixB[13]];
var column2 = [matrixB[2], matrixB[6], matrixB[10], matrixB[14]];
var column3 = [matrixB[3], matrixB[7], matrixB[11], matrixB[15]];
// å°æ¯ååå«åç©éµç¸ä¹
var result0 = multiplyMatrixAndPoint(matrixA, column0);
var result1 = multiplyMatrixAndPoint(matrixA, column1);
var result2 = multiplyMatrixAndPoint(matrixA, column2);
var result3 = multiplyMatrixAndPoint(matrixA, column3);
// æç»æéæ°ç»åæç©éµ
return [
result0[0],
result1[0],
result2[0],
result3[0],
result0[1],
result1[1],
result2[1],
result3[1],
result0[2],
result1[2],
result2[2],
result3[2],
result0[3],
result1[3],
result2[3],
result3[3],
];
}
让æä»¬çä¸çå®é 使ç¨ï¼
var someMatrix = [4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0, 4, 8, 4, 1];
var identityMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
// è¿å someMatrix çæ°ç»è¡¨ç¤º
var someMatrixResult = multiplyMatrices(identityMatrix, someMatrix);
è¦åï¼ è¿äºå½æ°æ¯ä¸ºäºè§£éçæ¸ æ°èç¼åï¼è䏿¯ä¸ºäºé度æè å å管çãè¿äºå½æ°æ°å»ºäºå¤§éæ°ç»ï¼å¯è½å¨å®æ¶è¿ç®æ¶å¯¼è´åå¾åæ¶ç巨大å¼éãå¨å®é 产åä¸æå¥½ä½¿ç¨ä¼åè¿ç彿°ãæ¯å¦glMatrixå°±æ¯ä¸ä¸ªæ³¨ééåº¦åæ§è½çåºã
平移ç©éµå¹³ç§»ç©éµåºäºåä½ç©éµãå®å°ä¸ä¸ªå¯¹è±¡æ²¿ xï¼yï¼z å ¶ä¸ä¸ä¸ªæ¹åè¿è¡ç§»å¨ãæç®åçæ³è±¡å¹³ç§»çæ¹å¼æ¯è®¾æ³æ¿èµ·ä¸ä¸ªå塿¯ãå塿¯å¿ é¡»ä¿æç´ç«åæå以å å塿´åºæ¥ãå®å¯ä»¥ç¦»å¼æ¡åå¨ç©ºé´ä¸ç§»å¨ã
ç°å¨æä»¬è¿åä¸å°è¿ä¸ªæ¯åéçåå¡ï¼å 为å¨å¹³ç§»ç©éµçåç¬ä½ç¨ä¸æ¯åå¹¶ä¸è½å¾æãå¨ä¹åçé¨åï¼æä»¬ä¼è®¨è®ºæ°çç©éµï¼æ¥è§£å³è¿ä¸ªé®é¢ã
var x = 50;
var y = 100;
var z = 0;
var translationMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1];
ç¨ç©éµæä½ DOM
ä¸ä¸ªé常ç®åçå¼å§ä½¿ç¨ç©éµçæ¹æ³æ¯ä½¿ç¨ CSS3 éç matrix3d
忢ãé¦å
ï¼æä»¬æ°å»ºä¸ä¸ªç®åç <div>
å¹¶å ä¸ä¸äºå
容ãè¿éæ ·å¼æ²¡æå±ç¤ºåºæ¥ï¼ä½æä»¬å°å
¶è®¾ç½®æäºé¡µé¢å±
ä¸ä¸åºå®å®½åº¦ä¸é«åº¦ãæä»¬åæ ·ä¸ºåæ¢è®¾å®äºå¨ç»ä»¥ä¾¿æ¸
æ°çè§å¯åççååã
<div id="move-me" class="transformable">
<h2>Move me with a matrix</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
</div>
æåï¼æä»¬ä¼ä¸ºæ¯ä¸ä¸ªä¾åçæä¸ä¸ª 4x4 ç©éµï¼ç¶åæ´æ°<div>çæ ·å¼ï¼å¯¹å ¶åºç¨ä¸ä¸ª matrix3d 忢ãè¦è®°ä½å³ä½¿ç©éµæåè¡ååï¼ä¹è¦å°å ¶åæåè¡ 16 个å¼ã
// ä»ç©éµæ°ç»å建 matrix3d æ ·å¼å±æ§
function matrixArrayToCssMatrix(array) {
return "matrix3d(" + array.join(",") + ")";
}
// è·å DOM å
ç´
var moveMe = document.getElementById("move-me");
// è¿åç»æå¦ï¼"matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 50, 100, 0, 1);"
var matrix3dRule = matrixArrayToCssMatrix(translationMatrix);
// è®¾ç½®åæ¢
moveMe.style.transform = matrix3dRule;
缩æ¾ç©éµ
缩æ¾ç©éµä½¿å¯¹è±¡çé«åº¦ãå®½åº¦åæ·±åº¦ä¸ä¸ªç»´åº¦çå ¶ä¸ä¹ä¸å大æåå°ãå¨å ¸åï¼ç¬å¡å°ï¼åæ ç³»ä¸ï¼è¿å°ä½¿å¾ xï¼yï¼z åæ æä¼¸ææ¶ç¼©ã
var w = 1.5; // width (x)
var h = 0.7; // height (y)
var d = 1; // depth (z)
var scaleMatrix = [w, 0, 0, 0, 0, h, 0, 0, 0, 0, d, 0, 0, 0, 0, 1];
æè½¬ç©éµ
æè½¬ç©éµæ¯å¹³ç§»å缩æ¾ç©éµè¦ç¨å¤æä¸äºãå ¶ä¸ç¨å°äºä¸è§å½æ°æ¥å®ææè½¬ã尽管è¿é¨åä¸ä¼ææ¥éª¤è®²å¾è¿äºè¯¦ç»ï¼ä½æ¯ä¸ä¾æç®åç说æã
// ä¸åå©ç©éµå°ç¹ç»åç¹æè½¬
var point = [10, 2];
// 计ç®å°åç¹çè·ç¦»
var distance = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
// 60 度
var rotationInRadians = Math.PI / 3;
var transformedPoint = [
Math.cos(rotationInRadians) * distance,
Math.sin(rotationInRadians) * distance,
];
æä»¬å¯ä»¥å°ä¸è¿°æ¥éª¤è¡¨ç¤ºä¸ºä¸ä¸ªç©éµï¼å¹¶ä¸åç¬åºç¨å° xï¼yï¼å z åæ ãä¸é¢æ¯ç» Z è½´æè½¬ç表示ï¼
var sin = Math.sin;
var cos = Math.cos;
// NOTE: There is no perspective in these transformations, so a rotation
// at this point will only appear to only shrink the div
var a = Math.PI * 0.3; // 转è§
// ç» Z è½´æè½¬
var rotateZMatrix = [
cos(a),
-sin(a),
0,
0,
sin(a),
cos(a),
0,
0,
0,
0,
1,
0,
0,
0,
0,
1,
];
è¿éæ¯ä¸ç»è¿åæè½¬ç©éµç彿°ãè¦æ³¨æçæ¯ç±äºæ²¡æå å ¥éè§ï¼æä»¥æè½¬çèµ·æ¥æ²¡æé£ä¹ 3Dãè¿å°±å¥½åæåæºå¨æè¿è·ç¦»ææä¸ä¸ªç©ä½ââéè§çæè§æ¶å¤±äºã
function rotateAroundXAxis(a) {
return [1, 0, 0, 0, 0, cos(a), -sin(a), 0, 0, sin(a), cos(a), 0, 0, 0, 0, 1];
}
function rotateAroundYAxis(a) {
return [cos(a), 0, sin(a), 0, 0, 1, 0, 0, -sin(a), 0, cos(a), 0, 0, 0, 0, 1];
}
function rotateAroundZAxis(a) {
return [cos(a), -sin(a), 0, 0, sin(a), cos(a), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
}
ç©éµç»å
ç©éµççæ£å害ä¹å¤å¨äºç©éµçç»åãå½ä¸ç»ç¹å®ç±»åçç©éµè¿ä¹èµ·æ¥ï¼å®ä»¬ä¿çäºåæ¢çç»è¿å¹¶ä¸æ¯å¯éçãè¿æå³çå¦æå¹³ç§»ãæè½¬å缩æ¾ç©éµç»åå¨ä¸èµ·ï¼å½æä»¬ä½¿ç¨éåæ¢å¹¶é¢ ååºç¨ç顺åºï¼å¯ä»¥å¾å°åæ¥çç¹ã
ç©éµç¸ä¹çç»æä¸é¡ºåºæå ³ã两个æ°ç¸ä¹æ¶ï¼a * b = cï¼å b * a = c 齿¯æ£ç¡®çãä¾å¦ï¼3 * 4 = 12ï¼å 4 * 3 = 12ã卿°å¦ä¸è¿äºæ°è¢«ç§°ä¸ºå¯äº¤æ¢ãç©éµä¸è½ä¿è¯äº¤æ¢é¡ºåºåçè¿ç®ç»æï¼æä»¥ç©éµæ¯ä¸å¯äº¤æ¢çã
å¦ä¸ä¸ªéè¦è®°ä½çç¹æ¯å¨ WebGL å CSS3 ä¸çç©éµç¸ä¹éè¦å忢åçç顺åºç¸åãä¾å¦ï¼ç¼©æ¾å¯¹è±¡å° 80%ï¼åä¸ç§»å¨ 200 åç´ ï¼ç¶åç»åç¹æè½¬ 90 度å¨ä¼ªä»£ç ä¸åºè¯¥åä¸é¢è¿æ ·ã
transformation = rotate * translate * scaleç»åå¤ç§åæ¢
æä»¬å°ä½¿ç¨ç彿°æ¯å·¥å ·å½æ°çä¸é¨åãå ¶æ¥åç©éµçæ°ç»å¹¶æå®ä»¬ä¹èµ·æ¥ãå¨ WebGL çè²å¨ä»£ç éï¼è¿å 建å¨è¯è¨éï¼å¹¶ä¸æä»¬å¯ä»¥ä½¿ç¨ * è¿ç®ç¬¦ã餿¤ä¹å¤ï¼æ¬ä¾ä½¿ç¨äºä¸ä¸ªç¼©æ¾å½æ°ï¼ä¸ä¸ªå¹³ç§»å½æ°ï¼å®ä»¬è¿åä¹åå®ä¹çç©éµã
var transformMatrix = MDN.multiplyArrayOfMatrices([
rotateAroundZAxis(Math.PI * 0.5), // 第 3 æ¥ï¼æè½¬ 90 度
translate(0, 200, 0), // 第 2 æ¥ï¼ä¸ç§» 100 åç´
scale(0.8, 0.8, 0.8), // 第 1 æ¥ï¼ç¼©å°
]);
æåæ¯å±ç¤ºç©éµç¨éçæè¶£ç䏿¥ï¼ççææ ·é¢ åè¿äºæ¥éª¤å¹¶å¾å°æå¼å§çåä½ç©éµã
var transformMatrix = MDN.multiplyArrayOfMatrices([
scale(1.25, 1.25, 1.25), // 第 6 æ¥ï¼æ¾å¤§
translate(0, -200, 0), // 第 5 æ¥ï¼ä¸ç§»
rotateAroundZAxis(-Math.PI * 0.5), // 第 4 æ¥ï¼å转
rotateAroundZAxis(Math.PI * 0.5), // 第 3 æ¥ï¼æè½¬ 90 度
translate(0, 200, 0), // 第 2 æ¥ï¼ä¸ç§» 100 åç´
scale(0.8, 0.8, 0.8), // 第 1 æ¥ï¼ç¼©å°
]);
为ä»ä¹ç©éµè¿ä¹éè¦ï¼
ç©éµä¹æä»¥éè¦ï¼æ¯å 为å®å¯ä»¥ç¨å°éçæ°åæè¿°å¤§éç空é´ä¸ç忢ï¼å¹¶ä¸è½è½»æå°å¨ç¨åºé´å ±äº«ãç©éµå¯ä»¥ä¸åçåæ ç©ºé´ï¼çè³ä¸äºç©éµä¹æ³å¯ä»¥å°ä¸ç»æ°æ®ä»ä¸ä¸ªåæ ç©ºé´æ å°å°å¦ä¸ä¸ªåæ 空é´ãç©éµè½å¤é«æçå°ä¿åçæå®ä»¬çæ¯ä¸æ¥åæ¢ã
对äºå¨ WebGL ä¸ä½¿ç¨ï¼æ¾å¡å°¤å ¶æ é¿å¤§éçç¹ä¹ç©éµè¿ç®ãåç§åæ ·çè¿ç®ï¼å¦ç¹å®ä½ãå 线è¿ç®ã卿è§è²ï¼é½ä¾èµè¿ä¸ªåºç¡å·¥å ·ã
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4