Как повернуть объект холста, пока объект остается на том же месте

Я создаю игру Javascript. Речь идет о парне, который стоит на вершине мира. У меня уже есть земля, и теперь мне нужно ее повернуть, но когда я ее поворачиваю, она также меняет свое место.

Земля Земля

Как видите, земля вращается, но и меняет свое место. Я хочу, чтобы он вращался так же, как поворот ключевых кадров из css. Какие-нибудь мысли?

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="Style.css"/>
</head>
<body onload="draw()">
    <canvas id="canvas"></canvas>
</body>
<script>
var ctx = document.getElementById("canvas").getContext('2d');
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
    
setInterval(draw, 10);
function draw() {
    var img = new Image();
    img.onload = function(){
    ctx.rotate(1*Math.PI/180);
    ctx.drawImage(img,canvas.width/2-200,canvas.height/2-100,300,300);
  };
  img.src = "earth.png";
}
</script>
</html>

Код не работает, потому что он не может загрузить изображение, потому что я скачал его, но теперь у вас есть код, так что вы можете увидеть проблему.


person Martijn Ven van de    schedule 27.06.2016    source источник
comment
Код? Вероятно, он вращается вокруг начала координат, а не вокруг собственного центра.   -  person Arg0n    schedule 27.06.2016
comment
Я обновил его @Arg0n   -  person Martijn Ven van de    schedule 27.06.2016


Ответы (2)


См. эту скрипку.

HTML

<canvas id="canvas"></canvas>

JavaScript

var ctx = document.getElementById("canvas").getContext('2d');
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var img;

function draw() {
  img = new Image();
  img.onload = function(){
    setInterval(rotate, 10);
  };
  img.src = "https://pixabay.com/static/uploads/photo/2013/07/12/13/55/earth-147591_960_720.png";
}

draw();

var i = 0;
function rotate() {
  i += 1;
  drawRotatedImage(img, 100, 100, 200, 200, i);
}

var TO_RADIANS = Math.PI/180; 
function drawRotatedImage(image, x, y, width, height, angle) { 
  ctx.save();
  ctx.translate(x, y);
  ctx.rotate(angle * TO_RADIANS);
  ctx.drawImage(image, -width/2, -height/2, width, height);
  ctx.restore(); 
}
person Arg0n    schedule 27.06.2016
comment
@MartijnVenvande Нет проблем, наслаждайтесь :) - person Arg0n; 27.06.2016

Более быстрый способ, который позволяет избежать использования сохранения и восстановления.

Если вы рисуете 100 или 1000 изображений (например, для игр), использование сохранения и восстановления может сделать разницу между играбельным или нет. В некоторых ситуациях вызов восстановления может снизить частоту кадров с хороших 60 кадров в секунду до менее чем 10 кадров в секунду.

Всегда будьте осторожны при использовании сохранения и восстановления, убедитесь, что при сохранении у вас нет больших шаблонов или фильтров (если они поддерживаются), сложных градиентов или детализированных шрифтов. Вам лучше удалить эти вещи перед сохранением и восстановлением, если вы планируете делать многие из них.

Для одиночных изображений это не имеет значения, и предыдущий ответ — лучшее решение.

Рендеринг спрайтов общего назначения с вращением масштаба и исчезновением

// draws a image centered at x,y scaled by sx,sy rotate (r in radians) and faded by alpha (0-1)and 

    function drawImage(image,x,y,sx,sy,r,alpha){ // 
        ctx.setTransform(sx,0,0,sy,x,y);
        ctx.rotate(r);
        ctx.globalAlpha = alpha;
        ctx.drawImage(image,-image.width/2,-image.height/2);
    }

и без увядания

    function drawImage(image,x,y,sx,sy,r){ // 
        ctx.setTransform(sx,0,0,sy,x,y);
        ctx.rotate(r);
        ctx.drawImage(image,-image.width/2,-image.height/2);
    }

или если вы хотите иметь преобразование по умолчанию после вызова

    function drawImage(image,x,y,sx,sy,r){ // 
        ctx.setTransform(sx,0,0,sy,x,y);
        ctx.rotate(r);
        ctx.drawImage(image,-image.width/2,-image.height/2);
        ctx.setTransform(1,0,0,1,0,0);
    }

Поскольку вы можете захотеть отобразить много изображений подряд, вы можете восстановить контекст холста с помощью

function restoreContext(){
    ctx.globalAlpha = 1;
    ctx.setTransform(1,0,0,1,0,0);
}
person Blindman67    schedule 27.06.2016
comment
Спасибо, это полезно. - person Martijn Ven van de; 28.06.2016
comment
@MartijnVenvande Я только что написал более подробный ответ на очень похожий вопрос, который также может оказаться полезным для вас stackoverflow.com/a/38079796/3877726< /а> - person Blindman67; 28.06.2016