2016-08-17 71 views
0

我试图模仿使用EaselJS在spire's横幅中看到的画布元素。但是我的动画在chrome和firefox上都不稳定。任何帮助表示赞赏。 (首次使用EaselJS)Ch canvas画布动画 - 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> 

回答

2

有许多与您的演示,这一切都将导致性能问题的问题。最重要的是你没有正确地使用补间,而不是清理物品。

  1. 主要性能问题是,你正在创建一个新补的每个圆圈每滴答。在你的第二个循环中,对于每个圆圈,你打电话给TweenLite.to(item, 10, {y: yy});。这将为每个圆圈创建(并且最好的情况下覆盖)该对象的补间。按照您制作圈子的粗略比率,任何时候都会有> 1000个圈子。这里最好的方法是将你的整个移动补丁移动到你创建每个圆圈的循环内部,所以它每圈发生一次。

  2. 补间的第二个问题是您检查圆圈是否小于300像素,如果是,则将其补间(alpha)。但是,由于圆圈在渐变时仍在移动,这意味着每个圆圈都会为每个圆圈创建一个新的阿尔法补间。你应该这样做一次为每个圆。你可以通过在它正在淡出的元素上设置一个标志来做到这一点,所以它不会发生一次以上。

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

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

总之,吐温的开销是最大的问题。你可以重构这个来获得更好的性能,而不使用补间,因为动画是相当可预测的。

干杯,

+1

下面是一个简单示例与您的代码,并充斥着移动到合适的位置:http://jsfiddle.net/lannymcnie/abLhozah/ - 我修改了门槛,使一些项目淡出,但没有一个基于它们的初始值被补偿(它们只是停止)而足够高。你应该能够从样本中得到你需要的。 – Lanny

+0

我知道问题出在tick中的for循环。需要彻底查阅文件。无论如何感谢一群兰尼。很好的帮助。标记为答案。 –