[OPによるさらなる明確化を考慮して編集]
OK、これであなたの質問をよりよく理解できました。ワールド内のオブジェクトに カメラ レンズの視点を与えたいと考えています。
カメラがワールド オブジェクトに対して X 方向にしか見えない場合は、単純に視差を使用できます。これを行うには、X 方向に異なる速度でスクロールする 2 つのレイヤーをキャンバスに適用します。これがパノラマ視差です。したがって、フレームごとに、次の疑似コードのように 2 つのレイヤーを描画します。
// Move the back layer
backLayerX += 3;
ctx.save();
ctx.translate(backLayerX,backLayerY);
// draw the objects in your back layer now
ctx.translate(-backLayerX,-backLayerY);
ctx.restore();
// Move the front layer faster than the back layer
frontLayerX += 10;
ctx.save();
ctx.translate(frontLayerX,frontLayerY);
// draw the objects in your front layer now
ctx.translate(frontLayerX,frontLayerY);
ctx.restore();
また、カメラ自体を X 方向に移動する場合は、フロント レイヤーとバック レイヤーが変換される速度も変更する必要があります。
カメラがワールド オブジェクトに対して Z 方向 (カメラ クローザー) も見ている場合、プロセスはさらに複雑になります。
たとえば、彫像に近づくと、彫像が大きくなるように見えます — ctx.scale(2,2)。バックグラウンド シーナリーも大きくなりますが、それほど速くはありません — ctx.scale(1.25,1.25)。
次に、さらに左に一歩進むと、彫像の左側が彫像の右側よりわずかに大きくなり、文脈がゆがみます。背景も歪んでいますが、非常にわずかです。
次に、椅子に立つ (Y 方向を変更する) と、別の種類のゆがみが発生します。
像は 2D であり、像の厚紙の切り抜きであるため、カメラは像と一緒に移動することはできません。カメラの視点から見ると、彫像は実際に消えてしまいます!
あなたのプロジェクトを始めるきっかけになったと思いますが、完全な答えは、Stackoverflow の答えを超えたものです。コンピューター グラフィックスの大学のコースです。
おすすめのオンライン チュートリアルがあります。Wolfgang Hurst による Perspective に関する優れた講義があります。これは、彼の 13 部構成のオンライン カレッジ コースの講義 #7 です。彼の講義は 2 つの方法で見ることができます。広く見て、カメラの視点を与えることに関連する概念を理解してください。または、深く見て数学的アルゴリズムを入手してください: http://www.youtube.com/watch?v=q_HA-x5AujI&list=PLDFA8FCF0017504DE
幸運と学習… :)
[以下は、OPの元の質問に対処します]
これは、キャンバス内の何かを正常に回転させる方法に関する簡単なチュートリアルです
全世界は、X/Y の「登録点」を中心に回転します。
ctx.rotate(angle) の直前に ctx.translate(X,Y) を実行して登録点を設定します。
この回転した空間に「ワールド」オブジェクトを描画した後、translate(-X,-Y) を実行して基準点を再設定する必要があります。
したがって、世界の回転は次のようになります。
- Context.save();
- Context.translate(登録X、登録Y);
- Context.rotate(角度);
- ものを描きます。
- Context.translate( -registrationX, -registrationY );
- Context.restore();
ローテーションとレジストレーション ポイントを理解するための優れた方法を次に示します。
- 一枚の紙を用意し、そのページに一文字書いてください。
- 鉛筆を手に取り、ページの任意の場所でそれを押し続けます。
- --鉛筆の先が登録点です。
- --鉛筆の先は移動(X,Y)です。
- 鉛筆の先を中心に紙を回転させます。
- --紙の回転はrotate(angle)
- --紙が動くと文字がどのように回転するかに注目してください。
- -- 赤いボックスが文字のように回転します (カメラの登録点を中心に)
- 用紙を直立回転に戻します。
- -- この「非回転」は、translate( -X, -Y )のようなものです。
- 紙の上の別の点に鉛筆を移動します
- -- 繰り返しますが、これは translate(newX,newY) のようなものです。
- 紙をもう一度回転させて、文字が異なるパターンでどのように回転するかに注目してください。
ここにコードとフィドルがあります:http://jsfiddle.net/m1erickson/nj29x/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:30px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var camX=100;
var camY=100;
var camRadius=40;
var camDegrees=0;
draw();
function draw(){
ctx.clearRect(0,0,canvas.width,canvas.height);
drawWorldRect(75,75,30,20,0,"blue","A");
drawWorldRect(100,100,30,20,15,"red","B");
drawCamera();
}
function drawWorldRect(x,y,width,height,angleDegrees,fillstyle,letter){
var cx=x+width/2;
var cy=y+height/2;
ctx.save();
ctx.translate(cx, cy);
ctx.rotate( (Math.PI / 180) * angleDegrees);
ctx.fillStyle = fillstyle;
ctx.fillRect(-width/2, -height/2, width, height);
ctx.fillStyle="white";
ctx.font = '18px Verdana';
ctx.fillText(letter, -6, 7);
ctx.restore();
}
function drawCamera(){
ctx.save();
ctx.lineWidth = 3;
ctx.beginPath();
// draw camera cross-hairs
ctx.strokeStyle = "#dddddd";
ctx.moveTo(camX,camY-camRadius);
ctx.lineTo(camX,camY+camRadius);
ctx.moveTo(camX-camRadius,camY);
ctx.lineTo(camX+camRadius,camY);
ctx.arc(camX, camY, camRadius, 0 , 2 * Math.PI, false);
ctx.stroke();
// draw camera site
ctx.fillStyle = "#222222";
ctx.beginPath();
ctx.arc(camX, camY-camRadius, 3, 0 , 2 * Math.PI, false);
ctx.fill()
ctx.restore();
}
function rotate(){
ctx.save();
ctx.translate(camX,camY);
ctx.rotate(Math.PI/180*camDegrees);
ctx.translate(-camX,-camY);
draw();
ctx.restore();
}
$("#rotateCW").click(function(){ camDegrees+=30; rotate(); });
$("#rotateCCW").click(function(){ camDegrees-=30; rotate(); });
$("#camUp").click(function(){ camY-=20; draw(); });
$("#camDown").click(function(){ camY+=20; draw(); });
$("#camLeft").click(function(){ camX-=20; draw(); });
$("#camRight").click(function(){ camX+=20; draw(); });
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=400 height=300></canvas><br/>
<button id="camLeft">Camera Left</button>
<button id="camRight">Camera Right</button>
<button id="camUp">Camera Up.</button>
<button id="camDown">Camera Down</button><br/>
<button id="rotateCW">Rotate Clockwise</button>
<button id="rotateCCW">Rotate CounterClockwise</button>
</body>
</html>