【问题标题】:(canvas) Push a new item every couple seconds(画布)每隔几秒钟推送一个新项目
【发布时间】:2014-01-08 20:49:36
【问题描述】:

您好,提前感谢您的帮助。

我正在尝试每隔几秒钟推送/创建一个新的“环”。我有一个带有 X 和 Y 几个变量的环。我遇到的问题是,如何获得一个新环并增加变量?每个环都需要一个新的变量名吗? 到目前为止,我已经走了多远:

http://codepen.io/hossman/pen/AfwkF

您可以在演示中看到 1 个环是如何熄灭的,但我希望超过 1 个环从我的眼睛中消失。因此,例如 1 个环发出,然后等待一秒钟,然后射出另一个环,所以现在画布上有 2 个环,然后是 3 个,然后是 4 个,等等....我想到了多种方法,例如使用数组和setTimeouts,但我不能指望它。我唯一的另一个想法是创建多个具有不同名称的变量并使每个环递增,但这不是很 D.R.Y.

有什么帮助吗?

如果我解释得不够好,请提出问题。再次感谢!

【问题讨论】:

  • 我可以试试吗? jsfiddle.net/m1erickson/QQ57C
  • @markE 哈哈哇!太棒了!!!喜欢 StackOverflow。这么多有才华的人愿意提供帮助。

标签: javascript html animation canvas


【解决方案1】:

将此添加到顶部的全局变量中(并设置为您希望圆圈之间的距离):

var distanceApart = 40;

然后像这样更新你的主循环:

requestAnimationFrame(function print() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    var leftRing = new Ring(x, y);
    var rightRing = new Ring(x2, y2);
    var temp = startRadius;
    var temp2 = 0;

    while(temp > 0){
         leftRing.draw(ctx, startRadius - temp2 , 'red');
         rightRing.draw(ctx, startRadius - temp2 , 'red');   
         temp2 = temp2 + distanceApart;
         temp = temp - distanceApart;
    }

    startRadius += increase;

    requestAnimationFrame(print);
});

在此处分叉:http://codepen.io/anon/pen/plBmj (看起来很有记忆力!)

【讨论】:

  • 如果 FORK 没有立即启动,请点击刷新。有时使用 codepen 在我的浏览器上出现奇怪的故障。并等待圆圈变得足够大,您就会开始看到下一个开始了。
  • 天哪!谢谢你,先生!你太不可思议了。我非常感谢你所做的一切。你帮了我很多。再次感谢!! :-)
  • 我知道我已经谢谢你了,但是真的谢谢你。我喜欢你写它的方式。我要记住这一点。不知道为什么我没有想到 while 循环。感谢您增加我的知识。
【解决方案2】:

我会重写您的部分代码以启用此功能。例如我会重写你的Ring类如下:

var Ring = defclass({
    constructor: function (x, y, r) {
        this.x = x;
        this.y = y;
        this.r = r;
    },
    draw: function (context) {
        context.beginPath();
        context.arc(this.x, this.y, this.r, 0, Math.PI * 2);
        context.stroke();
        return this;
    },
    addRadius: function (r) {
        return new Ring(this.x, this.y, this.r + r);
    }
});

您的Ring 类构造函数现在采用xy 和半径raddRadius 函数返回一个新的Ring,而不是改变原来的。这很好,因为不变性使您的代码更易于使用。哦,defclass 被声明为:

function defclass(prototype) {
    var constructor = prototype.constructor;
    constructor.prototype = prototype;
    return constructor;
}

然后我们为您的眼睛创建两个环:

var radius = 10;
var delta = 0.1;

var left = new Ring(cx - (cx / 3.6), cy - 5, radius);
var right = new Ring(cx + (cx / 3.6), cy - 10, radius);

之后我们调用动画循环:

var interval = 50 / 3;
var start = Date.now();
loop(start, [left, right]);

由于我们希望以 60 FPS 的速度播放,因此间隔为 1000 / 60,可以简化为 50 / 3。动画循环定义如下:

function loop(last, rings) {
    var next = last + interval;

    context.clearRect(0, 0, width, height);

    var newRings = rings.map(function (ring) {
        return ring.draw(context).addRadius(delta);
    });

    var now = Date.now();

    setTimeout(loop, next - now, next,
        Math.floor((now - start) / 1000) === rings.length / 2 ?
            [left, right].concat(newRings) : newRings);
}

这是发生了什么:

  1. 首先我们清除屏幕。
  2. 然后我们绘制所有环并增加它们的大小。
  3. 如果一秒钟过去了,我们会向数组中添加两个新环。
  4. 最后,我们计算何时再次调用loop,以便在正确的interval 之后触发。

查看演示:http://jsfiddle.net/LAr76/

【讨论】:

  • 哦,伙计。棒极了!! UGG!对不起,我把答案给了另一个人,但你的答案很好!我真的很感激你花时间解释和写出来。啊,伙计。抱歉,您没有得到答复。但非常感谢您的回答。我将检查你们两个人的代码。再次抱歉,您没有得到 answer,但效果很好。我+1。多谢你们!! :-)
  • 你做了一些很棒的事情。我不是很了解它,但就像我在检查它之前所说的那样。我对三元之类的东西了解不多,但是看到它在行动中很酷。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2018-09-24
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多