如何使用本机 javascript 旋转图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18033812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to rotate Image using native javascript
提问by Warlock
I'm developing a game using HTML5 canvas element and native javascript. I have different sprites for game objects. Is it possible to rotate sprites using native javascript?
我正在使用 HTML5 画布元素和本机 javascript 开发游戏。我有不同的游戏对象精灵。是否可以使用本机 javascript 旋转精灵?
For example, I have a sprite image like this:
例如,我有一个像这样的精灵图像:
I use Imagefor this sprite:
我为这个精灵使用Image:
var image = new Image(...);
image.src = "...";
After loading I want to rotate this image and save different projections in local variables:
加载后我想旋转这个图像并将不同的投影保存在局部变量中:
var sprite_left = rotate(image, 0),
sprite_top = rotate(image, 90),
sprite_right = rotate(image, 180),
sprite_right = rotate(image, 270);
The rotate function should look like this:
旋转函数应如下所示:
function rotate(sourceImage, angle){
...
}
Could anybody help me to write the rotate function?
有人可以帮我写旋转函数吗?
EDIT:
编辑:
I have decided to share my code, which I used to test my sprites:
我决定分享我用来测试精灵的代码:
var wait = function (image, completed, count) {
if (count == null) count = 0;
if (!image.complete && count < 1000) {
count++;
window.setTimeout(function () {
wait(image, completed, count);
console.log('waiting...');
}, 10);
}
else {
completed();
}
},
rotateW = function (image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var p = document.createElement("p");
p.innerText = "W: ";
p.appendChild(canvas);
document.body.appendChild(p);
var context = canvas.getContext("2d");
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(Math.PI);
context.translate(-canvas.width / 2, -canvas.height / 2);
context.drawImage(image, 0, 0);
var newImage = new Image();
newImage.src = canvas.toDataURL("image/png");
return newImage;
},
rotateE = function (image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var p = document.createElement("p");
p.innerText = "E: ";
p.appendChild(canvas);
document.body.appendChild(p);
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0);
var newImage = new Image();
newImage.src = canvas.toDataURL("image/png");
return newImage;
},
rotateS = function (image, frameCount) {
var canvas = document.createElement("canvas");
canvas.width = image.height * frameCount;
canvas.height = image.width / frameCount;
var p = document.createElement("p");
p.innerText = "S: ";
p.appendChild(canvas);
document.body.appendChild(p);
var context = canvas.getContext("2d");
context.translate(image.height / 2, image.width / (2 * frameCount));
context.rotate(Math.PI / 2);
var i = frameCount;
while (i--> 0) {
context.drawImage(image, - image.width / 2 , - ( 0.5 + i ) * image.height);
}
var newImage = new Image();
newImage.src = canvas.toDataURL("image/png");
return newImage;
},
rotateN = function (image, frameCount) {
var canvas = document.createElement("canvas");
canvas.width = image.height * frameCount;
canvas.height = image.width / frameCount;
var p = document.createElement("p");
p.innerText = "N: ";
p.appendChild(canvas);
document.body.appendChild(p);
var context = canvas.getContext("2d");
context.translate(image.height / 2, image.width / (2 * frameCount));
context.rotate( 3 * Math.PI / 2);
var i = frameCount;
while (i-- > 0) {
context.drawImage(image, -image.width / 2, (frameCount - i - 1.5) * image.height);
}
var newImage = new Image();
newImage.src = canvas.toDataURL("image/png");
return newImage;
};
/*
N
|
W----O----E
|
S
*/
getSprites = function (image, frameCount) {
var sprite = {
N: rotateN(image, frameCount),
S: rotateS(image, frameCount),
W: rotateW(image, frameCount),
E: rotateE(image, frameCount)
};
return [
sprite.W, // left
sprite.N, // up
sprite.E, // right
sprite.S] // down
};
$.sprite = {
register: function (options) {
var image = new Image();
image.src = options.src;
wait(image, function () {
var sprites = getSprites(image, options.frameCount);
});
}
};
The final result is:
最终结果是:
回答by GameAlchemist
the following function will create a new Canvas out of img (which might be an image or a canvas). Give it an angle in radian, or 'N', 'S', 'W' for the corresponding rotation.
以下函数将从 img(可能是图像或画布)创建一个新的 Canvas。给它一个弧度的角度,或者'N'、'S'、'W'以进行相应的旋转。
function createRotatedImage(img, angle) {
angle = (angle == 'N') ? -Math.PI/2 :
(angle == 'S') ? Math.PI/2 :
(angle == 'W') ? Math.PI :
angle ;
var newCanvas = document.createElement('canvas');
newCanvas.width = img.width ;
newCanvas.height = img.height ;
var newCtx = newCanvas.getContext('2d') ;
newCtx.save () ;
newCtx.translate ( img.width / 2, img.height / 2) ;
newCtx.rotate (angle);
newCtx.drawImage ( img, - img.width / 2, - img.height / 2) ;
newCtx.restore () ;
}
回答by Paul S.
- Use a
<canvas>
to pre-render the different rotations - Store these in memory using via
toBlob
, optionally converting these blobs to URLs withwindow.URL.createObjectURL
- Swap URLs as desired.
- 使用 a
<canvas>
预渲染不同的旋转 - 使用 via
toBlob
将这些存储在内存中,可选择将这些 blob 转换为 URLwindow.URL.createObjectURL
- 根据需要交换 URL。
See thisMDN pagefor canvas options
有关画布选项,请参阅此MDN 页面
回答by loxxy
How about having a function like :
有一个像这样的功能怎么样:
Image.prototype.rotate = function(angle) {
var c = document.createElement("canvas");
c.width = this.width;
c.height = this.height;
var ctx = c.getContext("2d");
ctx.rotate(angle);
var imgData = ctx.createImageData(this.width, this.height);
ctx.putImageData(imgData);
return new Image(imgData);
}
var img1 = new Image();
var img2 = img1.rotate(90);
Ofcourse it's just a quick sample to give you an idea.
当然,这只是给您一个想法的快速示例。
回答by Kirk Backus
Absolutely! It's not as simple as rotating the image, though. You need to rotate the context from the canvas, and draw that image on the rotated context, and then restore it.
绝对地!不过,这并不像旋转图像那么简单。您需要从画布旋转上下文,并在旋转的上下文上绘制该图像,然后恢复它。
context.save();
context.rotate(angle);
//DRAW IT!
context.restore();