开发者

HTML5 Canvas: How to make a loading spinner by rotating the image in degrees?

I am making a loading spinner with html5 canvas. I have my graphic on the canvas but when i rotate it the image rotates off the canvas. How do I tell it to spin the graphic on its center point?

<!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.onl开发者_StackOverflow中文版oad = 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>


Here is the complete working example:)

<!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>


rotate turns the canvas(?) around your current position, which is 0, 0 to start. you need to "move" to your desired center point, which you can accomplish with

context.translate(x,y);

after you move your reference point, you want to center your image over that point. you can do this by calling

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

this tells the browser to start drawing the image from above and to the left of your current reference point, by have the size of the image, whereas before you were starting at your reference point and drawing entirely below and to the right (all directions relative to the rotation of the canvas).

since your canvas is the size of your image, your call to translate will use the same measurement, (27/2), for x and y coordinates.

so, to put it all together

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

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

edit: also, rotation units are radians, so you'll need to translate degrees to radians in your code.

edits for rearranging stuff.


For anyone else looking into something like this, you might want to look at this script which does exactly what was originally being requested: http://projects.nickstakenburg.com/spinners/

You can find the github source here: https://github.com/staaky/spinners

He uses rotate, while keeping a cache of rectangles which slowly fade out, the older they are.


I find another way to do html loading spinner. You can use sprite sheet animation. This approach can work both by html5 canvas or normal html/javascript/css. Here is a simple way implemented by html/javascript/css.

It uses sprite sheet image as background. It create a Javascript timer to change the background image position to control the sprite sheet animation. The example code is below. You can also check the result here: 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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜