1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

animateCCで作ったcanvasを一つのページに複数表示する

Last updated at Posted at 2020-01-29

##したいこと
animateCCではcanvasをhtmlとjsファイルで書き出すことができますが、一つのページに一つのcanvasしか置けないように書き出されています。
ですが、一つのページに複数表示する必要ができたので試行錯誤してみました。
#原因
htmlに書き出されたスクリプトを見てみます。

sample.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側でもグローバル変数を使っているみたいなのでそれも修正しました。

sample.html
<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>
sample.html
<body onload="canvas1.init();">

html側の修正はこれでOK。
あとはインスタンスを作成するだけでいくらでもcanvasを追加できます。

sample.js
(lib.root = function (mode, startPosition, loop) {
		this.initialize(mode, startPosition, loop, {});

jsの真ん中くらいにanimateファイル名と同じ名前(この場合はlib.sample)の関数が追加されてるので、これをlib.rootに統一します。

sample.js
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設置できるようになってくれればいいのに...

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?