Adobe Illustratorでテキストのレイアウト情報をスクリプトで取得する

Create.jsのコンテンツをAnimateCCを使用せず、直接コードを書いて製作している場合。 イラストレーターのデザインデータを組み込もうとすると、選択して座標値を取得してコピペしてコードを書いて…という手順が必要になります。

Flashの時はコピペで直接タイムラインに放り込めばレイアウト反映済みのインスタンスができたのに!

辛くなったのでIllustrator用のスクリプトを書きました。

スクリプト

テキストオブジェクトを選択して実行すると、新規作成したレイヤーにCreate.jsでTextのインスタンスを生成するコードを吐き出します。

//結果を書き出すレイヤー
var resultLayer;
var resultLayerName = "_Positions";

//改行、区切りコード
var CR = String.fromCharCode(13);
var TAB = String.fromCharCode(9);

main();

function main() {

	var n = activeDocument.selection.length;
	if (n <= 0) {
		alert("座標を書き出したいオブジェクトを選択してからスクリプトを実行してください")
		return;
	}

	resultLayer = addLayer(resultLayerName);
	for (var i = 0; i < n; i++) {
		chekckPathItem(activeDocument.selection[i]);
	}
}


/**
 * 指定された名前のレイヤーを作成する。
 * すでにその名前のレイヤーが存在する場合はそのレイヤーを返す。
 * @param {string} layerName
 */
function addLayer(layerName) {
	var layer;
	var myDoc = app.activeDocument;
	for (var i = 0, il = myDoc.layers.length; i < il; i++) {
		if (myDoc.layers[i].name == layerName) {
			layer = myDoc.layers[i];
			layer.locked = false;
			layer.visible = true;
			break;
		}
	}
	if (!layer) {
		layer = myDoc.layers.add();
		layer.name = layerName;
	}
	return layer;
}

/* ***************************
 * 座標の書き出し
 *****************************/
function chekckPathItem(object) {

	if (object.typename !== "TextFrame") {
		//選択した対象がテキストではないので終了
		return;
	}
	var chr = object.characters[0];

	//現状の座標系設定を保存
	var currentSystem = app.coordinateSystem;
	//座標系をアートボード原点に変更
	app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;

	//バウンディングボックスの取得
	var bounds = object.geometricBounds;
	var anchor = object.anchor;
	var anchorX = Math.round(object.anchor[0]);
	var anchorY = Math.round(-object.anchor[1]);

	//textAlignとX座標の取得
	var textAlign = getTextAlign(object);

	//フォント設定の取得
	var fontName = chr.textFont.family;
	var styleName = getTextStyle(object);

	//色の取得
	var colorString = getColorString(object);

	var contents = object.paragraphs[0].contents;
	var fieldName = "textField_" + contents.split(' ').join('');

	//出力テキストを整形
	var result = "";
	result = 'const ' + fieldName + ' = new createjs.Text("'
		+ contents + '", "' + styleName + chr.size + 'px ' + fontName + '", "' + colorString + '");' + CR;
	result += fieldName + ".x = " + anchorX + ';' + CR;
	result += fieldName + ".y = " + anchorY + ';' + CR;
	result += fieldName + '.textAlign = "' + textAlign + '";' + CR;
	result += fieldName + '.textBaseline = "alphabetic";' + CR;
	result += 'this.addChild( ' + fieldName + ' );' + CR;

	//出力テキストを元オブジェクトの上に移動
	var textFrame = resultLayer.textFrames.add();
	textFrame.contents = result;
	textFrame.translate(bounds[0], bounds[1]);
	setTextColors(textFrame, 255, 0, 255);

	//座標系を元に戻す
	app.coordinateSystem = currentSystem;
}

function getTextStyle(obj) {
	var chr = obj.characters[0];
	switch (chr.textFont.style) {
		case "Regular":
			return "";
		case "Bold":
			return "Bold "
	}
	return "";
}

/**
 * TextAlignを取得する。
 * @param {TextFrameItem} obj 
 */
function getTextAlign(obj) {
	var justify = obj.paragraphs[0].paragraphAttributes.justification;
	switch (justify) {
		case Justification.LEFT:
			return "left";
		case Justification.RIGHT:
			return "right";
		case Justification.CENTER:
			return "center";
	}
	return "";
}

/**
 * TextFrameItemのカラー情報を取得する
 * 形式はrgba(r,g,b,a)
 * @param {TextFrameItem} obj 
 */
function getColorString(obj) {
	var chr = obj.characters[0];
	var color = chr.fillColor;
	var opacity = obj.opacity;

	var colorString = 'rgba('
		+ color.red + ','
		+ color.green + ','
		+ color.blue + ','
		+ opacity / 100
		+ ')'

	return colorString;
}

/**
 * TextFrameItemの文字全てに塗りの色を指定する。
 * @param {TextFrameItem} obj 
 * @param {number} r 
 * @param {number} g 
 * @param {number} b 
 */
function setTextColors(obj, r, g, b) {

	var fillColor = new RGBColor();
	fillColor.red = r;
	fillColor.green = g;
	fillColor.blue = b;

	for (i = 0, n = obj.characters.length; i < n; i++) {
		var chr = obj.characters[i];
		chr.fillColor = fillColor;
	}
}

実行結果

実行するとこんな感じのテキストオブジェクトができます。

const textField_example = new createjs.Text("example", "16px Arial", "rgba(255,255,255,1.0)");
textField_example.x = 128;
textField_example.y = 648;
textField_example.textAlign = "left";
textField_example.textBaseline = "alphabetic";
this.addChild( textField_example );

バウンディングボックスの取得ができるので 、ちょっと改造するとアセット書き出ししたパーツの座標出力とか、パスのアンカーポイントの配列での出力とかができます。