带缓动的动画画布弧线

发布于 2024-12-05 08:55:31 字数 1267 浏览 1 评论 0原文

我正在画布上画一个非传统的环形时钟。时间由秒环、秒针、分钟环和小时环表示。我正在使用 webkit/mozRequestAnimationFrame 在适当的时间进行绘制。我想修改第二个环以快速动画到下一秒(125ms - 250ms)并使用二次缓动(而不是那个可怕的捕捉)。

与 Raphael JS Clock 的第二个响铃动画非常相似,只不过它使用不同的缓动: http://raphaeljs.com/ Polar-clock.html

JS Fiddle 链接(必须在 Chrome、Firefox 或 Webkit Nightly 中查看):

  1. Fiddle:http://jsfiddle.net/thecrypticace/qmwJx/

  2. 全屏小提琴: http://jsfiddle.net/thecrypticace/qmwJx/embedded/result/

任何帮助将非常感激!

这已经很接近了,但仍然很不稳定:

var startValue;
if (milliseconds < 500) {
    if (!startValue) startValue = milliseconds;
    if (milliseconds - startValue <= 125) {
        animatedSeconds = seconds - 0.5 + Math.easeIn(milliseconds - startValue, startValue, 1000 - startValue, 125)/1000;
    } else {
        animatedSeconds = seconds;
    }
    drawRing(384, 384, 384, 20, animatedSeconds / 60, 3 / 2 * Math.PI, false);
} else {
    drawRing(384, 384, 384, 20, seconds / 60, 3 / 2 * Math.PI, false);        
    startValue = 0;
}

I'm drawing a non-traditional ring-clock in canvas. The time is represented by a second ring, second hand, minute ring, and hour ring. I am using webkit/mozRequestAnimationFrame to draw at the appropriate time. I would like to modify the second ring to animate to the next second quickly (125ms - 250ms) and with Quadratic easing (instead of that dreaded snap).

Much like the Raphael JS Clock animates its second ring, except it uses different easing: http://raphaeljs.com/polar-clock.html

JS Fiddle Links (must view in Chrome, Firefox, or Webkit Nightly):

  1. Fiddle: http://jsfiddle.net/thecrypticace/qmwJx/

  2. Full screen Fiddle:
    http://jsfiddle.net/thecrypticace/qmwJx/embedded/result/

Any help would be very much appreciated!

This comes close but is still really jerky:

var startValue;
if (milliseconds < 500) {
    if (!startValue) startValue = milliseconds;
    if (milliseconds - startValue <= 125) {
        animatedSeconds = seconds - 0.5 + Math.easeIn(milliseconds - startValue, startValue, 1000 - startValue, 125)/1000;
    } else {
        animatedSeconds = seconds;
    }
    drawRing(384, 384, 384, 20, animatedSeconds / 60, 3 / 2 * Math.PI, false);
} else {
    drawRing(384, 384, 384, 20, seconds / 60, 3 / 2 * Math.PI, false);        
    startValue = 0;
}

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

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

发布评论

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

评论(1

何以畏孤独 2024-12-12 08:55:31

这是一个数学问题:

drawRing(384, 384, 384, 20, seconds / 60, 3 / 2 * Math.PI, false);

这是绘制秒圈的线。所以问题是在任何给定时刻你都会有类似 34/60、35/60 等的情况。这意味着您的秒圈是 60/60,因此不使用毫秒,而是每秒绘制一次。

线性缓动解决方案:使秒圈为 60 000 / 60 000 ->每个 60 秒 x 1000 毫秒。数学:

drawRing(384, 384, 384, 20, ((seconds*1000)+milliseconds) / 60000, 3 / 2 * Math.PI, false);

In Out Quadric 解决方案或选择一个 这些

Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
};

我优化并更改了您的代码:

//+1 animation happens before the second hand
//-1 animation happens after the second hand
animatedSeconds = seconds+1;
if (milliseconds > 10) {
    if (!startValue) { startValue = milliseconds; }
    if (milliseconds - startValue <= 100) {
        animatedSeconds -= -0.5+ Math.easeInOutQuad(milliseconds - startValue, startValue, 1000 - startValue, 125) / 1000;
    }
} else {
    startValue = 0;
}
drawRing(384, 384, 384, 20, animatedSeconds / 60, 3 / 2 * Math.PI, false);

希望这就是您正在寻找的。

It is a mater of math:

drawRing(384, 384, 384, 20, seconds / 60, 3 / 2 * Math.PI, false);

This is the line which is drawing the seconds circle. So the problem is that in any given moment you have something like 34/60, 35/60 and so on. This means your seconds circle is 60/60 thus not using the milliseconds, and drawing it each second.

The linear easing solution: make your seconds circle 60 000 / 60 000 -> 60 seconds by 1000 millisecond each. And the math:

drawRing(384, 384, 384, 20, ((seconds*1000)+milliseconds) / 60000, 3 / 2 * Math.PI, false);

The In Out Quadric solution or choose one these :

Math.easeInOutQuad = function (t, b, c, d) {
    t /= d/2;
    if (t < 1) return c/2*t*t + b;
    t--;
    return -c/2 * (t*(t-2) - 1) + b;
};

And I optimized and changed your code:

//+1 animation happens before the second hand
//-1 animation happens after the second hand
animatedSeconds = seconds+1;
if (milliseconds > 10) {
    if (!startValue) { startValue = milliseconds; }
    if (milliseconds - startValue <= 100) {
        animatedSeconds -= -0.5+ Math.easeInOutQuad(milliseconds - startValue, startValue, 1000 - startValue, 125) / 1000;
    }
} else {
    startValue = 0;
}
drawRing(384, 384, 384, 20, animatedSeconds / 60, 3 / 2 * Math.PI, false);

Hopefully this is what you are looking for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文