2013-08-03 2 views
1

Я разрабатываю игру с использованием элемента canvas HTML5 и собственного javascript. У меня разные спрайты для игровых объектов. Можно ли вращать спрайты с помощью встроенного javascript?Как повернуть изображение, используя собственный javascript

К примеру, у меня есть спрайт изображения, как это:

enter image description here

Я использую Image для этого спрайта:

var image = new Image(...); 

image.src = "..."; 

После загрузки я хочу повернуть это изображение и сохранить различные проекции в местных переменных:

var sprite_left = rotate(image, 0), 
    sprite_top = rotate(image, 90), 
    sprite_right = rotate(image, 180), 
    sprite_right = rotate(image, 270); 

Повернуть функция должна выглядеть следующим образом:

function rotate(sourceImage, angle){ 
... 
} 

Может кто-нибудь помочь мне написать функцию поворота?

EDIT:

я решил поделиться мой код, который я использовал, чтобы проверить мои спрайтов:

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); 
     }); 
    } 
}; 

Конечный результат:

enter image description here

+2

Либо использовать CSS или вместо '' , используйте '' . –

+0

Использование CSS или может привести к проблемам с производительностью :( – Warlock

+1

Как насчет использования '' для предварительного рендеринга разных оборотов, а затем хранения их в памяти с помощью 'toBlob', конвертируя эти капли в _URLs_ с помощью' window.URL. createObjectURL', а затем поменять URL-адреса по желанию (см. https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement для опций холста) –

ответ

2
  1. Используйте <canvas> предварительно делают различные повороты
  2. хранить их в памяти с использованием с помощью toBlob, необязательно превращают эти капли в URL-адресов с window.URL.createObjectURL
  3. своп URL, как хотелось бы.

См this MDN page варианты холст

1

Raphael будет отличной библиотекой для поворота изображения. здесь demo

+0

Спасибо, но я не хочу для использования внешних библиотек для этой незначительной задачи. – Warlock

1

Абсолютно! Однако это не так просто, как поворот изображения. Вам нужно повернуть контекст с холста и нарисовать это изображение во вращающемся контексте, а затем восстановить его.

context.save(); 
context.rotate(angle); 

//DRAW IT! 

context.restore(); 
+0

Я думаю, что OP хочет, чтобы каждая часть изображения была повернута и сохранена до рендеринга на холсте ... – loxxy

3

следующая функция создаст новый холст из из IMG (который может быть изображение или холст). Дайте ему угол в радине, или '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 () ; 
} 
2

Как о наличии функции, как:

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 это просто быстрый образец, чтобы дать вам идею.

+1

Я думаю, вы имели в виду ctx.putImageData (это) и только после того, как вы извлекли imageData. Но на самом деле просто возвращение холста в порядке, поскольку putImage работает еще быстрее с холстом, чем с изображением. – GameAlchemist

Смежные вопросы