##したいこと
animateCCではcanvasをhtmlとjsファイルで書き出すことができますが、一つのページに一つのcanvasしか置けないように書き出されています。
ですが、一つのページに複数表示する必要ができたので試行錯誤してみました。
#原因
htmlに書き出されたスクリプトを見てみます。
<script>
var canvas, stage, exportRoot, anim_container, dom_overlay_container, fnStartAnimation;
function init() {
canvas = document.getElementById("canvas");
anim_container = document.getElementById("animation_container");
dom_overlay_container = document.getElementById("dom_overlay_container");
var comp=AdobeAn.getComposition("7FA144C866007148B35B38661139E543");
var lib=comp.getLibrary();
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", function(evt){handleFileLoad(evt,comp)});
loader.addEventListener("complete", function(evt){handleComplete(evt,comp)});
var lib=comp.getLibrary();
loader.loadManifest(lib.properties.manifest);
}
これは書き出されたhtmlの一部ですが、init()を実行することでcanvasに作ったanimationが表示されるようです。
init()で使われる変数はグローバルで宣言されていて、これをほかの関数でも使っているようです。
グローバルで宣言された変数がかぶってしまうことが一つのページに一つのcanvasしか置けない原因みたいです。
##解決策
かぶっているグローバル変数を別の変数名にしてあげたら解決しそうです。
でも、いちいち関数名を変更するのは大変なのでclassを作ってそれをインスタンス化することにしましたが、書き出されたjs側でもグローバル変数を使っているみたいなのでそれも修正しました。
<script>
class animate_canvas {
constructor(canvasName, animName, conName, id, an, obj) {
this.canvasName = canvasName;
this.animName = animName;
this.conName = conName;
this.id = id;
this.AdobeAn = an;
}
init() {
this.canvas = document.getElementById(this.canvasName);
this.anim_container = document.getElementById(this.animName);
this.dom_overlay_container = document.getElementById(this.conName);
var comp = this.AdobeAn.getComposition(this.id);
var lib = comp.getLibrary();
var loader = new createjs.LoadQueue(false);
loader.eventParam = this;
loader.addEventListener("fileload", function (evt) {
loader.eventParam.handleFileLoad(evt, comp)
});
loader.addEventListener("complete", function (evt) {
loader.eventParam.handleComplete(evt, comp)
});
var lib = comp.getLibrary();
loader.loadManifest(lib.properties.manifest);
}
handleFileLoad(evt, comp) {
var images = comp.getImages();
if (evt && (evt.item.type == "image")) {
images[evt.item.id] = evt.result;
}
}
handleComplete(evt, comp) {
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage.
var lib = comp.getLibrary();
var ss = comp.getSpriteSheet();
var queue = evt.target;
var ssMetadata = lib.ssMetadata;
for (var i = 0; i < ssMetadata.length; i++) {
ss[ssMetadata[i].name] = new createjs.SpriteSheet({
"images": [queue.getResult(ssMetadata[i].name)],
"frames": ssMetadata[i].frames
})
}
this.exportRoot = new lib.root();
this.stage = new lib.Stage(this.canvas);
//Registers the "tick" event listener.
this.fnStartAnimation = function () {
this.stage.addChild(this.exportRoot);
createjs.Ticker.framerate = lib.properties.fps;
createjs.Ticker.addEventListener("tick", this.stage);
}
//Code to support hidpi screens and responsive scaling.
this.AdobeAn.makeResponsive(false, 'both', false, 1, [this.canvas, this.anim_container, this
.dom_overlay_container
]);
this.AdobeAn.compositionLoaded(lib.properties.id);
this.fnStartAnimation();
}
}
var canvas1 = new animate_canvas("canvas1", "animation_container1", "dom_overlay_container1", "A913565CFDED704984ECDA79F58F4E5B",
AdobeAn1);
</script>
<body onload="canvas1.init();">
html側の修正はこれでOK。
あとはインスタンスを作成するだけでいくらでもcanvasを追加できます。
(lib.root = function (mode, startPosition, loop) {
this.initialize(mode, startPosition, loop, {});
jsの真ん中くらいにanimateファイル名と同じ名前(この場合はlib.sample)の関数が追加されてるので、これをlib.rootに統一します。
stage.scaleX = pRatio * sRatio;
canvas1.stage.scaleY = pRatio * sRatio;
lastW = iw;
lastH = ih;
lastS = sRatio;
canvas1.stage.tickOnUpdate = false;
canvas1.stage.update();
canvas1.stage.tickOnUpdate = true;
}
}
})(createjs = createjs || {}, AdobeAn1 = AdobeAn1 || {});
var createjs, AdobeAn1;
stageとAdobeAnがjsで使われていたのでこれも修正します。
AdobeAnが何なのかよくわからなかったのですが、とりあえず動けばいい。
createjsもグローバル変数ですが変数名を変えなくても動きました(なぜかわかりません)。
これで一つのページに複数表示することができます。
##まとめ
私はclassを使ってインスタンス化しましたが、とにかくグローバル変数がかぶらなければ動くみたいです。
animateが複数canvas設置できるようになってくれればいいのに...