2016-04-29 10 views
1

rotate()関数が描画領域全体を回転させているようです。パスを個別に回転する方法はありますか?回転の中心を描画領域ではなくオブジェクトにしたい。キャンバス内の個々のオブジェクトを回転させますか?

save()restore()を使用すると、全体の描画領域が考慮されます。

var canvas = document.getElementById('canvas'); 
 
var context = canvas.getContext('2d'); 
 
context.save(); 
 
context.fillStyle = 'red'; 
 
context.rotate(0.35); 
 
context.fillRect(40,40, 100, 100); 
 
context.restore(); 
 

 
context.save(); 
 
context.fillStyle = 'blue'; 
 
context.rotate(0.35); 
 
context.fillRect(200, 40, 100, 100); 
 
context.restore();
<canvas id="canvas" width="500" height="500"></canvas>

答えて

2

使用ローカル空間

代わりに、あなたは彼らがそのローカル空間に独自の原点を中心にすべてのものを描きたい位置にオブジェクトを描画します。原点は(0,0)にあり、オブジェクトが回転する場所です。

あなたは、それがその起源で描画されるように

function drawRect(){ 
    context.fillRect(-50,-50 , 100, 100); 
} 

function drawRect(){ 
    context.fillRect(200, 40, 100, 100); 
} 

変化に描く四角形を持っている場合は、

をしたいwhereveryだから今、あなたは簡単にそれを描くことができます

既存のトランスフォームをクリアするsetTransform関数から始めて、オブジェクトの中心の位置を設定する便利な方法は

0123です
ctx.setTransform(1,0,0,1,posX,posY); // clear transform and set center location 

あなたはそれを回転させたい場合は、あなたが回転する前に拡張すべき二つの異なるスケールを持っているならば、

ctx.scale(scale,scale); 

ctx.rotate(ang); 

とスケール回転を追加します。

は今だけ

drawRect(); 

描画関数を呼び出し、それがPOSXを中心に描かれている、POSYが回転し、スケール。

x、yの位置、幅と高さ、位取りと回転を持つ関数にすべてを組み合わせることができます。あなたは上の2000のスプライトを描画することができます6歳のラップトップで

function drawImage(img,x,y,w,h,scale,rotation,alpha){ 
    ctx.globalAlpha = alpha; 
    ctx.setTransform(scale,0,0,scale,x,y); 
    ctx.rotate(rotation); 
    ctx.drawImage(img,-img.width/2,-img.height/2,img.width,img.height); 
} 

をまた、スプライトとして画像に適用され、私はアルファが含まれるのsetTransformに

function drawRect(x,y,w,h,scale,rotation){ 
    ctx.setTransform(scale,0,0,scale,x,y); 
    ctx.rotate(rotation); 
    ctx.strokeRect(-w/2,-h/2,w,h); 
} 

をスケールを含むことができ、ファイアフォックスは1/60th毎秒、回転、拡大縮小、配置、アルファフェードで再生されます。

前後の翻訳を混乱させる必要はありません。あなたが描いているすべてのオブジェクトを元のものに保ち、その起源を変換を介して移動してください。

更新 ここでデモを失ったので、実際にどのように行うかを示します。

多くの回転、拡大縮小された翻訳、アルファ付きの長方形を描画します。あなたは、その中心の周りの形状の点のすべてを回転させる回転機能を使用し

// create canvas and add resize 
 
var canvas,ctx; 
 
function createCanvas(){ 
 
    canvas = document.createElement("canvas"); 
 
    canvas.style.position = "absolute"; 
 
    canvas.style.left  = "0px"; 
 
    canvas.style.top  = "0px"; 
 
    canvas.style.zIndex = 1000; 
 
    document.body.appendChild(canvas); 
 
} 
 
function resizeCanvas(){ 
 
    if(canvas === undefined){ 
 
     createCanvas(); 
 
    } 
 
    canvas.width   = window.innerWidth; 
 
    canvas.height   = window.innerHeight; 
 
    ctx   = canvas.getContext("2d"); 
 
} 
 
resizeCanvas(); 
 
window.addEventListener("resize",resizeCanvas); 
 

 

 
// simple function to draw a rectangle 
 
var drawRect = function(x,y,w,h,scale,rot,alpha,col){ 
 
    ctx.setTransform(scale,0,0,scale,x,y); 
 
    ctx.rotate(rot); 
 
    ctx.globalAlpha = alpha; 
 
    ctx.strokeStyle = col; 
 
    ctx.strokeRect(-w/2,-h/2, w, h); 
 

 
} 
 

 
// create some rectangles in unit scale so that they can be scaled to fit 
 
// what ever screen size this is in 
 
var rects = []; 
 
for(var i = 0; i < 200; i ++){ 
 
    rects[i] = { 
 
    x : Math.random(), 
 
    y : Math.random(), 
 
    w : Math.random() * 0.1, 
 
    h : Math.random() * 0.1, 
 
    scale : 1, 
 
    rotate : 0, 
 
    dr : (Math.random() - 0.5)*0.1, // rotation rate 
 
    ds : Math.random()*0.01, // scale vary rate 
 
    da : Math.random()*0.01, // alpha vary rate 
 
    col : "hsl("+Math.floor(Math.random()*360)+",100%,50%)", 
 
    }; 
 
} 
 

 
// draw everything once a frame 
 
function update(time){ 
 
    var w,h; 
 
    w = canvas.width; // get canvas size incase there has been a resize 
 
    h = canvas.height; 
 
    ctx.setTransform(1,0,0,1,0,0); // reset transform 
 
    ctx.clearRect(0,0,w,h); // clear the canvas 
 
    
 
    // update and draw each rect 
 
    for(var i = 0; i < rects.length; i ++){ 
 
    var rec = rects[i]; 
 
    rec.rotate += rec.dr; 
 
    drawRect(rec.x * w, rec.y * h, rec.w * w,rec.h * h,rec.scale + Math.sin(time * rec.ds) * 0.4,rec.rotate,Math.sin(time * rec.da) *0.5 + 0.5,rec.col); 
 
    } 
 
    
 
    requestAnimationFrame(update); // do it all again 
 
} 
 
requestAnimationFrame(update);

0

キャンバスのすべての変換は、全体の描画領域のためのものです。その点を原点に変換しなければならない点を中心に回転させたい場合は、回転して元に戻します。 thisのようなものがあなたの望むものです。

+0

ただし、2番目の回転は最初のオブジェクトに影響しますか?それは私が望むものではありません。 – katie

+0

の前に描画されたオブジェクトにのみ影響を与えるように、それぞれ回転したいと思います。それらの後に起こることに変換が適用されます。したがって、rotateを呼び出した後にfillRectを呼び出すと、それは適用される回転の前になります。 2番目のオブジェクトに対して異なる量だけ回転させたい場合は、呼び出す前に別の回転値を使用してください。 – CrazyCasta

0

の保存と復元避けることによって、多くの時間を節約するのsetTransformを使用することにより

<!DOCTYPE html> 
<html> 
<head> 
    <style> 
     body 
     { 
      margin: 0px; 
      padding: 0px; 
      overflow: hidden; 
     } 
     canvas 
     { 
      position: absolute; 
     } 
    </style> 
</head> 
<body> 
<canvas id="canvas"></canvas> 
<script> 
    var canvas; 
    var context; 
    canvas = document.getElementById("canvas"); 
    context = canvas.getContext("2d"); 
    canvas.width = window.innerWidth; 
    canvas.height = window.innerHeight; 
    var degreesToRadians = function(degrees) 
    { 
     return degrees*Math.PI/180; 
    } 
    var rotate = function(x, y, cx, cy, degrees) 
    { 
     var radians = degreesToRadians(degrees); 
     var cos = Math.cos(radians); 
     var sin = Math.sin(radians); 
     var nx = (cos * (x - cx)) + (sin * (y - cy)) + cx; 
     var ny = (cos * (y - cy)) - (sin * (x - cx)) + cy; 
     return new Vector2(nx, ny); 
    } 
    var Vector2 = function(x, y) 
    { 
     return {x:x,y:y}; 
    } 
    var Shape = function(points, color) 
    { 
     this.color = color; 
     this.points = points; 
    }; 
    Shape.prototype.rotate = function(degrees) 
    { 
     var center = this.getCenter(); 
     for (var i = 0; i < this.points.length; i++) 
     { 
      this.points[i] = rotate(this.points[i].x,this.points[i].y,center.x,center.y,degrees); 
     } 
     context.beginPath(); 
     context.arc(center.x,center.y,35,0,Math.PI*2); 
     context.closePath(); 
     context.stroke(); 
    } 
    Shape.prototype.draw = function() 
    { 
     context.fillStyle = this.color; 
     context.strokeStyle = "#000000"; 
     context.beginPath(); 
     context.moveTo(this.points[0].x, this.points[0].y); 
     for (var i = 0; i < this.points.length; i++) 
     { 
      context.lineTo(this.points[i].x, this.points[i].y); 
      //context.fillText(i+1, this.points[i].x, this.points[i].y); 
     } 
     context.closePath(); 
     context.fill(); 
     context.stroke(); 
    } 
    Shape.prototype.getCenter = function() 
    { 
     var center = {x:0,y:0}; 
     for (var i = 0; i < this.points.length; i++) 
     { 
      center.x += this.points[i].x; 
      center.y += this.points[i].y; 
     } 
     center.x /= this.points.length; 
     center.y /= this.points.length; 
     return center; 
    } 
    Shape.prototype.translate = function(x, y) 
    { 
     for (var i = 0; i < this.points.length; i++) 
     { 
      this.points[i].x += x; 
      this.points[i].y += y; 
     } 
    } 
    var Rect = function(x,y,w,h,c) 
    { 
     this.color = c; 
     this.points = [Vector2(x,y),Vector2(x+w,y),Vector2(x+w,y+h),Vector2(x,y+h)]; 
    } 
    Rect.prototype = Shape.prototype; 
    var r = new Rect(50, 50, 200, 100, "#ff0000"); 
    r.draw(); 
    r.translate(300,0); 
    r.rotate(30); 
    r.draw(); 

</script> 
</body> 
</html> 
関連する問題