一点背景: 我在Flash Pro / Adobe Animate中创建了一个带有时间轴动画的详细MovieClip,并导出到CreateJS / EaselJS库。当我在运行时实例化它时,它需要比一帧更长的时间或“#”;完成此实例化,动画播放在前进到下一帧之前等待。这导致播放动画中的打嗝。这是一个在我的项目中出现的问题。如何在不简化MovieClip中的框架艺术的情况下克服这种打嗝?
代码:如果不清楚,这就是我所说的......
var instanceMC = new lib.bigMovieClip_mc(); // <-- LONG DELAY, OVER 1 TICK IN TIME
stage.addChild(instanceMC); // <-- from here on it seems to run smoothly
instanceMC.x = xPosition;
instanceMC.y = yPosition;
stage.update();
我的想法:
帮助:您可以建议哪种方法(无论是否列出)可以解决我的问题?
答案 0 :(得分:0)
首先,我希望有人能提供比这更好的答案,我很乐意改变所选择的答案。
我在某种程度上研究了各种选项,并了解到这实际上是一个非常根深蒂固的问题。它与浏览器的单线程特性有关,UI更新使用相同的线程,必须等待轮到他们。请参阅:here,here,here和here。
从头开始设计库(如CreateJS)以尽可能地清除调用堆栈并利用回调队列可以避免在自己的操作期间锁定UI(如实例化MovieClip)。 (实际上,每帧都会暂停复杂操作的代码。)这是处理这种野兽的最佳方法。据我所知,MovieClip的实例化在CreateJS中没有这样的支持,虽然在运行时构建spritesheets有一个'async'选项,当然,LoadJS也是异步运行的(但是不支持执行代码到目前为止)正如我所知道的那样)。据推测,我非常大的MovieClip将被认为超出了创作者预期用途的范围。
我的解决方案是在运行我的应用程序之前预加载所有动画片段并显示预加载器。这不是一个理想的解决方案,因为它有很长的等待时间,但它比我的需求更好(即减少劳动力)。一个更好的方法可能是将我有问题的MovieClip分解为不会独立引起问题的较小的MovieClip,然后像这样实例化它们:
setTimeout( function(){ firstMovieClip = new lib.firstMovieClip(); },0);
setTimeout( function(){ secondMovieClip = new lib.secondMovieClip(); },0);
and so on....
这导致它们不能直接进入堆栈,而是进入回调队列。这反过来允许UI在这些较小的实例之间进行更新,因为堆栈清除了。
对于它的价值,还有一些选项可以在浏览器中使用Web worker运行其他线程。它不适用于我的目的,因为这些Web工作者中的对象无法移动到UI。对于具有简单结果的复杂计算(如数字),这将是一个很好的解决方案。