【问题标题】:Choppy canvas animation - EaselJS断断续续的画布动画 - EaselJS
【发布时间】:2016-12-24 00:04:17
【问题描述】:

我正在尝试使用 EaselJS 模拟在 spire's 横幅中看到的画布元素。但是我的动画在 chrome 和 firefox 上都很不稳定。任何帮助表示赞赏。 (第一次使用 EaselJS)

我的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>EaselJS</title>
    <style>
        body{
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        #spire-canvas{
            background: #333;
        }
    </style>
</head>
<body>

    <canvas id="spire-canvas" width="1366" height="768"></canvas>

    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/EaselJS/0.8.0/easeljs.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
    <script>
        $(document).ready(function(){


            //INITIALIZATIONS
            var stage,
            particles = 10, 
            fps = 30, 
            viewportWidth = window.innerWidth, 
            viewportHeight = window.innerHeight,
            circles = [];

            function init(){
                stage = new createjs.Stage("spire-canvas");
                createjs.Ticker.addEventListener("tick", refresh);
                createjs.Ticker.setFPS(fps);
                console.log("init fired");
            }

            function refresh(){
                for(var i = 0; i < particles; i++){
                    var circle = new createjs.Shape();
                    circle.graphics.beginFill('#' + Math.floor(Math.random() * 16777215).toString(16))
                    .drawCircle(0, 0, (Math.random() * 10));
                    circle.x = circle.x + Math.random() * viewportWidth;
                    circle.y = (Math.random() * viewportHeight) + viewportHeight;
                    circle.alpha = 0.1 + Math.random() * 0.2;
                    stage.addChild(circle);
                    circles.push(circle);
                };
                for(var i = 0; i < circles.length; i++){
                    var item = circles[i];
                    var yy = item.y + Math.floor(Math.random() * (viewportHeight - 300)) * -1;

                    if(item.y < 300){
                        TweenLite.to(item, 1, {alpha: '0', ease: Power4.easeOut, onComplete: function(){
                            stage.removeChild(item);
                        }});
                    }

                    TweenLite.to(item, 10, {y: yy});
                };
                stage.update();
            }

            init();
        });
    </script>
</body>
</html>

【问题讨论】:

    标签: javascript html5-canvas createjs easeljs gsap


    【解决方案1】:

    您的演示存在许多问题,这些问题都会导致性能问题。主要是因为你没有正确使用补间,也没有清理项目。

    1. 主要的性能问题是您为每个圆圈每个刻度创建一个新的补间。在您的第二个循环中,对于每个圈子,您都调用TweenLite.to(item, 10, {y: yy});。这将为每个圆创建(最好的情况下覆盖)该对象的补间。以您制作圆圈的粗略速度,在任何给定时间都会有> 1000个圆圈。这里最好的方法是在你制作每个圆圈的循环内移动你的整体移动补间,这样每个圆圈都会发生一次。

    2. 补间的第二个问题是您检查圆是否小于 300 像素,如果是,则将其补间 (alpha)。然而,由于圆圈在消失时仍在移动,这意味着您为每个圆圈创建一个新的 alpha 补间。您应该为每个圈子执行一次一次。您可以通过在它正在淡出的元素上设置一个标志来做到这一点,因此它不会发生多次。

    3. 您永远不会从circles 数组中删除圈子。这意味着您的阵列每滴答声增长 10 圈〜所以每秒大约 300 圈。 10 秒后,你有 3000 个圆圈,等等。使用形状,你将很快达到性能最大值,即使在解决了我上面概述的补间问题之后也是如此。从舞台上移除时,也从阵列中移除。

    4. 图形很慢。如果您想要一些超高性能的东西,请使用图像或缓存的形状。您的演示对每个精灵都有随机颜色,但 Spire 演示没有。如果你想要一些变化,你可以预先缓存一堆颜色,并从图像对象池中绘制,最好是在 SpriteSheet 中。

    总体而言,Tweens 的开销是最大的问题。您可能可以在不使用补间的情况下对其进行重构以获得更好的性能,因为动画非常可预测。

    干杯,

    【讨论】:

    • 这里是您的代码的快速示例,补间移动到了正确的位置:jsfiddle.net/lannymcnie/abLhozah -- 我修改了阈值,使一些项目淡出,但没有一个项目成功根据它们的初始值向上足够高以进行补间(它们只是停止)。您应该能够从该示例中获得所需的内容。
    • 我知道问题出在记号内的 for 循环上。需要彻底参考文档。无论如何感谢一堆兰尼。很大的帮助。将其标记为答案。
    猜你喜欢
    • 2011-05-25
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2010-09-23
    • 2011-02-15
    相关资源
    最近更新 更多