web-dev-qa-db-ja.com

HTML5 Canvas:画像を度単位で回転させて読み込みスピナーを作成するにはどうすればよいですか?

Html5キャンバスで読み込みスピナーを作成しています。キャンバスにグラフィックがありますが、回転すると画像がキャンバスから回転します。グラフィックを中心点で回転させるにはどうすればよいですか?

<!DOCTYPE html>
<html>
 <head>
  <title>Canvas test</title>
  <script type="text/javascript">
   window.onload = function() {
    var drawingCanvas = document.getElementById('myDrawing');
    // Check the element is in the DOM and the browser supports canvas
    if(drawingCanvas && drawingCanvas.getContext) {
     // Initaliase a 2-dimensional drawing context
     var context = drawingCanvas.getContext('2d');

     //Load the image object in JS, then apply to canvas onload     
     var myImage = new Image();
     myImage.onload = function() {
      context.drawImage(myImage, 0, 0, 27, 27);
     }
     myImage.src = "img/loading.png";

     context.rotate(45);
    }
   }
  </script>
 </head>
 <body>
  <canvas id="myDrawing" width="27" height="27">
  </canvas>
 </body>
</html>
18
Bill

これが完全な実例です:)

<!DOCTYPE html>
<html>
    <head>
        <title>Canvas Cog</title>
        <script type="text/javascript">
            var cog = new Image();
            function init() {
                cog.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAYAAACN1PRVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABK1JREFUeNqMVt1ZGzkUvVfS4IW1l8GO82w6IBXE7mCpAFMB+Pt4Z6iApALcAe4AU0HoAJfg7BPYHinnXmmciX+y0YdmJHnQ0bk/R5cvh5cUyFPwRD4EChgEvGWMB36R3+JaiTkmD5gOs8yNb25uLlerFf1pM2yIGA82TEY7xow1oj4GBU6S6yywPNG4JwDH+XGv0Whs7ndN8n97mmPsLCSYgy7ImPQE/pFDyAF+7L0fgTNFUDBcLal90taD1doQ/T6NT9DnW8zkT+jJuQVYukG3hifCVk/L3JOxMBa8VVlSp9MhHKLaB+zpNo1fdgEpmByuMqUAV5viOQLwXNax9KBAFNEEpN1pUwnQmvl6aTza6zNjrCKaymeyOdYAMgfg18iG4T/qw+AC94zvpzDjcwqOXo3VGH26H0xMZ7jPxgT0R2zUi4BYt6bAfEbJvJFZKA4ODgZ5nhcJLE9mk35X21vWC/TXKmiwr2xszoQd/PQv3t/QCzY2twpqBpb5FKOp+hCgzWaTWq0W1Xx0ij5An9WC5VtiLMwvNBrVaSGMvQk5jHQVPN7sb0HzAtE+QJrNgrcUNEARieWCut0ugR0tl8sKcJ5Ahc3jRviPK8ZGTaaBwGKyT+gTiwM4a3Jrba6MbeVXo5F4kp9shn29ndUYC9vLirGDXzRhrYhD8DME5Hkg22df5rDYS/RXmVIsaP/Q/SXs600YnifTjbeSWliEdTYb3QyTqYfdDKTL4B1KS6tVqf6SgGq3P9BvZGpvNIrPCgVKZlGlCDQDxJiCjVppCab05DJHzb+b1Gm36X80cVjLuzozexs0f6IgRkA5XRhzIixRL1+IzhwdHVHrn1Y9oXe1i10aKT6bGGhg1CKK+cT0zCGCs0oXTIogybJMw/779//o48duMvnO9rzLn+Kz8wgS5Shqo4njpCoOQA5Ajb8adHh4SMvVghaLhYb/HsBip88krNVISSEigOlhjmi0LziNhr6wOsgO9C1339vbGznnNAU2AM9Svk235cqKieKGkldAf7DGvTrjnjJnzyQoMu0ZTuZgUqvmlYR+f39XIE4uqCX1E/rDZpCYmKwOOmivAfYK9KF1AM7EdG4uAMLAOjmQideQXOJQkyUisqYiFRhtSFbxCxj8do0T30dmTvLhC+an0MZZVBHX09tBTG4qFigZEJEChjTIEwtRik81Qa7uOQU0IrYAe7FRjqYw6SlYjgAyN1GmHsFIGPfVnxzFuFITKEkfYK+oWZ5qKlIkcZ7UE92oXBmeIgIxtAO5UtSHqo9uiLW+sme5ejSIRASeAFR4LYy8MMzL1aq3EYWzJF28BgMEzGYpBkrMKelgl+P6uTcVY8NjLYyYPwMTCcufSaouH6al9xNJcjC82vDb9uVZKbrWIumNO+waVsu1TCC+Wxcg6xaSpsZSYM2wLO9/U8qZWH+wztQnsfAxV/E3MIKZVf1FsmJVV8mamhEmxZ0X7sSsABsGv1tZJGejmptU7FBUDYzPAXQBwFEEl+9+stFEroJEci2ELwIMmZuWoSTE9DYYcWVCjlJrZWMpeBhlAEqBiulPE84S3ixU5gSTwGGOdyEVNJXxA8nPevshwABHktBS1YoQ+QAAAABJRU5ErkJggg=='; // Set source path
                setInterval(draw,10);
            }
            var rotation = 0;
            function draw(){
                var ctx = document.getElementById('myCanvas').getContext('2d');
                ctx.globalCompositeOperation = 'destination-over';
                ctx.save();
                ctx.clearRect(0,0,27,27);
                ctx.translate(13.5,13.5); // to get it in the Origin
                rotation +=1;
                ctx.rotate(rotation*Math.PI/64); //rotate in Origin
                ctx.translate(-13.5,-13.5); //put it back
                ctx.drawImage(cog,0,0);
                ctx.restore();
            }
            init();
        </script>
    </head>
    <body>
        <canvas width="27" height="27" id="myCanvas"></canvas>
    </body>
</html>
28
Bill

rotateは、現在の位置(0、0)を中心にキャンバス(?)を回転させて開始します。目的の中心点に「移動」する必要があります。これは、次の方法で実行できます。

context.translate(x,y);

参照点を移動した後、画像をその点の中央に配置します。あなたは呼び出すことによってこれを行うことができます

context.drawImage(myImage, -(27/2), -(27/2), 27, 27);

これにより、ブラウザは、現在の参照点の上と左から画像のサイズを指定して画像の描画を開始するように指示されますが、参照点から開始して完全に下と右に描画する前(すべての方向は相対的)キャンバスの回転に)。

キャンバスは画像のサイズであるため、translateの呼び出しでは、x座標とy座標に同じ測定値(27/2)が使用されます。

だから、それをすべてまとめるには

// initialization:
context.translate(27/2, 27/2);

// onload: 
context.rotate(Math.PI * 45 / 180);
context.drawImage(myImage, -(27/2), -(27/2), 27, 27);

編集:また、回転単位はラジアンであるため、コードで度をラジアンに変換する必要があります。

ものを再配置するための編集。

5
lincolnk

このようなことを検討している他の人は、最初に要求されていたものを正確に実行するこのスクリプトを確認することをお勧めします。 http://projects.nickstakenburg.com/spinners/

ここでgithubソースを見つけることができます: https://github.com/staaky/spinners

彼は回転を使用しますが、ゆっくりとフェードアウトする長方形のキャッシュは古くなります。

1
benjamin.keen

HTML読み込みスピナーを実行する別の方法を見つけました。スプライトシートアニメーションを使用できます。このアプローチは、html5キャンバスまたは通常のhtml/javascript/cssの両方で機能します。これは、html/javascript/cssによって実装される簡単な方法です。

スプライトシート画像を背景として使用します。スプライトシートのアニメーションを制御するために背景画像の位置を変更するJavascriptタイマーを作成します。サンプルコードは以下のとおりです。ここで結果を確認することもできます: http://jmsliu.com/1769/html-ajax-loading-spinner.html

<html>
<head><title></title></head>
<body>
    <div class="spinner-bg">
        <div id="spinner"></div>
    </div>
    <style>
        .spinner-bg
        {
            width:44px;
            height:41px;
            background: #000000;
        }

        #spinner
        {
            width: 44px;
            height: 41px;
            background:url(./preloadericon.png) no-repeat;
        }
    </style>
    <script>
        var currentbgx = 0;
        var circle = document.getElementById("spinner");
        var circleTimer = setInterval(playAnimation, 100);

        function playAnimation() {
            if (circle != null) {
                circle.style.backgroundPosition = currentbgx + "px 0";
            }

            currentbgx -= 44; //one frame width, there are 5 frame
            //start from 0, end at 176, it depends on the png frame length
            if (currentbgx < -176) {
                currentbgx = 0;
            }
        }
    </script>
</body>
0
James