サイトトップ

Director Flash 書籍 業務内容 プロフィール

Animateテクニカルノート

HTML5 Canvasで書き出したCanvasの大きさが倍になる


Animate CC 2017で[HTML5 Canvas]ドキュメントをパブリッシュして、変数canvasやStage.canvasプロパティで調べた幅(width)や高さ(height)がドキュメントに定めたステージの倍(あるいは3倍)になることがあります。

01 Retinaに対応して<canvas>要素の大きさが変わる

Animate CCで[HTML5 Canvas]ドキュメントをパブリッシュすると、<canvas>要素はグローバル変数canvasに納められます。また、Stage.canvasプロパティが、要素の参照です。たとえば、インスタンスをステージの中央に置こうとして、<canvas>要素の幅と高さそれぞれの1/2の位置に定めると、右下角にいってしまうことがあります(図001)。


var _canvas = stage.canvas;
instance.x = _canvas.width / 2;
instance.y = _canvas.height / 2;

図001■インスタンスが中央でなく右下角に置かれた

図001

Animate CC 2015.2から、[HTML5 Canvas]ドキュメントのパブリッシュにレスポンシブウェブデザインが採り入れられました(「Flash Professionalから名称を変えて一年。Animate CCはこんなに進化した」の「HTML5 Canvasの書き出し方法の充実」参照)。<canvas>要素はHiDPI/Retinaディスプレイに応じた大きさに変えられ、スタイルシートで補正されるのです(図002)。

図002■<canvas>要素の幅と高さが変わってstyleで補正されている

図002

パブリッシュされたHTMLドキュメントには、つぎのような<canvas>要素の大きさを変える関数(resizeCanvas())が定められています。


resizeCanvas();		
function resizeCanvas() {			

	canvas.width = w*pRatio*sRatio;			
	canvas.height = h*pRatio*sRatio;
	canvas.style.width = dom_overlay_container.style.width = anim_container.style.width =  w*sRatio+'px';				
	canvas.style.height = anim_container.style.height = dom_overlay_container.style.height = h*sRatio+'px';
	stage.scaleX = pRatio*sRatio;			
	stage.scaleY = pRatio*sRatio;			

}

02 Stageオブジェクトの伸縮のプロパティから座標を補正する

Stage(Container)クラスに幅や高さのプロパティはありません。内部的には、伸縮のプロパティDisplayObject.scaleXDisplayObject.scaleYで大きさを変えているようです(前掲コードのresizeCanvas()関数参照)。したがって、このプロパティ値からステージ上の座標を求めればよいでしょう(図003)。


var _canvas = stage.canvas;
instance.x = _canvas.width / 2 / stage.scaleX;
instance.y = _canvas.height / 2 / stage.scaleY;

図003■Stageオブジェクトの伸縮のプロパティで座標を補正する

図003

03 <canvas>要素に定められたstyleの大きさを調べる

前項のStageクラスのプロパティで<canvas>要素の大きさを求めるのは、コードとしては簡単です。けれど、伸縮された大きさを調べて、伸縮のプロパティでもとに戻すというのは、まだるっこしい感じがしないではありません。そこでご参考までに、<canvas>要素に与えられたstyle属性から幅と高さを返す関数(getStageSize())として定めてみました。


window.addEventListener('DOMContentLoaded', function(eventObject) {
	this.getStageSize = function() {
		var stageSize = {width: null, height: null}
		var _canvas = document.getElementById('canvas');
		if (_canvas) {
			stageSize.width = _canvas.width;
			stageSize.height = _canvas.height;
			var _style = _canvas.style;
			if (_style.width) {
				stageSize.width = parseFloat(_style.width);
				stageSize.height = parseFloat(_style.height);
			}
		}
		return stageSize;
	}
});

Animate CC 2017.1から備わったグローバルスクリプトに書くと、どこからでも関数が呼び出せて便利です(図004)。なお、グローバルスクリプトについては「Adobe Animate CC 2017.1のグローバルスクリプトとサードパーティスクリプト」をお読みください。


var stageSize = getStageSize();
instance.x = stageSize.width / 2;
instance.y = stageSize.height / 2;

図004■[アクション]パネルの[グローバル]階層で[スクリプト]に定める

図004

作成者: 野中文雄
作成日: 2017年2月15日


Copyright © 2001-2017 Fumio Nonaka.  All rights reserved.