Javascript HTML5 Canvas:如何通过以度为单位旋转图像来制作加载微调器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2761100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:49:00  来源:igfitidea点击:

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

javascripthtmlcanvasrotation

提问by Bill

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?

我正在用 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>

回答by Bill

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>

回答by lincolnk

rotateturns 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

rotate围绕您的当前位置转动画布(?),从 0, 0 开始。你需要“移动”到你想要的中心点,你可以用

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 translatewill use the same measurement, (27/2), for x and y coordinates.

由于您的画布是图像的大小,因此您translate对 x 和 y 坐标的调用将使用相同的测量值 (27/2)。

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.

编辑重新排列的东西。

回答by benjamin.keen

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/

对于其他人正在研究这样的事情,你可能想看看这个脚本,它完全符合最初的要求:http: //projects.nickstakenburg.com/spinners/

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

你可以在这里找到 github 源:https: //github.com/staaky/spinners

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

他使用旋转,同时保留一个矩形缓存,这些矩形会慢慢淡出,它们越老。

回答by James

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.

我找到了另一种方法来做 html 加载微调器。您可以使用精灵表动画。这种方法可以通过 html5 canvas 或普通的 html/javascript/css 工作。下面是通过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

它使用精灵表图像作为背景。它创建一个 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>