我想出的唯一解决方案是一个非常可怕的黑客攻击。看起来 Swiffy 真的不喜欢在动画被破坏后重新创建它们。我已经成功地将 Swiffy 从 DOM 中分离出来,但在内存中保留了它的引用。然后我不得不破解运行时以启用暂停和重新启动。然后我可以重新连接原来的 Swiffy 而不必破坏它。这是在从https://www.gstatic.com/swiffy/v5.2/runtime.js下载的 v5.2.0 中,在将运行时通过 jsbeautifier.org 之后
在函数之后的第 5640 行附近,M.releaseCapture
我添加了以下函数:
M.hackPause = function (bool) {
if(this.hackPaused === bool) return;
if(this.hackPaused) {
bi(ef(this.qh.yl, this.qh));
}
this.hackPaused = bool;
};
在第 7137 行周围,将AK[I].yl
函数替换为以下内容:
Ak[I].yl = function () {
if (this.bh) {
var a = Date.now();
a >= this.Mf && (this.tl.ei(), this.Mf += (s[Xb]((a - this.Mf) / this.sl) + 1) * this.sl);
this.tl.lc();
if(!this.tl.hackPaused) {
bi(ef(this.yl, this))
}
}
};
这样做是为了阻止 requestAnimationFrame 或 setTimeout 触发,从而有效地暂停动画。
我也尝试在运行时中公开 gotoAndStop 函数,但我无法在代码中找到范围。与此同时,使用这篇文章中的一个技巧 -是否可以从 JS 暂停/恢复/操作一个 swiffyobject?我们可以通过将进入帧事件添加到 Flash 电影并测试 Flashvars 的变化来使用蛮力方法来做到这一点。下面是我们一直用于动画的文档类。值得注意的是,Swiffy 似乎不喜欢从同一个基类扩展的 AS3 类,它会引发相同的无法重新定义属性错误,因此我们在每个 Flash 动画的 Document 类中复制了此处的代码。我'
package {
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.events.Event;
import flash.utils.setTimeout;
public class BaseAnimation extends MovieClip {
private var _request:URLRequest;
private var _pageName:String;
private var _movieName:String;
public function BaseAnimation() {
_request = new URLRequest();
_pageName = getFlashVar('pageName');
_movieName = getFlashVar('movieName');
addEventListener(Event.ENTER_FRAME, jsListen);
}
private function getFlashVar(name:String):String {
var flashVar:String = stage.loaderInfo.parameters[name] || '';
stage.loaderInfo.parameters[name] = '';
return flashVar;
}
public function dispatchJSEvent(eventName:String, param:String = ''):void {
_request.url = "javascript:onSwiffyEvent('" + eventName + "', '" + param + "', '" + _movieName + "', '" + _pageName + "');";
navigateToURL(_request, "_self");
}
private function jsListen(e:Event):void {
var mode:String = getFlashVar('mode');
if(mode.length) {
switch(mode) {
case 'stop':
stop();
break;
case 'play':
play();
break;
case 'gotoStart':
gotoAndStop('start');
break;
}
}
}
}
}
Swiffy 似乎也不喜欢 gotoAndStop(0) 所以我不得不在动画的第一帧上设置一个帧标签“开始”。
有了所有这些可怕的骇客,我们就可以删除并重新启动 Swiffy 动画。我们发现的唯一问题是分离和重新附加导致嵌入的 SVG 字体出现问题,我们最终将所有文本转换为轮廓。上面是这样使用的:
您可以像这样在 swiffy 舞台上调用它:
var stage = new swiffy.Stage(domObject, swiffyObj);
stage.start();
// when reading to remove this element from the DOM do the following:
stage.setFlashVars('mode=gotoStart');
setTimeout(function () {
// timeout is required to ensure that the enterframe listener has time to run
stage.hackPause(true); // paused animation
}, 100);
// you can then remove the containing div from the DOM, but retain it in memory
// after you reattach the div to the DOM, ensuring we've kept hold of our stage variable in memory, you can restart it like this:
stage.hackPause(false); // resumes javascript requestAnimationFrame
stage.setFlashVars('mode=play'); // resumes flash animation
希望这对某人有所帮助,但我也真的希望 Google 开始向 Swiffy 运行时公开某种 JS API 或 ExternalInterface,以便让我们更好地控制真正非常棒的工具。