使用 html5 canvas 的等待动画

发布于 2024-12-23 05:21:58 字数 1751 浏览 2 评论 0原文

我正在尝试实现在此问题中提到的那种等待动画,特别是看起来像这样的动画:

在此处输入图像描述

但我不想使用图形文件,并且我尝试纯粹在 html5 canvas 和 javascript 中实现它。另外,我想要一个圆形的黑色背景而不是方形的。作为第一步,我尝试绘制一个静态框架(没有任何移动/旋转)并执行以下操作:

<html>
<head><script>
window.onload = function(){
    var c=document.getElementById("waiting").getContext("2d");
    c.lineCap="round";
    c.fillStyle="#353535";
    c.translate(100,100);
    function slit(p){
        shade = 256*p;
        th = 2*Math.PI*p;
        cos = Math.cos(th);
        sin = Math.sin(th);
        c.strokeStyle = '#'+((shade<<16)+(shade<<8)+shade).toString(16);
        c.moveTo(55*cos, 55*sin);
        c.lineTo(84*cos, 84*sin);
        c.stroke();
        c.closePath();
    }
    c.lineWidth=0;
    c.arc(0,0,100,0,Math.PI*2);
    c.fill();
    c.lineWidth=7;
    for(var i = 0;i<1;i+=0.05){slit(i);}
}
</script></head>
<body><canvas id="waiting" width=200 height=200></canvas></body>
</html>

我得到的结果是:

“在此处输入图像描述”

问题在于,lineCap="round" 无法对所有“狭缝”正常工作,并且 lineWidth=0 属性不适用于圆的边缘。我做错了什么?我用Chrome 16.0.912.63和Firefox 10.0检查过,得到了类似的结果。


下一步,我将让上面创建的部分函数进行交互,

window.animationFrames = (function(callback){
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){window.setTimeout(callback, 1000 / 60);};
 })();

但目前我需要先解决这个问题。

I am trying to implement a wating animation of the kind mentioned in this question, particularly something that looks like this:

enter image description here

But I do not want to use graphic files, and am trying to implement it purely in html5 canvas and javascript. Also, I want a circular black background rather than a square one. As a first step, I tried to draw a static frame (without any movement/rotation) and did this:

<html>
<head><script>
window.onload = function(){
    var c=document.getElementById("waiting").getContext("2d");
    c.lineCap="round";
    c.fillStyle="#353535";
    c.translate(100,100);
    function slit(p){
        shade = 256*p;
        th = 2*Math.PI*p;
        cos = Math.cos(th);
        sin = Math.sin(th);
        c.strokeStyle = '#'+((shade<<16)+(shade<<8)+shade).toString(16);
        c.moveTo(55*cos, 55*sin);
        c.lineTo(84*cos, 84*sin);
        c.stroke();
        c.closePath();
    }
    c.lineWidth=0;
    c.arc(0,0,100,0,Math.PI*2);
    c.fill();
    c.lineWidth=7;
    for(var i = 0;i<1;i+=0.05){slit(i);}
}
</script></head>
<body><canvas id="waiting" width=200 height=200></canvas></body>
</html>

The result I get is:

enter image description here

The problem is that, the lineCap="round" is not working correctly for all of the "slits", and the lineWidth=0 attribute is not working for the edge of the circle. What am I doing wrong? I checked it with Chrome 16.0.912.63 and Firefox 10.0, and got similar results.


For the next step, I am going to let parts of the functions that I created above interact with

window.animationFrames = (function(callback){
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){window.setTimeout(callback, 1000 / 60);};
 })();

but for the time being, I need to solve this problem first.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

娇柔作态 2024-12-30 05:21:58

这里有一点混乱。

零不是可接受的线宽值。规范规定,如果您说 lineWidth = 0 这将是一个空操作。

此外,您没有在那里使用 lineWidth ,因为您没有抚摸。 fill() 不考虑线宽。

至于另一个问题,你所要做的就是调用beginPath!请参阅此处:

http://jsfiddle.net/JfcDL/

只需添加 beginPath 调用,您将通过代码得到以下内容:

在此处输入图像描述

您所做的错误是绘制整个路径到目前为止每一个新的中风()。您需要调用 beginPath 打开一个新的路径,以便 lines 仅适用于最后一个零件,而不适用于迄今为止制作的所有零件。

There's a bit of confusion here.

Zero is not an acceptable value for line width. The spec dictates that if you say lineWidth = 0 that it will be a no-op.

Furthermore you are not using lineWidth there because you are not stroking. fill() does not take line width into account.

As for the other issue, all you have to do is call beginPath! See here:

http://jsfiddle.net/JfcDL/

Just adding the beginPath call and you'll get this with your code:

enter image description here

What you were doing incorrectly was drawing the entire path so far with every new stroke(). You need to call beginPath to open a new one so that the stroke only applies to the last part and not all the parts made so far.

淤浪 2024-12-30 05:21:58

感谢这里几个人的帮助,我终于想出了这段代码,它完全可以与运动配合使用:

<html>
<head><script>
var r1 =  400;
var r2 =  340;
var r3 = 220;
var slitWidth = 40;
var speed = 0.0004;
var attenuation = 1.7;

function rgbToHex(r, g, b){
    return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

window.nextFrame = (function(callback){
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){window.setTimeout(callback, 1000 / 60);};
})();

window.onload = function(){
    var waiting=document.getElementById('waiting').getContext('2d');
    function slit(d,p){
        shade = Math.round(Math.pow(1-(d+p)%1, attenuation)*255)
        th = Math.PI*2*(p);
        cos = Math.cos(th);
        sin = Math.sin(th);
        waiting.strokeStyle = rgbToHex(shade, shade, shade);
        waiting.beginPath();
        waiting.moveTo(r2*cos, r2*sin);
        waiting.lineTo(r3*cos, r3*sin);
        waiting.stroke();
        waiting.closePath();
    }
    function frame(){
        waiting.arc(0,0,r1,0,Math.PI*2);
        waiting.fill();
        var time = new Date().getTime()* speed;
        for(var p = 1;p>0;p-=0.05){slit(time,p);}
        nextFrame(function(){frame();});
    }
    waiting.lineCap='round';
    waiting.lineWidth=slitWidth;
    waiting.fillStyle='#353535';
    waiting.translate(r1, r1);
    frame();
}
</script></head>
<body><canvas id='waiting' width=800 height=800></canvas></body>
</html>

Thanks to the help by the several people here, I finally came up with this code, which works fully with the movement:

<html>
<head><script>
var r1 =  400;
var r2 =  340;
var r3 = 220;
var slitWidth = 40;
var speed = 0.0004;
var attenuation = 1.7;

function rgbToHex(r, g, b){
    return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}

window.nextFrame = (function(callback){
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){window.setTimeout(callback, 1000 / 60);};
})();

window.onload = function(){
    var waiting=document.getElementById('waiting').getContext('2d');
    function slit(d,p){
        shade = Math.round(Math.pow(1-(d+p)%1, attenuation)*255)
        th = Math.PI*2*(p);
        cos = Math.cos(th);
        sin = Math.sin(th);
        waiting.strokeStyle = rgbToHex(shade, shade, shade);
        waiting.beginPath();
        waiting.moveTo(r2*cos, r2*sin);
        waiting.lineTo(r3*cos, r3*sin);
        waiting.stroke();
        waiting.closePath();
    }
    function frame(){
        waiting.arc(0,0,r1,0,Math.PI*2);
        waiting.fill();
        var time = new Date().getTime()* speed;
        for(var p = 1;p>0;p-=0.05){slit(time,p);}
        nextFrame(function(){frame();});
    }
    waiting.lineCap='round';
    waiting.lineWidth=slitWidth;
    waiting.fillStyle='#353535';
    waiting.translate(r1, r1);
    frame();
}
</script></head>
<body><canvas id='waiting' width=800 height=800></canvas></body>
</html>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文