我正在處理基於畫布的動畫,並試圖在2D畫布中獲得3D效果。將視角添加到假3D動畫中
到目前爲止,事情進展順利!我有我的工作非常好「三角形的軌道線」:
var c = document.createElement('canvas');
c.width = c.height = 100;
document.body.appendChild(c);
var ctx = c.getContext("2d");
function Triangles() {
this.rotation = {
x: Math.random()*Math.PI*2,
y: Math.random()*Math.PI*2,
z: Math.random()*Math.PI*2
};
/* Uncomment this for testing perspective...
this.rotation = {
x: Math.PI/2,
y: 0,
z: 0
};
*/
}
Triangles.prototype.draw = function(t) {
this.rotation.z += t/1000;
var i, points;
for(i=0; i<15; i++) {
points = [
this.computeRotation(Math.cos(0.25*i),-Math.sin(0.25*i),0),
this.computeRotation(Math.cos(0.25*(i+1)),-Math.sin(0.25*(i+1)),-0.1),
this.computeRotation(Math.cos(0.25*(i+1)),-Math.sin(0.25*(i+1)),0.1)
];
ctx.fillStyle = "black";
ctx.beginPath();
ctx.moveTo(50+40*points[0][0],50+40*points[0][1]);
ctx.lineTo(50+40*points[1][0],50+40*points[1][1]);
ctx.lineTo(50+40*points[2][0],50+40*points[2][1]);
ctx.closePath();
ctx.fill();
}
};
Triangles.prototype.computeRotation = function(x,y,z) {
var rz, ry, rx;
rz = [
Math.cos(this.rotation.z) * x - Math.sin(this.rotation.z) * y,
Math.sin(this.rotation.z) * x + Math.cos(this.rotation.z) * y,
z
];
ry = [
Math.cos(this.rotation.y) * rz[0] + Math.sin(this.rotation.y) * rz[2],
rz[1],
-Math.sin(this.rotation.y) * rz[0] + Math.cos(this.rotation.y) * rz[2]
];
rx = [
ry[0],
Math.cos(this.rotation.x) * ry[1] - Math.sin(this.rotation.x) * ry[2],
Math.sin(this.rotation.x) * ry[1] + Math.cos(this.rotation.x) * ry[2]
];
return rx;
};
var tri = new Triangles();
requestAnimationFrame(function(start) {
function step(t) {
var delta = t-start;
ctx.clearRect(0,0,100,100)
tri.draw(delta);
start = t;
requestAnimationFrame(step);
}
step(start);
});
正如你可以看到它使用旋轉矩陣其旋轉後計算點的位置,和我使用這個來繪製使用輸出x和y座標的三角形。
我想通過使用z座標和向該動畫添加透視來進一步深化,這會使三角形在前景中稍大一點,在背景中較小。但是,我不知道如何去做這件事。
我想這是一個數學問題比編程更多,對此感到抱歉!
啊哈,所以看起來我應該與z成反比,與我自己的嘗試不成比例。這是有道理的,因爲當距離接近零時,感知的大小應該接近無窮大,並且當距離接近無窮大時,感知的大小應該接近於零。很高興知道這很簡單! –
嗯,有趣的是,我的「壞」視角實際上最終在這個特定情況下產生了更好的視覺效果(在一個更完整的動畫中),所以我會堅持這個例子,但是很高興知道如何正確地做透視。謝謝! –
奇怪的是,你在答案中給出的公式有一個線性結果,而隨着z變大,'x *(z + 2)/ 2'的結果變得更大,因此距離越遠的對象變得越大?或者你將x,y與'x *(z + 2)/ 2'的結果相除,那麼你就和我的相同,其中2是焦距,'(z + 2) '是沿着Z – Blindman67