Archives

You are currently viewing archive for June 2009
カテゴリ: Progression
投稿者: terada
Progressionで自作コマンドを作っていて、ちょっとひっかかったところ。CastButtonなどの中にあるaddCommandの中でスコープを受け渡す方法です。

例えばCastButtonクラスの中で、
protected override function _onCastMouseDown():void 
{
addCommand(
HogeCommand( this )
);
}
みたいな感じでCastButtonクラスへの参照を渡そうとすると失敗します。
protected override function _onCastMouseDown():void 
{
var scope = this;
addCommand(
HogeCommand( this )
);
}
も案の定ダメ。さて、正解(?)は・・・
protected override function _onCastMouseDown():void 
{
var hoge:HogeCommand= new HogeCommand();
hoge.scope = this;
addCommand(
hoge
);
}


こうすると、HogeCommandクラス内のscope変数でCastButtonの参照が取れます。Commandクラスにあらかじめscopeという変数が用意されていました。でも説明ないし、あんまりこの件扱った記事も少ないのは、単に自分のCommandクラスへの理解が足りないのか。デザインパターンちゃんと勉強しよう、というメモ。
カテゴリ: Illustrator
投稿者: terada
非表示状態のレイヤーやアイテム・グループをきれいに消去してくれるJavascriptを作ってみました。ロックされてても関係なく消されます。個人的には最後のクリーンナップがポイント高し。

DeleteAllHiddens.zip

<使い方>
・解凍したファイルを「Adobe Illustrator CS3/プリセット/スクリプト/...」に保存
・「ファイル→スクリプト→DeleteAllHiddenItemsAndLayers」を実行
・実行後アラートで処理結果を表示

<処理の流れ>
非表示状態のアイテムの消去

非表示状態のレイヤーの消去

子要素がなくなったレイヤーの消去(クリーンナップ)


前回のスクリプトの使用前に使うと便利かと思います。
カテゴリ: Illustrator
投稿者: terada
<追記:2013.5.8 バージョンアップしました


ウェブとは関係ないエントリです。
巷によくあるレイヤーごとPDF書き出しのスクリプトって、その他のレイヤーを非表示にするだけでやってたりするので、書き出したPDFの容量が無駄に大きくなり、あまりよろしくありません。なので、いつも別ファイルに必要なものだけ持っていって書き出したりしていたのですが、やはりつらいのでJavascriptで書いてみました。最上位階層のレイヤーを走査して、その他のレイヤーを毎回消しながら順番にPDF保存していきます。個人的に、ヘッダーなどの共通部分も一つのレイヤーにまとめるやり方をよくするので、それも考慮してみました。
今回、ExtendscriptToolkitを使ってみたのですが、便利ですね。変数値の監視や$クラスを使ったブレークポイント挿入やwrite関数、さらにIllustratorを再起動しなくても実行できるのが素晴らしい。

せっかくなので、作ったスクリプトを公開します。ぜひ使ってみてください。
ソースの上部に主要なPDFの書き出しオプションまとめてるので、必要なら書き換えてください。そのうち、ダイアログで設定可能なようにしたいですな。勉強してみます。


SaveAsPDFByLayers.zip

<追記:2012.2.17>
※ 中身は一緒ですが課金版も用意してみました。100円です。Gumroadなのでその場で簡単にクレジット決済できます。気に入ったら、購入お願いしますっ。売れたら、アップデートする気が起こるかも?

Get this for 100 yen


<使い方>
・解凍したファイルを「Adobe Illustrator CS3/プリセット/スクリプト/...」に保存
・「ファイル→スクリプト→SaveAsPDFByLayers」を実行
・実行後にダイアログが表示されますので、保存先を指定してください
・保存されるPDFは「[3桁連番]_[レイヤー名].pdf」となります

<機能・解説>
・最上位階層のレイヤーを上から順にPDFで保存します
・下位階層のレイヤーは操作の対象になりません
・ロックされているレイヤーは操作の対象になりません
・ヘッダーなどの共通部分を含むレイヤーは「表示・ロック」しておくと便利です
・「非表示・ロック」になっているレイヤーも非表示のまま書き出し対象になりますので、不必要なレイヤーはあらかじめ破棄しておくことをお勧めします(追記:こちらを活用してください)
・書き出されたPDFのファイル名の接頭数字は3桁でつくので、Acrobatで一気に読みこんだ時に順番の入替作業が不要で便利です
カテゴリ: FLASH (AS3)
投稿者: terada
カスタムクラスでイベントの発行を行いたい、でもすでに他のクラスを継承しちゃってる場合、AS3は多重継承できないのでIEventDispatcherインターフェースを実装するんですよね。リファレンスをみるとこんなサンプルがあります。

元のサンプルコード
package {
import flash.events.Event;
import flash.display.Sprite;

public class IEventDispatcherExample extends Sprite {
public function IEventDispatcherExample() {
var decorDispatcher:DecoratedDispatcher = new DecoratedDispatcher();
decorDispatcher.addEventListener("doSomething", didSomething);
decorDispatcher.dispatchEvent(new Event("doSomething"));
}

public function didSomething(evt:Event):void {
trace(">> didSomething");
}
}
}

import flash.events.IEventDispatcher;
import flash.events.EventDispatcher;
import flash.events.Event;

class DecoratedDispatcher implements IEventDispatcher {
private var dispatcher:EventDispatcher;

public function DecoratedDispatcher() {
dispatcher = new EventDispatcher(this);
}

public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
dispatcher.addEventListener(type, listener, useCapture, priority);
}

public function dispatchEvent(evt:Event):Boolean{
return dispatcher.dispatchEvent(evt);
}

public function hasEventListener(type:String):Boolean{
return dispatcher.hasEventListener(type);
}

public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
dispatcher.removeEventListener(type, listener, useCapture);
}

public function willTrigger(type:String):Boolean {
return dispatcher.willTrigger(type);
}
}


でも、これってよく見るとDecoratedDispatcherクラスが別のクラスを何も継承してないのです!例えば、DecoratedDispatcherのスーパークラスをSpriteとかにした場合、下の赤字の部分を修正する必要があります。

サンプルコード修正
package {
import flash.events.Event;
import flash.display.Sprite;

public class IEventDispatcherExample extends Sprite {
public function IEventDispatcherExample() {
var decorDispatcher:DecoratedDispatcher = new DecoratedDispatcher();
decorDispatcher.addEventListener("doSomething", didSomething);
decorDispatcher.dispatchEvent(new Event("doSomething"));
}

public function didSomething(evt:Event):void {
trace(">> didSomething");
}
}
}

import flash.events.IEventDispatcher;
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.display.Sprite;

class DecoratedDispatcher extends Sprite implements IEventDispatcher {
private var dispatcher:EventDispatcher;

public function DecoratedDispatcher() {
dispatcher = new EventDispatcher(); // 引数のthisを消す
}

public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{
dispatcher.addEventListener(type, listener, useCapture, priority);
}

public override function dispatchEvent(evt:Event):Boolean{
return dispatcher.dispatchEvent(evt);
}

public override function hasEventListener(type:String):Boolean{
return dispatcher.hasEventListener(type);
}

public override function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void{
dispatcher.removeEventListener(type, listener, useCapture);

}

public override function willTrigger(type:String):Boolean {
return dispatcher.willTrigger(type);
}
}


リファレンスのサンプルがよくない気がします。
オーバーライドのとこはエラーが出るからすぐわかるんですが、引数のthisをはずすところ、気付かずに結構はまってしまいました・・・。元のままではイベントが発行されないので、気を付けましょう。
カテゴリ: Progression
投稿者: terada
Progression 3.1.52を使って、外部から画像を読み込んで表示する仕組みを作っていると、「index.htmlで見ると画像が表示されない」という症状が出ました。index.swfやpreloader.swfを直接開いた場合は、正常に見られるのに、index.htmlでみると表示されないのです。サーバーでもローカルでも同じ症状でした。
FireBugで読み込み状況を見てみると、ちゃんと読み込んでいるようだし、Completeメッセージもトレースできているのに、なぜか表示されないのです。
追記:画像だけでなくMCをnewしても同じでした。

※ためしにProgression 3.1.62にアップデートしても同じでした・・・

不思議だぁ、と思って調べてみるとこのような記事を発見。

baseが上手く適応されない件(Progression3.1.2)

近いかもと思って同じ手順をたどってみましたが、baseはロストしておらず、正常に受け渡されていました。でも、この記事のindex2.htmlを作ってる部分のようにprogression.jsでなくswfobjectのembedSWFを直接呼び出してswfを貼り付けるととうまく動作したので、この辺が怪しいということになりました。
なので、この記事にあるようにいったんcompressする前のprogression.js(progression-unpack.js)をいただいてきて、手持ちのprogression.jsと置き換えます。そしてこのprogression.jsの関数embedSWF周辺をちょこちょこ調べてみると、原因がつかめました。

問題の個所は59行目。

c.attributes.id = c.attributes.name = "external_" + fc;


ここではidとname属性を一気に同じ名前でつけていますが、どうやらここがいけないようです。この行全体をコメントアウトするか、どちらか一方のみ定義することで問題が解消しました。

追記:name属性を取ってしまうとswfaddressでエラーが出たので残しておいた方がよさそう。

c.attributes.name = "external_" + fc;


ただ、id属性とname属性は同一にするの、間違ってない気が・・・。でも、swfobjectの中身まで探り出すときりがなくなるので、とりあえずこれで良しということに。
すみません、この件に関して何かご存知の方おられましたら、もしくはもっとちゃんとした対処法がありましたらご享受ください!

追記:どうも「表示されない」のではなく、勝手にトップのシーンに移動してしまっていることが判明。なぜだ!?ちょっと今日は時間がないので、また後日。もしかして、Progressionの使い方自体何か間違えているのかも・・・って気がしてきました、