使用本地空间
相反的位置描绘对象,你希望他们周围画了自己的一切都起源在其本地空间。原点位于(0,0)处,并且是对象旋转的位置。
所以,如果您有与
function drawRect(){
context.fillRect(200, 40, 100, 100);
}
改变它绘制,以便它在它的起源绘制一个矩形
function drawRect(){
context.fillRect(-50,-50 , 100, 100);
}
现在你可以很容易地画出它wherevery你想
以setTransform函数开始,因为它可以清除任何现有的变形,并且是设置对象中心位置的便捷方法将是
ctx.setTransform(1,0,0,1,posX,posY); // clear transform and set center location
如果你想旋转,然后将其与
ctx.scale(scale,scale);
添加旋转
ctx.rotate(ang);
和规模,如果你有你的旋转前,应扩大两个不同的尺度。
现在只需调用绘制函数
drawRect();
,并绘制其在POSX中心,波西旋转和缩放。
你可以把它全部合并成一个具有x,y位置,宽度和高度,缩放和旋转功能。您可以包括规模在一个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);
}
它也适用于图像作为一个精灵,我将包括阿尔法
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);
}
在一个6岁的笔记本电脑,可以借鉴2000个精灵firefox每1/60秒,每个旋转,缩放,定位,并与阿尔法淡入淡出。
没有必要混淆翻译回来和前进。只需保留所有绘制的对象都有自己的原点并通过变换移动原点。
更新 失去了演示,所以这里是展示如何在实践中做到这一点。
只画了很多旋转的,缩放翻译的字母矩形。
使用的setTransform你避免保存和恢复
// 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);
但第二次旋转仍会影响第一个对象吗?那不是我想要的。我想每个旋转只影响之前绘制的对象 – katie
转换适用于后面发生的事情。所以当你在调用rotate之后调用fillRect的时候,就是前面的rotate应用了。如果要为第二个对象旋转不同的量,请在调用它之前使用不同的旋转值。 – CrazyCasta