モジュール 1 タスク 3: 拡大効果の追加
- 概要
-
javafx.scene.Groupおよびjavafx.scene.shape.Rectangleを使用して、サムネイルをまとめて配置できるようにするpreserveRatioを使用して、画像を拡大/縮小する際に元の縦横比を保持するonMouseEnter()およびonMouseExit()を使用して、拡大/縮小をトリガーする
はじめに
このタスクでは、すべてのサムネイルを同じ比率で倍率変更して、個々のサムネイルにマウスオーバー効果を追加します。図 1 に示すように、カーソルの下のサムネイルは 25% 大きくなります。
図 1
サムネイルへの拡大効果の追加には、2 つの課題があります。
- サムネイルを fitWidth および fitHeight の制約に合わせて倍率変更後に中央に配置する
- 壁のサイズが変わらないように拡大を処理する (サイズが変わると、壁がふたたび中央に配置されて「ジャンプ」します)。
プロジェクトの実行
- モジュール 1 タスク 3: NetBeans プロジェクトをダウンロードします。
- プロジェクトを実行します。
モジュール 1 タスク 2 では、サムネイルはすべて同じサイズでした。タスク 3 では、サムネイルは同じ比率でサイズ変更されます。 - カーソルで壁を横切ります。マウスがサムネイルの上を通過すると、そのサムネイルは拡大されます。マウスが通過し終えると、サムネイルは通常のサイズに縮小されます。
アーキテクチャー
ここでは余分なマウス動作を追加するだけであるため、新しい関数を Thumbnail.fx に追加して Wall.fx を編集します。図 2 を見てわかるように、このプロジェクトに新しいファイルはありません。
図 2
サムネイルのグループの作成
Thumbnail.fx では、画像の縦横比を維持しながら、画像のサイズをサムネイルの寸法に合わせて設定します。拡大効果によってサムネイルの倍率を変更し、マウスの通過時に 25% 拡大して、通過終了時に 100% に戻します。
前のタスクでは、壁の高さはサムネイルの高さ (THUMB_HEIGHT) にサムネイルの行間 (THUMB_VERTICAL_SPACING) と、サムネイルおよびフレーム間のスペースを加えた値でした。ここでは拡大効果によって、一番上の行または一番下の行にあるサムネイルが拡大されたときに、壁全体のサイズが変わります。拡大を考慮しない場合、壁はサイズの変更に伴ってジャンプします。
このタスクでは問題はすでに解決されていますが、開発プロセスの手順を振り返ることは、問題と解決策の両方を理解するよい方法です。手順:
Thumbnail.fxを編集します。- // を使用して、Rectangle を参照する文をコメントアウトします。
- 行 119 - 123:
def boundingRect = Rectangle { ... } - 行 133 および 134:
translateX: bind ... and translateY: bind ... - 行 172:
boundingRect
- 行 119 - 123:
- プロジェクトを実行します。
- 一番上の行または一番下の行にあるサムネイルの上にマウスを移動します。マウスを画像の上に移動すると、壁が「ジャンプ」します。次の図 3 と図 1 を比較します。一番下にある横向きの画像が、どちらも列の中央ではなく右に移動することに注意してください。
図 3
- 手順 2 で作成したコメントを削除します。
境界の矩形の作成
壁の寸法をサムネイルの寸法に基づいて決定するため、拡大効果を考慮する必要があります。次に定義するように、矩形はサムネイル用のコンテナです。EXPANDED_THUMB_SCALE で乗算することにより、壁のサイズが正しくなり、前述の「ジャンプ」が起こらなくなります。
def boundingRect = Rectangle {
width: Constants.THUMB_WIDTH * Constants.EXPANDED_THUMB_SCALE
height: Constants.THUMB_HEIGHT * Constants.EXPANDED_THUMB_SCALE
visible : false
}
boundingRect (またはその他の非表示の矩形) の輪郭を表示することは、便利なデバッグツールとなります。boundingRect の塗りつぶしとストロークを初期化し、可視性を true に設定することにより、輪郭を表示することができます。
fill : null
stroke : javafx.scene.paint.Color.YELLOW
visible : true
サムネイルのサイズ変更と縦横比の維持
矩形にはサムネイルが含まれているため、サムネイルのサイズを縦横比が維持されるように変更し、サムネイルを矩形内の中央に配置する必要があります。
translateX: bind (boundingRect.boundsInLocal.width
- imageView.width) / 2.0
translateY: bind (boundingRect.boundsInLocal.height
-imageView.height) / 2.0
fitWidth: Constants.THUMB_WIDTH
fitHeight: Constants.THUMB_HEIGHT
preserveRatio: true
onMouseEntered および onMouseExited を使用した倍率の変更
Thumbnail.fx には、新しい onMouseEntered 関数と onMouseExited 関数が含まれています。これらの関数は javafx.scene.Node から scaleX と scaleY を継承するため、倍率の変更はオブジェクトの中央から行われます。これが、boundsInLocal の値 (サイズの計算に使用される値) が重要である理由です。
onMouseEntered: function(evt: MouseEvent) : Void {
imageView.scaleX = Constants.EXPANDED_THUMB_SCALE;
imageView.scaleY = Constants.EXPANDED_THUMB_SCALE;
}
// Scale the thumbnail back down for normal display when the mouse exits.
onMouseExited: function(evt: MouseEvent) : Void {
imageView.scaleX = 1;
imageView.scaleY = 1;
倍率の変更は imageView のみに適用されることに注意してください (コードに表示されている Rectangle や、Thumbnail CustomNode には適用されません)。
グループの作成
Thumbnail.fx は、create() 関数で Group を使用します。タスク 2 では ImageView の内部だった反射効果は、ここではグループのコンテンツが整形される前に有効です。Group とは、多数の子を持つシーングラフ内のノードのことです。Group 内の各ノードは 1 つのノードとして処理できます。次のコードでは、Rectangle は Group 内の 1 つのノードで、imageView はもう 1 つのノードです。反射は Group に適用されるため、Group 内のどのノードにも反射効果があります。
Group {
effect: if (reflect) then reflection else null;
content: [
boundingRect,
imageView
]
}
試してみましょう
Photo.fxでは、ルック & フィールの変更を試みます。
- ギャップの値を変更し、間隔全体への影響を観察します。
- フレームの属性を変更します。
- 反射効果を
imageViewに移動します。boundingRectにはどのような変更を行えばよいでしょうか? (ヒント: 反射はimageViewの高さにどのように影響するでしょうか?)
