[jsfl] シンボル化されていないシェイプでも座標を丸めたい!

2014/08/28

こんにちは。きんくまです。

Flashでツールアプリを作っております。最近IDEをFlash BuilderからIntelliJ IDEAに乗り換えました。1年まえにくらいにWebStormも買っちゃったので、JetBrainsさんにお布施してますね。あーいまみたらWebStromの方はライセンス切れしてました。(でも、アップグレードできないだけで、そのバージョンで使い続けること自体は大丈夫みたい)
これでjs/TypeScriptもflash/AIRもIDEA一本でできるからいいかもと思って使ってます。
ためしてないけど、Androidも作れるの??

さてさて、クライアントから「たくさんあるファイル内の、ステージ上のオブジェクトの座標を丸めたい」というご要望がありました。

で、こういうときはjsflを使って自動で作業をさせるのですが、そんなときこんな感じのjsflがあります。

var sel = fl.getDocumentDOM().selection[0];
sel.x = Math.round(sel.x);
sel.y = Math.round(sel.y);

(上のコードは適当なんで動かないかも。)

で、これはMovieClipのインスタンスだったり、シンボル化されているものをステージ上に置いたときには、きちんと機能するんですが、シンボル化されていないもの、例えばシェイプなんかについてはうまく機能しないのでした。

これは困りました。ググっていろいろと試みたのですが、うまくいきません。
で、結局作ったのがこれです。

function snapPixels( element ) {
	/* 浮動小数点の丸め誤差のため数回まわす */
	for(var i = 0; i < 5; i++){
		var tmpX = element.left;
		var tmpY = element.top;
		var dx = Math.round(tmpX) - tmpX;
		var dy = Math.round(tmpY) - tmpY;
		if(dx == 0 && dy == 0){
			break;
		}
		element.x += dx;
		element.y += dy;
	}
}

/* 使い方 */
var sel = fl.getDocumentDOM().selection[0];
snapPixels(sel);

snapPixelsのところが本体です。下の2行は使いかたで、実際には、ステージ上全体を捜査してループでエレメントを検出したりとかして使うことを想定してます。

flashの内部構造がどうなっているのか正直よくわからないんですが、調べてみると、シェイプの場合、element.x, element.y はプロパティパネル上のx, yとは値が違っていました。その代わりに、element.left, element.topがx,yの値になっていました。
なので、element.left, element.topを四捨五入の対象にして、x,yに差分を割り当てました。

ただ、これだけだと何故かうまくいかないことがあります。たぶん内部的に浮動小数点で座標をもっているのか(よくわかんなくて書いてます)1回ではなく3回ぐらい回すと、完全に小数点以下を0にすることができました。うーん、謎。

LINEで送る
Pocket

自作iPhoneアプリ 好評発売中!
フォルメモ - シンプルなフォルダつきメモ帳
ジッピー電卓 - 消費税や割引もサクサク計算!

ページトップへ戻る