- ベストアンサー
スクロール処理を行うための方法
- MX2004バージョンを使用して、ScrollBarコンポーネントを使ってスクロール処理を行いたいですが、具体的な方法が分かりません。ある矩形の中に表示される複数のイメージをスクロールする仕組みを作りたいです。
- また、横スクロールで表示されるサムネイル画像があり、クリックすると別のフィールドに拡大画像が表示されるコンテンツも作りたいです。
- 自分の考えをうまく表現できないので、相談しながら進めたいです。ご協力よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
インスタンスの中心点(+)は、元になっているシンボルと必ず同じ位置になります。インスタンスごとに、それぞれ違う位置に変更することはできません。 シンボルの中心点は、シンボルを編集する時に自由に決められますが、+の印を移動するのではなく、画像の方を移動して決めます。 ○(変形の中心点)の方は、変形ツールを選択している時にドラッグすると、移動が可能です。 中心点については、Now Loading のプログレスバー(中心点を左端にして作ります)などを作ってみると、よく分かると思いますよ。シンボルの中心点を中心に置いたままだと中央からバーが伸びてしまいますし、+が中央にある状態で○を左端に移動しただけでは、同じ現象になってしまうはずです。 (ちなみに私は、この失敗から中心点のことを覚えました ^^ゞ) 失敗したら何が悪かったのか原因を考えて、不明な点はできるだけ調べて、技術と知識を身につけてください。手取り足取り教わるよりも、自分で苦労して、まあ、時にはインパクトのあるお間抜けな失敗や間違いなどもしでかして(笑)覚えた方が、よく覚えられます。 これ以上長くなるのも何ですので。 新しい疑問が出てきたら、違う質問を立ててください。同じような悩みを持っている方の参考にもなりますし、私以外の人からも詳しい回答が得られると思いますよ。
その他の回答 (4)
- DPE
- ベストアンサー率85% (666/776)
+はインスタンスの中心点です。シンボルの中心点と必ず同じ位置になり、変更はできません。 ActionScript でインスタンスの _x や _y プロパティを参照すると、この点の座標が返されます。また、_rotation や _xscale ・ _yscale プロパティを操作して変形する時も、ここが基点となります。 ちなみに、_x や _y は親座標の中心点を基準にした座標です。ステージにあるインスタンスは画面の左上を ( 0 , 0 ) 、何かのムービークリップなどの子になっているインスタンスは、親の中心点を ( 0 , 0 ) とする座標になります。 ○は、変形ツールでインスタンスを変形する時の中心点です。ムービーの編集画面で変形ツールを選択している時、○をドラッグして移動できます。 これは変形ツールで変形する時の中心点であって、ActionScript で移動・変形する時は、この点は特に意味を持ちません。例えば、+が左上に、○が中心に表示されている場合、ActionScript で移動や回転・拡大等の変形を加えると、左上を基点として移動や変形が実行されます。 同じシンボルから作ったインスタンスでありながら、インスタンスを配置する時点で、それぞれ違う点を中心にして変形したい場合などに利用してください。
補足
いつもありがとうございます。 「+はインスタンスの中心点です。シンボルの中心点と必ず同じ位置になり、変更はできません。 」 この中心点を左上に設定するようにと教えて頂いたと思うのですが、「変更出来ない」と言うのはどういう意味でしょうか?。
- DPE
- ベストアンサー率85% (666/776)
おそらくですが、sheet の中心点が中央にあるからではないかと思います。 例えば、移動の処理で sheet._x = sc_bar.getScrollPosition() * ( -1 ) + 250; このように補正値を加算すると、いかがでしょうか?これで正常に動くようでしたら、sheet の中心点が中央にあるということですが。 直らない場合は、ムービークリップの幅やマスクの幅が、実は 500 px・300 px ではない・setScrollProperties の第3引数が 200 ではない・初期配置(特にX座標)が0ではないなど、スライダの範囲とムービークリップの座標が正しく対応できていない理由が考えられます。 中心点を左端に、配置する時も ( 0 , 0 ) にと申しましたのは、その方が数値も考えやすく、また、スクロールバーの特性を考える上でも分かりやすいかと思っただけのことで、必ずこの配置でなければならない理由はありません。 getScrollPosition では、スライダが左端にある時は0が、右端にある時は 200 が返され、それを元に sheet の座標を決めています。 また、sheet の中心点が左端で、初期状態では _x = 0 になっているものとして座標を計算しています。 sheet の中心点が左端でない場合や座標が0の地点以外に配置している場合は、左端からの距離の分だけ・0の地点からの距離の分だけ生じるズレを考慮してください。 Sheet_Scrolling 関数は、スライダが移動しなければ呼び出されません。ムービーが再生された直後は1度も呼び出されておらず、sheet の配置は初期状態のままです。 1度でもスライダが動くと、関数が呼び出されて移動します。この時の座標の計算が正しくないと、2回め以降にスライダが端に来た時、表示が切れたり余白が出たりしますし、最初にスライダを移動させた時、異常に表示が飛んでしまうなどのトラブルが発生します。 最初の1回だけ正しい位置で表示されるのは、このような理由によるものです。 #都合により、次の回答は後日になります。スクロールバーの動作原理と上手くいかなかった原因を考えて、いろいろ研究してみてください。
お礼
ありがとうございます。 座標計算は、必ずゼロを基点に行なわれるんですね。 シンボルの中心点(+マーク)は左上端に位置していましたが、配置していた箇所がドキュメントの中のX=100,Y=100にしていました。補正値を+100加えれば正しく表示されました。 ムービークリップの中に、新たに各画像毎にボタンシンボルを配置し、Press時に拡大表示するように改変を加えてみます。 ところで、ムービークリップにFocusした時に左上端に+マークは付いていますが、中心に○マークがついています。 この○マークって一体何なんでしょうか?。 どうぞ宜しくお願い致します。
- DPE
- ベストアンサー率85% (666/776)
全部説明しますと長くなりますし、大変申し訳ないのですが、今回は都合によりこまめに回答ができません。 とりあえず、縦x横が 100 x 500 px のムービークリップの 100 x 300 px の部分を表示し、表示しきれない部分はスクロールさせるという、”ScrollPane もどき”を作る手順をご紹介します。これを解析するなり改良するなりしてください。 「 ScrollPane もどき」のムービークリップのレイヤー構成は、次のようにします。ここでのレイヤーの順序は、実際の Flash で表示される順序と同じです。 ・アクション :スクリプト用。 ・マスク :マスク用画像を配置。 ・表示クリップ :サムネイル画像を並べたムービークリップを配置。 ・スクロールバー: ScrollBar のインスタンスを配置。 「表示クリップ」レイヤーにスクロールさせるムービークリップを配置し、インスタンス名を付けます。ここでは sheet という名前にします。 この時、sheet の元になっているシンボルの中心点に注目してください。 #1に書きました通り、中心点が左端以外になっていると、スライダの範囲設定や座標の計算がややこしくなります。 sheet のシンボル画面を開き、シンボルの中心点を確認してください。 +の印がシンボルの中心点です。+が中央などにある場合は、これが左端に来るように画像を移動して合わせてください。 「 ScrollPane もどき」シンボルの編集画面でも、sheet の中心点(左端)が、シンボルの中心点 ( 0 , 0 ) に来るように配置します。 「マスク」レイヤーに、線のない 100 x 300 px の四角形を描画します。色は意味を持ちませんから、分かりやすい色でどうぞ。ムービークリップには変換しなくても構いません。位置は sheet の左端に合わせてください。 「マスク」レイヤーを選択して右クリックでメニューを出し、「マスク」を選択します。このレイヤーがマスク、その下の「表示クリップ」レイヤーがマスクされるレイヤーとなります。 「スクロールバー」レイヤーに ScrollBar コンポーネントのインスタンスを置き、インスタンス名を付けます。ここでは sc_bar とします。 Horizontal パラメータを true にすると、横向きになります。幅( W: )のボックスに 300 を入力して、 横 300 px のスクロールバーにします。 今回はテキストフィールドに付ける目的ではないので、Target TextField パラメータの入力は不要です。 「アクション」レイヤーのフレーム1に、次のようなスクリプトを設定します。 以下のアクションは、sheet の中心点が左端にあり、この部分が「 ScrollPane もどき」の中心点にくるように配置されているものとして話を進めます。 (コピーする場合は、各行頭の全角のスペースにご注意ください) //スクロールの処理 function Sheet_Scrolling() { //スライダの位置から座標を決める sheet._x = sc_bar.getScrollPosition() * ( -1 ); } //スクロールバーの設定 sc_bar.setScrollProperties( 50 , 0 , 200 ); //スライダが動いた時に呼ぶ関数を設定 sc_bar.setChangeHandler( "Sheet_Scrolling" ); 「 ScrollPane もどき」はこれで完成です。 スライダの大きさは、#1で書いた通り setScrollProperties の第1引数で決まります。大きさを変えたい時は、「 50 」の部分を変更してください。 スクロールバーとともに画像が動くかどうか、「ムービープレビュー」で確認してみてください。 動くには動くが、動き方がおかしい・スクロールバーを操作した途端に画像がどこかに行ってしまう場合は、中心点が左端以外にきていないかどうか、移動を実行している sheet._x = sc_bar.getScrollPosition() * ( -1 ); の部分に誤りがないかをご確認ください。 全く反応しない場合は、インスタンス名・setChangeHandler で登録する関数名が違っている可能性があります。 Flash のマスクは、マスク用画像と被マスク画像が重なっている部分だけが表示される仕組みです。 スクロールした時に画像がズレて見えるなどの場合は、マスク用画像の配置位置などにも注意してみてください。 ところで、sheet に配置されているサムネイル画像はムービークリップになっていますでしょうか? Flash に読み込んだ JPEG ファイルなどは、グラフィックというタイプのシンボルになっています。 グラフィックシンボルのインスタンスは ActionScript で制御できないため、クリックされた時の処理が作れません。 グラフィックのインスタンスを「シンボルに変換」でムービークリップにすると、グラフィックを内部に持つムービークリップになります。sheet にはこちらを配置してください。 -------------- ScrollBar コンポーネントは本来、テキストフィールドに簡単にスクロールバーを付けられるようにと提供されているものです。 ですから、テキストフィールドに付けるのであれば、テキストフィールドの名前を指定するだけで各種の設定も自動で行われ、簡単に利用できます。 テキストフィールド以外にも流用できるように設計されているコンポーネントなので、他の目的に使うことも、可能といえば可能です。 しかし、改造して本来の目的以外に使おうというのですから、対象の名前を指定するだけで利用できるようなサービスはありません。スクロールバーのトラックやスライダの大きさ、スライダが動いた時に何をどう動かすのか、この指示を全て自前で用意してやらなければならないのです。 例えば、スクロールバーで絵を動かすように改造したい場合は、絵を動かす関数を作り、スライダが動くたびに実行するものとして setChangeHandler でこの処理関数を登録しなければ、せっかくのスクロールバーもただの飾りになってしまいます。 (#1の補足で、スクロールバーが動作しなかった理由は、これです) このあたりが、ActionScript やコンポーネントのことがある程度分かっていないと説明が難しい点で、限られた紙面で説明しなければならないヘルプが、”初心者お断り”の薄情な記述になっている所以でもあります。 ここで回答できることは限られていますし、文章を読むより図で見た方が分かりやすい事柄もあります。 回答した以上、内容に対しての責任は持ちますが、ネット上で、しかも文字だけのやりとりでは、1から手取り足取りはお教えできません。 特に今回は”初心者お断り”レベルの話ですので、#1で、基本は省略するとお断りさせていただきました。厳しいようですけれど、Flash の描画機能や ActionScript の基本事項は、解説書や解説サイトなどをご参照ください。 いろいろ調べたり、数値を変えるなどの改造をして、どんなことが起きるか、なぜそういう現象になるのかを考えてみてください。いきなり正解だけを得るだけが勉強ではなく、失敗から得られる知識や技術も多いです。 (ちなみに私は、画像がどこかに行ってしまったり、逆方向に動いたり、範囲の指定と画像のサイズが上手く対応しなくてズレたりと、お間抜けな失敗ばかり繰り返して、ようやくスクロールバーの仕組みが理解できました ^^; 失敗も大切な経験です)
補足
ありがとうございます。 教えた頂いた内容で試行錯誤しながら、何とか自分の力で結果をと思っていましたが、MX UI コンポネントのHelpが全て英語表記でチンプンカンプンです。(今日、7.2にアップデートしました。) ちゃんと表示する事も出来ましたし、スクロールも出来ました。ただ、最初はムービーの左端から表示されているのですが、一旦スクロールバーを操作すると一番左の画像が半分切れた所でスクロールバーが左端いっぱいに来てしまって表示されません。その文、右に空白が表現されてしまいます。 100x100の画像を5枚横に繋げてムービーシンボルとして作成。(横500のムービーを作成) 横300x縦100のマスクを作成。 中心点は、全て左端になっていると思います。最初は正しく表示され、スクロールも一応正しく動作します。 ただ、最初に表示された左端に戻らないと言う事です。 どうぞ宜しくお願い致します。
- DPE
- ベストアンサー率85% (666/776)
一応、ScrollBar コンポーネントを流用してそれらしいものは作れましたが、少々難しいので、気合いを入れて(笑)お読みください。 作り方を1から説明するとここでは書ききれませんし、スレが長くなると、後からご覧になる方にも迷惑になります。 申し訳ありませんが、ここではスクロールバーの処理を中心に話を進め、基本事項や画像処理の説明はヒントのご紹介程度に限らせていただきます。マスクの利用方法・ムービークリップの座標・クリックされた時の処理・画像の読み込みなどは、市販の解説書や解説サイト・付属のサンプル等で研究してください。 サムネイルの表示部分は、次のように考えます。 スクロールバーで複数の画像を1つずつ動かすのは大変です。そこで、ムービークリップの親子階層を利用して、画像のムービークリップを並べた1つの大きなムービークリップを用意し、スクロールバーではこちらを動かすことにします。 仮に、動かすムービークリップを sheet という名前とします。 マスクを利用して、sheet の一部分だけを表示します。スクロールバーの動きに合わせて sheet を移動すると、マスクと重なっている部分だけが表示され、スクロールしているように見えます。sheet の子になっている画像は、親である sheet と連動して動きます。 ScrollBar コンポーネントは、マスクして表示する部分と同じ長さにします。横のスクロールバーですから、Horizontal パラメータは true にします。 ScrollBar コンポーネントを制御するには FScrollBar オブジェクトを使います。 今回使うのは、次の3つのメソッドです。 ・setChangeHandler スライダが移動した時に呼び出される関数を登録します。 ・getScrollPosition スライダの位置を取得します。 ・setScrollProperties 1ページに表示できる量と、スライダの移動範囲を指定します。 getScrollPosition でスライダの位置を取得し、それを元に sheet のX座標を決める関数を作ります。この関数を setChangeHandler で登録しておくと、スライダが動くたびに呼び出され、スライダの動きに合わせて sheet がスクロールして見えるという仕組みです。 スクロールバーの肝となるポイントが、スライダの移動範囲を決める setScrollProperties です。 setScrollProperties に渡す引数は3つです。 ・第1引数:1ページあたりの表示量 ・第2引数:スライダの移動最小値 ・第3引数:スライダの移動最大値 第1引数はスライダの大きさに関係します。大きくするほどスライドできる距離が短くなり、従って1回あたりのドラッグでスクロールされる量が多くなります。使い勝手のいい程度に調節してください。 第2引数はスライダの移動最小値、つまり、スライダが左端にある時の位置情報です。0にした方が考えやすいでしょう。 問題は第3引数、スライダが右端にある時の位置情報です。 この値は、sheet の大きさとマスク(表示されて見える部分)の大きさなどから決めます。 例えば、sheet の中心点が左端にあり、横が 600px、マスクの幅が 100px 、sheet の _x が最初は0になっている(親座標の X = 0 の地点に配置されている)とします。 マスクの幅が 100px ということは、スライダが右端にある時に表示される部分は、sheet の右端 100px だけということになります。sheet の中心点は左端になっていますから、スライダが右端にある時は sheet を -500px に移動させるように数値を設定すればいいわけです。 つまり、スライダの位置を0~500 までの間で返すようにスクロールバーを設定すると、sheet の移動の処理にスライダの位置がそのまま利用できます。ただし、sheet の動きはスクロールバーと逆方向になりますから、スライダの位置に -1 を乗算して符号を反転します。 スクロールバーのインスタンス名を sc_bar とすると、スクリプトは大体次のようになります。 (↓このスクリプトをコピーして使う場合は、各行頭の全角のスペースを、全て半角のスペースかタブに置き換えてください) //スクロールの処理 function Sheet_Scrolling() { //スライダの位置から座標を決める sheet._x = sc_bar.getScrollPosition()*(-1); } //スクロールバーの設定 sc_bar.setScrollProperties( 100 , 0 , 500 ); //スライダが動いた時に呼ぶ関数を設定 sc_bar.setChangeHandler( "Sheet_Scrolling" ); スクロールバーの考え方は比率です。例えば、setScrollProperties の引数をそれぞれ 1/10 にし、sheet の移動量を 10 倍にしても、同じ動きになります。 getScrollPosition で返ってくる値や setScrollProperties で決定する範囲自体が、実際の座標値や表示する文字数などの意味を持っているのではありません。ただ、指定された長さのトラックにおいて、スライダの位置がここである、というだけの情報にすぎないのです。 この情報をいかにしてスクロール処理に活かすかが、腕の見せ所というわけです。最初から座標に対応できるように範囲を設定(ただし、スライダの移動最小値は0未満にはできません)してもいいですし、範囲を小さくして、対象の移動処理の方で工夫しても構いません。 sheet の位置を決める _x プロパティは、sheet の中心点の座標です。sheet の中心点が左端以外にある場合や、初期配置が親座標の原点以外の場合は、スライダの位置をそのまま sheet の位置には利用できません。sheet の座標を求める過程で、補正値を加減するなどの工夫が必要です。 図形・空間的なセンスが必要ではありますが、計算は算数レベルです。図を書いたり、大きな紙と小さな紙などを使ってシミュレーションしながら、考えてみてください。 ヒントは、スライダが左右の端にある時、sheet の中心点の座標がいくつになっていればいいのかを考えることです。スライダが左端にある時は、必ず位置情報が0で返ってくることから考え始めると、分かりやすいかと思います。分からない時は、trace アクションで sheet やスライダの位置を表示しながら試してみてください。 スクロール処理については、まずは、マスクの大きさやスクロール対象の大きさを 100px や 500px などの分かりやすい大きさにしたり、親座標の原点に配置すると座標が0になる点を利用するなどして、簡単な試作品から作ってみることをオススメします。 スクロールバーの仕組みを理解してから、画像を並べたり、拡大表示の処理を入れていくといいと思いますよ。 Flash のムービークリップは、制限なく大きくできるわけではありません。多くの画像を横1列に並べようとすると、端が切れてしまう可能性もあります。 横のスクロールバーの原理が分かれば、縦のスクロールバーへも応用できるかと思います。縦・横のスクロールバーがあるサムネイル画面にも、ぜひチャレンジしてみてください。 画像の処理は、loadMovie などで外部から読み込むか、画像をムービークリップにして最初から内部に置いておくかで方法が変わります。 ムービークリップにしてあれば、読み込みは最初の1回で済みます。拡大は、MovieClip.duplicateMovieClip で複製するか、MovieClip.attachMovie で動的に挿入するなどの方法が考えられます。 また、簡単にできる方法として、予め、拡大表示用として、1フレームごとに画像を配置したムービークリップを作っておき、クリックされたサムネイルに対応するフレームを表示するというのも、1つの手です。 画像を外部から読み込んだ場合は、duplicateMovieClip が正常に動作しません。拡大表示する時は、対応する画像を改めて読み込み直すか、あるいは、サムネイルのムービークリップを拡大・移動して使いまわすかになると思います。 ヘルプの記述も、この説明で理解できないレベルの人は手を出すなと言わんばかりの薄情さで、目が@@になりましたが、こちらもいい勉強になりました。 頑張ってください。
補足
DPEさん、 本当に気合を入れて取りかかります。(笑) でも、やはり何度かキャッチボールをさせて頂かないと理解出来そうにありません。(すみません) ・マスクの使い方について レイヤー1に縦横100Pixcelのムービークリップを5枚並べ更にそれを一つのムービークリップにする。 レイヤー2に縦100Pixcel,横300Pixcelの矩形を作成し、アルファ値0%し透明にする。(ムービーに変換) レイヤー3にScrollBarコンポネントを配置しTargetをレイヤー2の矩形にする。 とりあえず、この時点でパブリッシュして確認しましたが、ScrollBarは動作しません。 何か間違いを犯しておりますでしょうか?。 申し訳ありません。Step by Stepでお願い致します。
お礼
ありがとうございます。 思い通りの所にムービークリップを配置し、正しくスクロールする事が出来ました。 また、各個別ムービークリップを押下する事により拡大表示すると言う当初の目的を達成する事が出来ました。