Я хочу создать анимацию, изображенную на следующей диаграмме слева. Он должен визуализировать то есть облака, вращающиеся вокруг сферы.

Wrong rotation around a pivot

Я хочу, чтобы облако A вращалось вокруг точки поворота X в некотором фиксированном радиусе (например, 100 пикселей). Конечно, необходимо, чтобы облако было правильно ориентировано, иначе это выглядело бы странно. Я добился эффекта вращения вокруг оси на фиксированном расстоянии, но мой прямоугольник был неправильно ориентирован (см. Рисунок справа).

Код следующий:

<canvas id="cloudsCanvas" width="1050" height="300"></canvas>
   <script>
        var cloudCenter = [400, 400];

        // pivot point coordinates
        var cx = 1050 / 2;
        var cy = 800;
        var deg = 45;

        var cloud1 = new Image;


        window.onload = function () {
            var cloudsCanvas = document.getElementById("cloudsCanvas");
            var cloudsContext = cloudsCanvas.getContext("2d");

            setInterval(function () {
                cloudsContext.save();
                cloudsContext.clearRect(0, 0, cloudsCanvas.width, cloudsCanvas.height);

                deg += 1;
                // Center the needle on the canvas.
                cloudsContext.translate(cx, cy);
                cloudsContext.rotate(deg * Math.PI / 180);
                cloudsContext.drawImage(cloud1, cloudCenter[0], cloudCenter[1]);

                cloudsContext.restore();
            }, 50);

        };

        cloud1.src = './img/cloud1.png';
 </script>

Любые идеи, как это исправить? Спасибо!

2
Very Curious 17 Дек 2013 в 20:08

2 ответа

Лучший ответ

Угол 0 всегда указывает вправо, поэтому просто создайте облако, которое предварительно повернуто на 90 градусов по часовой стрелке (как если бы оно было нарисовано в этом месте) - оно должно выглядеть так:

cloud

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

Измененная скрипка здесь

Вам также необходимо внести некоторые другие изменения в свой код:

  • cloudCenter должен быть начальной позицией справа от земного шара (т. е. местом, где он будет находиться под углом 0 градусов)
  • перевести обратно после вращения

Как это:

cloudsContext.translate(cx, cy);
cloudsContext.rotate(deg * Math.PI / 180);
cloudsContext.translate(-cx, -cy);
cloudsContext.drawImage(cloud1, cloudCenter[0], cloudCenter[1]);
1
17 Дек 2013 в 17:52

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

Но если вы хотите знать, как это сделать программно, вот пример и скрипт.

Демо: http://jsfiddle.net/m1erickson/YqBC2/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
    $(function(){

        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");

        var angle=0;
        var cx=150;
        var cy=150;
        var radius=50;
        var img90;

        var img=new Image()
        img.onload=function(){
            canvas.width=img.height;
            canvas.height=img.width;
            ctx.save();
            ctx.translate(canvas.width/2,canvas.height/2);
            ctx.rotate(Math.PI/2);
            ctx.drawImage(img,-img.width/2,-img.height/2);
            ctx.restore();
            img90=new Image();
            img90.onload=function(){
                canvas.width=300;
                canvas.height=300;
                animate();
            }
            img90.src=canvas.toDataURL();
        }
        img.crossOrigin="anonymous";
        img.src="https://dl.dropboxusercontent.com/u/139992952/cloud1.png";


        function draw(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            ctx.beginPath();
            ctx.arc(cx,cy,radius,0,Math.PI*2);
            ctx.closePath();
            ctx.fillStyle="orange";
            ctx.fill();
            ctx.stroke();

            ctx.save();
            ctx.translate(cx,cy);
            ctx.rotate(angle);
            ctx.drawImage(img90,radius+35-img.width/2,-img.height/2);
            ctx.restore();

        }

        function animate() {
            requestAnimationFrame(animate);

            // Drawing code goes here
            angle+=Math.PI/360;
            draw();
        }


    }); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=350 height=350></canvas>
</body>
</html>
1
markE 17 Дек 2013 в 17:46