EaselJS 0.7.1: サンプル「Smooth Line」 [Edit]

Sebastian DeRossi氏がEaselJS 0.7.1を使って「Smooth Line」というサンプルコードを公開されました。マウスポインタの動きにしたがって、滑らかな曲線が描かれては消えていきます。この振る舞いを少し変えるとともに、これまでFumioNonaka.comやgihyo.jpの連載でご紹介した小技をコードに採入れてみました(サンプル001)。

サンプル001■EaselJS 0.7.1: Smooth Line

01 ドラッグの軌跡を滑らかな曲線で描く

Sebastian DeRossi氏のコードは、GitHubに公開されています。このコードにもとづいて、前掲サンプル001ではドラッグの軌跡にしたがった滑らかな曲線を、つぎのような関数(drawCurve())で描きました。引数には描画するGraphicsオブジェクト(myGraphics)とともに、曲線の始点(oldPoint)と終点(newPoint)、およびコントロールポイント(controlPoint)の座標をPointオブジェクトで渡します。

function draw() {

	var midPoint = new createjs.Point((lastPoint.x + currentPoint.x) / 2,  (lastPoint.y + currentPoint.y) / 2);
	drawCurve(myShape.graphics, lastMidPoint, midPoint, lastPoint);

}

function drawCurve(myGraphics, oldPoint, newPoint, controlPoint) {
	myGraphics.beginStroke("black")
	.setStrokeStyle(getLineThickness(oldPoint, newPoint), "round", "round")
	.moveTo(oldPoint.x, oldPoint.y)
	.quadraticCurveTo(controlPoint.x, controlPoint.y, newPoint.x, newPoint.y);   
}

このお題はgihyo.jp連載「HTML5のCanvasでつくるダイナミックな表現―CreateJSを使う」第10回「ドラッグの軌跡を滑らかな曲線で描く」で扱いました。「2次ベジエ曲線で滑らかな軌跡を描く」の項で各座標の定め方が解説されています。連続した座標はすべてコントロールポイントにして、座標の中点をアンカーポイントとして結ぶのです(図001)。gihyo.jp連載第10回の解説には、jsdo.itのシミュレーションサンプルも掲げてあります。

図001■軌跡の座標に対する滑らかな曲線の描き方
図001

02 つくったオブジェクトを使い回す

このサンプルでは、予め決めた数までの多くのインスタンスに、つぎつぎと線を書き加えてステージに置きます。そして、古いオブジェクトから順に表示リストから除くことで、線の消えるアニメーションを表現しています。

このような場合、新たなインスタンスを毎回つくるより、すでにあるオブジェクトはそのまま使った方がお得です。そこで、前掲サンプル001は、gihyo.jp連載第14回「オブジェクトの使い回しとアニメーション素材の変更」にならって、「つくったオブジェクトを使い回す」ことにしました。使い回しの関数は、つぎのふたつです。

function getNewChild() {
	var child;
	if (children.length) {
		child = children.pop();
		child.graphics.clear();
	} else {
		child = new createjs.Shape();
	}
	return child;
}
function removeOldChild() {
	var child = container.getChildAt(0);
	container.removeChildAt(0);
	children.push(child);
}

使い終えたオブジェクトは変数(children)の配列に入れます。オブジェクトを返す関数(getNewChild())は、配列にエレメントがないときだけ新たにつくります。オブジェクトがあれば、配列から取出して、描画を消したうえで返します。

一番古いオブジェクトを表示リストから除く関数(removeOldChild())は、その後配列エレメントに加えます。これで、つくられたインスタンスは消されることなく、使い回されます。

03 曲線のアニメーションを滑らかに描く

サンプル001の動きに、不具合といえるところはありません。ただ、曲線の描かれるアニメーションに滑らかさが少し足りないようです。とくに、線の太さが変わるとき、階段状に見えてしまうことがあります。

そこで、ふたつ手を加えました。まず、線の太さはイージングを加えながら変えます。


var currentLineThickness = 1;

function drawCurve(myGraphics, oldPoint, newPoint, controlPoint) {
	getLineThickness(oldPoint, newPoint);
	myGraphics.beginStroke("black")
	// .setStrokeStyle(getLineThickness(oldPoint, newPoint), "round", "round")
	.setStrokeStyle(currentLineThickness, "round", "round")
	.moveTo(oldPoint.x, oldPoint.y)
	.quadraticCurveTo(controlPoint.x, controlPoint.y, newPoint.x, newPoint.y);   
}

function getLineThickness(oldPoint, newPoint) {

	var lineThickness = distance / ratio;
	currentLineThickness += (lineThickness - currentLineThickness) * 0.5;
	// return lineThickness;
}

つぎに、Ticker.timingModeプロパティに定数Ticker.RAFを定めて、requestAnimationFrameのモードにしました。これで描画の効率が上がり、描替えの頻度も高まります。今回のサンプルでは、経過時間を計算に用いていないので、変更も楽です。

function initialize() {

	createjs.Ticker.timingMode = createjs.Ticker.RAF;
	createjs.Ticker.addEventListener("tick", draw);   
}

これらふたつの調整を加えたのが、つぎのサンプル002です。

サンプル002■EaselJS 0.7.1: Smooth Line tuned

その他の記事