電子書籍の厳選無料作品が豊富!

Macromedia Flash8を使っているほぼ初心者の質問です。

Flashで作りたいものがあるのでもしおわかりになる方がいれば教えてください。

今、このような名札のようなものを作っています。

    ┌────────┐
 名前└────────┘

┌──┬───────┬──┐
│   │          │   │
└──┴───────┴──┘
 ↑     ↑     ↑
通常画像(1) パターンで  通常画像(2)
     塗りつぶした画像  



名札なので
パターンで塗りつぶした画像の部分にテキストボックスを配置し
文字を名前欄に入力するとその画像部のテキストボックスに反映されるという仕様です。

反映させるのは本を見つつ出来るようになったのですが
今回わからずに困っているのは名前の文字数が長くなれば
このままだと文字が名札からはみ出てしまいますので
長かった場合パターンで塗りつぶした画像が右に伸びて通常画像(2)が右に移動するように
したいのですがどうすればいいのかわからない状態です…。


わかりにくい文章で大変申し訳ありません。
もし何かありましたら補足させていただきます。

おわかりになる方がいらっしゃいましたらよろしくお願い致します。

A 回答 (3件)

テキストボックス というのは,


普通の テキストフィールド(ダイナミックテキスト or テキスト入力) と解釈してよろしいでしょうか?

テキストボックスは知りませんが,
似たようなものに,
テキストフィールド(TextField) と,TextAreaコンポーネントと,TextInputコンポーネントがあります。
それぞれのクラスが違うのでスクリプトや操作方法も変わります。

よくわからないので,
一般的によく使われる テキストフィールド として回答します。



> 長かった場合パターンで塗りつぶした画像が右に伸びて
> 通常画像(2)が右に移動するようにしたい

構造物の説明は,文字でしか書けないココでは説明しにくいのですが,
さらに説明を難しくさせる部分が
「パターンで塗りつぶした画像が右に伸びて」 です。

そのままを実現すると,パターンの模様(ガラ)も横伸びしますよ。
パターンの模様(ガラ)は横伸びをさせずに,パターンの模様の表示エリアを広くするのではないでしょうか?

この部分に少し頭を使いましたが,
まず「パターンで塗りつぶした画像」をかなり横長に作成しておいて,
その「パターンで塗りつぶした画像」にマスクをかけて,
そのマスクを拡大させれば,
パターンの模様(ガラ)は横伸びをさせずに,
パターンの模様(ガラ)の表示エリアを広くすることが可能になります。

以上のようなこととして以下の回答をします。



///////////////////////////////////////////////////////

詳細は後に書くとして,まずはムービーの構造を書きます。
度々出てくる MC とか mc はムービークリップのことです。


---_rootのタイムライン-----------------------
 □ レイヤー  ・・■|○| ←ActionScriptを書く
 □ レイヤー  ・・■|●| ←テキストフィールド(2つ)
 □ レイヤー  ・・■|●| ←通常画像(2つ)
 ■ レイヤー  ・・■|●| ←マスク(mask_mc)
   ■ レイヤー・・■|●| ←パターン画像
----------------------------------------


---_rootのステージ上------------------------
       ↓テキスト入力(インスタンス名 input_txt)
       □□□□□□□□□□□□□

           ダイナミックテキスト(output_txt)
 ■■■■■回回↓回回回回回回回回■■■■■
 ■■■■■回□□□□□□回回回回■■■■■
 ■■■■■回回回回回回回回回回回■■■■■
  通常画像      マスクMC       画像MC
              (mask_mc)      (gazou_mc)
-----------------------------------------



下のレイヤーの方から説明します。



まずパターン画像ですが,
これは上にも書きましたように横長なものを作成しておきます。



次にマスク(mask_mc)ですが,
パターン画像の上のレイヤーに,何色でも良いので "塗りだけ" の長方形(または正方形)を描きます。
描く位置は,通常画像(1) と (2) の間です。
最初の見た目を決めるだけですから横長でなくても良いです。

描いた "塗りだけ" の長方形 を選択してムービークリップに変換します。
変換するときに 基準点 に気を付けます。
テキストフィールドの基準点は左上ですから,
それに準じてややこしくないようにムービークリップの基準点も左上に設定して「OK」します。
つまり,
「シンボルに変換」パネルで 基準点(R): の部分を
次のように左上にチェックを入れて「OK」します。

 ■□□
 □□□
 □□□

変換しましたらそのムービークリップを選択して,
ステージ下のプロパティインスペクタで インスタンス名 を付けます。
インスタンス名は 「mask_mc」 と付けることにしておきます。

そして, 「mask_mc」 のあるレイヤーの,
レイヤー1 とか 2 とかになっている レイヤー名 の部分を選択して,
[右クリック]→[マスク] にチェックをするなどしてマスクレイヤーにします。



次に通常画像ですが,
マスクレイヤーの上のレイヤーに 通常画像(1) はそのまま配置して問題はありません。

通常画像(2) はムービークリップに変換します。
このときの基準点も 「mask_mc」 と同様,左上にしておきます。

このムービークリップになった 通常画像(2) にもインスタンス名を付けます。
インスタンス名は 「gazou_mc」 と付けることにしておきます。



次に テキストフィールド(2つ) ですが,
入力してもらう方のテキストフィールドは,テキスト入力 の設定にしておいて,
これにもインスタンス名を付けます。
インスタンス名は 「input_txt」 と付けることにしておきます。

表示される方のテキストフィールドは,
ダイナミックテキスト の設定にしておいて,
[テキストの周囲にボーダーを表示] のボタンを押さない状態にします。
つまり テキストの周囲にボーダーを表示 させないようにしておきます。

配置する場所はマスクのムービークリップに重なるような位置です。
ActionScriptでは,
表示されるテキストがマスクからはみだしそうになったとき,
マスクのムービークリップの左側からこのテキストフィールドの左側の間隔で,
テキストフィールドの右側と 通常画像(2) との間隔も決まるようにしています。
それをイメージするような位置に配置します(つまり適当に配置してください。)

そしてこのテキストフィールドにもインスタンス名を付けます。
インスタンス名は 「output_txt」 と付けることにしておきます。



そしてやっと ActionScript です。

この説明は簡単。
ActionScript用にレイヤーを1つ作って,次のように書けば(コピペ可)完成です。

------------------------------
// masc_mc と output_txt の隙間を算出
chink = output_txt._x-mask_mc._x;

// mask_mc の初期幅を記録
mask_w = mask_mc._width;

// output_txt を自動サイズにする
output_txt.autoSize = true;

// input_txt に文字入力時の動作を定義
input_txt.onChanged = function() {

// output_txt に input_txt の文字を代入
output_txt.text = this.text;

// output_txtの幅+隙間 が mask_mcの初期幅 より大きいとき
if (chink*2+output_txt._width>mask_w) {
// mask_mcの幅を output_txtの幅+隙間 にする
mask_mc._width = chink*2+output_txt._width;
} else {
// それ以外はmask_mc の初期幅通りにする
mask_mc._width = mask_w;
}

// gazou_mc の座標を mask_mc の右横に付ける
gazou_mc._x = mask_mc._x+mask_mc._width;

};
------------------------------



このActionScriptは上記の通り簡単です。
テキストが入力されたとき,
大きさが変動するテキストフィールドにその文字を代入して,
そのテキストフィールドの大きさに合わせて,
ムービークリップの横幅や座標を動かす。
それだけのことです。

それ以外のしくみを考えて,
そのしくみ込み込みで動くようにするのが難しいのですよ。
また,説明するのもそれを理解するのも難しいのです。



ちなみにどうでも良いことですが,
上のスクリプトを次のようにすると,ちょっとFlashっぽい動きになります。

------------------------------
// masc_mc と output_txt の隙間を算出
chink = output_txt._x-mask_mc._x;

// mask_mc の初期幅を記録
mask_w = mask_mc._width;

// mask_mcの目標幅の初期値を設定
mask_aim_w = mask_mc._width;

// output_txt を自動サイズにする
output_txt.autoSize = true;

// input_txt に文字入力時の動作を定義
input_txt.onChanged = function() {

// output_txt に input_txt の文字を代入
output_txt.text = this.text;

// output_txtの幅+隙間 が mask_mcの初期幅 より大きいとき
if (chink*2+output_txt._width>mask_w) {
// mask_mcの目標幅を output_txtの幅+隙間 にする
mask_aim_w = chink*2+output_txt._width;
} else {
// それ以外はmask_mc の初期幅通りにする
mask_aim_w = mask_w;
}

};

// 1フレーム進む時間毎に随時実行
this.onEnterFrame = function() {
// mask_mc の幅を目標幅に 0.2 の割合ずつ近付ける
mask_mc._width += (mask_aim_w-mask_mc._width)*0.2;
// gazou_mc の座標を mask_mc の右に付ける
gazou_mc._x = mask_mc._x+mask_mc._width;
};
------------------------------
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

テキストボックス等間違った記述があったにも関わらず私のやりたいことが実現できました。
本当にありがとうございます。
やってみたとき感動で叫んでしまいました。

マスクを使うとは全く思いつきもしませんでした。
丁寧に一行一行説明してくださり、実現できただけでなく理解もできました。

ですがおっしゃる通り他のしくみ組み込みで動かすのがまた難しいですね。
今は出力するテキストフィールドが1つの名札の中に実は2つありまして(名前とクラブ名)
名前のテキストフィールドが伸びれば同じ長さにクラブ名テキストフィールドも
伸びて欲しい。
逆もまた然り…。
という状態で格闘しております。

お礼部分で質問をして申し訳ないのですが
もしよろしければヒントだけでも頂けるとありがたいです。

なにはともあれこの回答とても助かりました。
ありがとうございました!

お礼日時:2008/07/18 11:53

#1&2 です。




> テキストフィールドを箱として見せたいのではなく
> 2つのテキストの文字を左ぞろえではなく短い方を
> 中央ぞろえにしたかったからなんです。

それですと,
#2で作成した枠用のムービークリップ2つをレイヤーごと削除して,
#2のスクリプトから次の行を消して,

// 枠用MCの横幅を output_w にする
waku_c_mc._width = waku_n_mc._width=output_w;

ユーザ定義関数 nameCardCoordinate 内の最後に次の2行(3行)を加えれば良いと思います。

// ★表示用テキストをマスクと通常画像(2)の中間ポイントに移動
output_c_txt._x = (gazou_mc._x-mask_mc._x)/2-output_c_txt._width/2+mask_mc._x;
output_n_txt._x = (gazou_mc._x-mask_mc._x)/2-output_n_txt._width/2+mask_mc._x;

つまり,
スクリプト全体は次のようになります。

////////////////////////////////////////////////////////////////////////////
// masc_mc と output_c_txt の隙間を算出
chink_c = output_c_txt._x-mask_mc._x;
// masc_mc と output_n_txt の隙間を算出
chink_n = output_n_txt._x-mask_mc._x;
// chink に chink_c と chink_n の大きい方の値を代入
chink = Math.max(chink_c, chink_n);

// mask_mc の初期幅を記録
mask_w = mask_mc._width;

// output_c_txt を自動サイズにする
output_c_txt.autoSize = true;
// output_n_txt を自動サイズにする
output_n_txt.autoSize = true;

// ユーザ定義関数 nameCardCoordinate の定義
function nameCardCoordinate() {
//
// output_w に output_c_txt の幅 と output_n_txt の幅の大きい方を代入
output_w = Math.max(output_c_txt._width, output_n_txt._width);
//
// output_w が mask_mcの初期幅 より大きいとき
if (chink*2+output_w>mask_w) {
// mask_mcの幅を output_txtの幅+隙間 にする
mask_mc._width = chink*2+output_w;
} else {
// それ以外はmask_mc の初期幅通りにする
mask_mc._width = mask_w;
}
//
// gazou_mc の座標を mask_mc の右横に付ける
gazou_mc._x = mask_mc._x+mask_mc._width;
//
// ★表示用テキストをマスクと通常画像(2)の中間ポイントに移動
output_c_txt._x = (gazou_mc._x-mask_mc._x)/2-output_c_txt._width/2+mask_mc._x;
output_n_txt._x = (gazou_mc._x-mask_mc._x)/2-output_n_txt._width/2+mask_mc._x;
}

// input_c_txt に文字入力時の動作を定義
input_c_txt.onChanged = function() {
// output_c_txt に input_c_txt の文字を代入
output_c_txt.text = this.text;
// ユーザ定義関数 nameCardCoordinate の実行
nameCardCoordinate();
};

// input_n_txt に文字入力時の動作を定義
input_n_txt.onChanged = function() {
// output_n_txt に input_n_txt の文字を代入
output_n_txt.text = this.text;
// ユーザ定義関数 nameCardCoordinate の実行
nameCardCoordinate();
};
////////////////////////////////////////////////////////////////////////////



> ActionScriptは奥が深いですね。

そうとも言える???のかもしれませんが,
今回の場合はそうではなくて,
inataroさんの求めていらっしゃるものが奥が深いだけなのではないかと思いますよ。

ややこしことをさせなければ簡単なのですが,
ややこしいことをさせようと思うので,ActionScript がややこしくなるのだと思います(多分...)。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

ちゃんと動いてくれました…。
感動です。
しっかり伸びました。

ややこしい質問にも関わらず本当に丁寧に回答していただき誠にありがとうございました。

>そうとも言える???のかもしれませんが,
>今回の場合はそうではなくて,
>inataroさんの求めていらっしゃるものが奥が深いだけなのではないか>と思いますよ。
あまりプログラムなどを組んだことがないのでこの場合はこうする!という
発想が乏しく奥が深いなぁと感じてしまった次第です。
でもWEBデザイナーさんのサイト等を見ていると想像もつかない動きをするので
そういうサイトこそ奥が深いと言えるのかもしれないですね^^;

本当にありがとうございました。

お礼日時:2008/07/21 14:42

#1 です。

遅くなりました。

> 名前のテキストフィールドが伸びれば
> 同じ長さにクラブ名テキストフィールドも伸びて欲しい。

どこから説明すれば良いのか(どこまで溯れば良いのか)がわかりませんが,
#1 で書いたものはそこでも書きましたように,

> 表示される方のテキストフィールドは,
> ダイナミックテキスト の設定にしておいて,
> [テキストの周囲にボーダーを表示] のボタンを押さない状態にします。
> つまり テキストの周囲にボーダーを表示 させないようにしておきます。

という条件が前提となっています。
ですからそもそも 「キストフィールドが伸びる」 ということは意味を成しません。
(仮に伸ばしても見えない。)

なぜテキストの周囲にボーダー非表示にするのかというと,
テキストフィールドに枠を付けると折角のパターン柄が見えにくくなるというのもありますが,
> // output_txt を自動サイズにする
> output_txt.autoSize = true;
をするので,見えると不恰好だからです。

ではなぜ,
> // output_txt を自動サイズにする
> output_txt.autoSize = true;
をするのかというと,
文字数でテキストフィールドの幅を求めることは不可能だからです。

テキストフィールドに表示される文字列の幅は,
テキストのポイント数や半角全角によって変わるのも当然ですが,
それどころではなく,フォントによって1文字の大きさがまちまちです。

たとえば,
デバイスフォントの「_ゴシック」や,「MS P明朝」のように P の付いたフォントは
プロポーショナルフォントですから文字によって幅は変わります。
また,
デバイスフォントの「_等幅」や,「MS 明朝」のような等幅フォントにしたからと言って,
そのフォントがわからない以上,どのような文字列の幅になるかはわかりません。
計算式の立てようがないということです。
また,
デバイスフォントの「_等幅」に固定したとしても,Windows と Mac では文字の大きさに差が出ます。
エンドユーザのPCで入力した文字の文字数から
文字列の幅を算出することは不可能です。

ですから,
とりあえずは autoSize = true 設定のテキストフィールドに文字列を入れてみて,
そこでテキストフィールド横幅を知ることで,全てを決めているのです。



===というわけで本題=============

> 名前のテキストフィールドが伸びれば
> 同じ長さにクラブ名テキストフィールドも伸びて欲しい。
> 逆もまた然り…。

それは
> // output_txt を自動サイズにする
> output_txt.autoSize = true;
を使う時点で無理です。

ですから,
テキストフィールドの枠になるようなムービークリップを自作して,
テキストフィールドの下(同じ座標の下レイヤー)に配置して,
そのムービークリップの横幅を伸ばしてテキスト枠を付けるという方法を取るのが良いのではないかと思います。

---_rootのタイムライン--------------------------
 □ レイヤー  ・・■|○| ←ActionScriptを書く
 □ レイヤー  ・・■|●| ←テキストフィールド(4つ)
 □ レイヤー  ・・■|●| ←★テキストフィールド枠MC(2つ)
 □ レイヤー  ・・■|●| ←通常画像(2つ)
 ■ レイヤー  ・・■|●| ←マスク(mask_mc)
   ■ レイヤー・・■|●| ←パターン画像
-------------------------------------------


テキストフィールドの下にレイヤーを挿入して,
そこに矩形ツールで「極細線の縁線付き白塗り四角」を描きます。
幅は適当です。
高さはテキストフィールドと同じ高さかすこし高めが良いと思います。

「極細線」は矩形ツールを選択した状態で下のプロパティインスペクタより,
中央付近の [実線----------------[v]] となっている部分を
[v]をクリックし [極細線--------------[v]] にすると選択できます。

「1px」とか「0.25px」とか px 単位の太さにすると,
ムービークリップを拡大縮小させたときに線の太さまで変わってしまいます。
拡大縮小時に線の太さを変えないために 「極細線」 にします。

※またはムービークリップに変換時に
 □ 9スライス拡大/縮小のためのガイドを表示
 にチェックを入れて 9スライスを有効にしても良いと思います。
 その場合線の太さは何でも良いです。角丸もOKになります。

そのテキストフィールド用枠の四角をムービークリップに変換しますが,
これも基準点を左上にしておきます。

そして,
そのムービークリップをコピペなどで2つに増やして,
2つにインスタンス名を付けます。

クラブ名用が「waku_c_mc」,名前用が「waku_n_mc」としておきます。
その2つを,
クラブ名用テキストフィールドの下(同じ座標の下レイヤー)と,
名前用テキストフィールドの下(同じ座標の下レイヤー)に配置します。


あと,入力用テキストフィールド と 表示用テキストフィールドのインスタンス名を変更します。

クラブ名入力用テキストフィールド 「input_c_txt」
名前入力用テキストフィールド 「input_n_txt」
クラブ名表示用テキストフィールド 「output_c_txt」
名前表示用テキストフィールド 「output_n_txt」


そしてスクリプトを次のように変更します。

///////////////////////////////////////////////////////////////
// masc_mc と output_c_txt の隙間を算出
chink_c = output_c_txt._x-mask_mc._x;
// masc_mc と output_n_txt の隙間を算出
chink_n = output_n_txt._x-mask_mc._x;
// chink に chink_c と chink_n の大きい方の値を代入
chink = Math.max(chink_c, chink_n);

// mask_mc の初期幅を記録
mask_w = mask_mc._width;

// output_c_txt を自動サイズにする
output_c_txt.autoSize = true;
// output_n_txt を自動サイズにする
output_n_txt.autoSize = true;

// ユーザ定義関数 nameCardCoordinate の定義
function nameCardCoordinate() {
//
// output_w に output_c_txt の幅 と output_n_txt の幅の大きい方を代入
output_w = Math.max(output_c_txt._width, output_n_txt._width);
//
// output_w が mask_mcの初期幅 より大きいとき
if (chink*2+output_w>mask_w) {
// mask_mcの幅を output_txtの幅+隙間 にする
mask_mc._width = chink*2+output_w;
} else {
// それ以外はmask_mc の初期幅通りにする
mask_mc._width = mask_w;
}
//
// 枠用MCの横幅を output_w にする
waku_c_mc._width = waku_n_mc._width=output_w;
//
// gazou_mc の座標を mask_mc の右横に付ける
gazou_mc._x = mask_mc._x+mask_mc._width;
}

// input_c_txt に文字入力時の動作を定義
input_c_txt.onChanged = function() {
// output_c_txt に input_c_txt の文字を代入
output_c_txt.text = this.text;
// ユーザ定義関数 nameCardCoordinate の実行
nameCardCoordinate();
};

// input_n_txt に文字入力時の動作を定義
input_n_txt.onChanged = function() {
// output_n_txt に input_n_txt の文字を代入
output_n_txt.text = this.text;
// ユーザ定義関数 nameCardCoordinate の実行
nameCardCoordinate();
};
///////////////////////////////////////////////////////////////



◎ ちなみにActionScriptの補足

#1 で書いたスクリプトもこのスクリプトも,
_root や _level0 などが付く絶対パスを一切使用していません。

なぜそうしているのかと言うと,
#1 で書いたものやこの回答で書いたものは,
_root(メインのムービーのタイムライン)だけではなく,
ムービークリップの中にでも同じ構造を作成することを可能にするためです。

#1や上で書いたものを,
_root ではなく ムービークリップ 内のタイムライン内に作成すると,
「自作 オリジナル コンポーネント モドキ」ができて持ち運びや使い回しが簡単になります。
シンボル名をユニークなものにしておけば,
他のFLAファイルにそのムービークリップをコピペするだけでも使用できます。

いつもそうとは限りませんが,
書かれていらっしゃるような機能を果たすツールのようなものを作成するときは,
この辺を意識するようにすると,
同じ動作をするスクリプトであっても使い勝手が違ったものになります。

この考え方をさらに発展させると,
カスタムクラス(自作クラス)の作成などにもつながって行きます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます!
私のわがままにも丁寧に解説して下さり大変感謝しております。

テキストフィールドを自動サイズにするとサイズ指定ができないのですね。
一生懸命長いほうのテキストフィールドの長さを取得して同じようにする命令を書いては出来なくて悩んでいました…。

更に、使う人の環境によって同じフォントサイズでも見え方が変わってくるのですね。
自分でしか見てなかったので友人にも見てもらうことにします。


そしてなぜ、テキストフィールドを伸ばしたいかといいますと
テキストフィールドを箱として見せたいのではなく
2つのテキストの文字を左ぞろえではなく短い方を中央ぞろえにしたかったからなんです。
言葉足らずでした。
申し訳ありません。

×
たなかじろう
ハンドボール部(2年生)


   たなかじろう
ハンドボール部(2年生)

一回目の回答を頂いた後に悩み倒した結果、短い方のテキストフィールドを
長い方に合わせて移動させることにしました。
まだうまくいっておりませんが質問タイトルと内容が全然違うことになってしまうので
本当に行き詰りましたらまた別で質問させていただきます。

BlurFiltanさんの回答を参考にがんばります!

本当にありがとうございました。
ActionScriptは奥が深いですね。

お礼日時:2008/07/20 14:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!