5 効果の適用
このチュートリアルでは、視覚効果を使用してJavaFXアプリケーションの外観を向上させる方法について説明します。
効果はすべてjavafx.scene.effect
パッケージ内にあり、これらはEffect
クラスのサブクラスです。特定のクラス、メソッドまたは追加機能の詳細は、APIドキュメントを参照してください。
ブレンド効果
ブレンドは、事前定義されたブレンド・モードの1つを使用して2つの入力を組み合せる効果です。
ノード・ブレンド(node.setBlendMode()
)の場合、これら2つの入力は次のとおりです。
-
レンダリング対象のノード(上部入力)
-
このノードの下にあるものすべて(下部入力)
下部入力の決定は、次のルールに基づいています。
-
同じグループ内の下位のZ順序の兄弟がすべて含まれます。
-
グループ内にブレンド・モードが定義されている場合、プロセスが停止され、下部入力が定義されます。
-
グループ内にデフォルトのブレンド・モードがある場合、グループの下にあるものすべてが含まれ、これと同じルールが再帰的に使用されます。
-
プロセスが再帰的にルート・ノードに戻る場合、シーンの背景ペイントが含まれます。
注意:
通常は不透明な色であるシーンの背景ペイントが下部入力に含まれる場合、SRC_ATOP
モードにより、完全に不透明な下部ソースでレンダリングが行われ、効果は作成されません。この場合、SRC_ATOP
はSRC_OVER
と等価です。
ブレンド・モードでは、オブジェクトを混合する方法を定義します。たとえば、図5-1では、四角形とグループ化された円に適用するブレンド・モードのいくつかの例を確認できます。
例5-1に、同じアプリケーションでのブレンド効果のコード・スニペットを示します。
例5-1 ブレンド効果
static Node blendMode() { Rectangle r = new Rectangle(); r.setX(590); r.setY(50); r.setWidth(50); r.setHeight(50); r.setFill(Color.BLUE); Circle c = new Circle(); c.setFill(Color.RED); c.setCenterX(590); c.setCenterY(50); c.setRadius(25); c.setBlendMode(BlendMode.SRC_ATOP); Group g = new Group(); g.setBlendMode(BlendMode.SRC_OVER); g.getChildren().add(r); g.getChildren().add(c); return g; }
ブルーム効果
ブルーム効果では、構成されているしきい値に基づいて、イメージが光って見える輝度の高い部分を作成します。しきい値の範囲は0.0から1.0までです。デフォルトでは、しきい値は0.3に設定されています。
図5-2に、デフォルトのしきい値とのしきい値1.0のブルーム効果を示します。
例5-2に、ブルーム効果を使用しているサンプル・アプリケーションのコード・スニペットを示します。
例5-2 ブルームの例
static Node bloom() { Group g = new Group(); Rectangle r = new Rectangle(); r.setX(10); r.setY(10); r.setWidth(160); r.setHeight(80); r.setFill(Color.DARKBLUE); Text t = new Text(); t.setText("Bloom!"); t.setFill(Color.YELLOW); t.setFont(Font.font("null", FontWeight.BOLD, 36)); t.setX(25); t.setY(65); g.setCache(true); //g.setEffect(new Bloom()); Bloom bloom = new Bloom(); bloom.setThreshold(1.0); g.setEffect(bloom); g.getChildren().add(r); g.getChildren().add(t); g.setTranslateX(350); return g; }
ぼかし効果
ぼかしは、選択したオブジェクトに対するフォーカスをより集中するために使用される一般的な効果です。JavaFXでは、ボックスぼかし、モーションぼかし、またはガウスぼかしを適用できます。
ボックスぼかし
ボックスぼかしは、簡単なボックス・フィルタ・カーネルを使用するぼかし効果です。この場合、オブジェクトに適用されるぼかしの割合を制御する、両方向に個別に構成可能なサイズと、生成されたぼかしの品質を制御するIterations
パラメータを使用します。
図5-3に、ぼかしを適用したテキストのサンプルを2つ示します。
例5-3は、ボックスぼかし効果を使用したコード・スニペットです。
例5-3 ボックスぼかしの例
static Node boxBlur() { Text t = new Text(); t.setText("Blurry Text!"); t.setFill(Color.RED); t.setFont(Font.font("null", FontWeight.BOLD, 36)); t.setX(10); t.setY(40); BoxBlur bb = new BoxBlur(); bb.setWidth(5); bb.setHeight(5); bb.setIterations(3); t.setEffect(bb); t.setTranslateX(300); t.setTranslateY(100); return t; }
モーションぼかし
モーションぼかし効果では、移動するオブジェクトの効果を作成するために構成可能な半径と角度を使用して、ガウスぼかしを使用します。
図5-4に、テキストに対するモーションぼかしの効果を示します。
例5-4に、サンプル・アプリケーションで半径を15、および角度を45に設定してモーションぼかし効果を作成するコード・スニペットを示します。
例5-4 モーションぼかしの例
static Node motionBlur() { Text t = new Text(); t.setX(20.0f); t.setY(80.0f); t.setText("Motion Blur"); t.setFill(Color.RED); t.setFont(Font.font("null", FontWeight.BOLD, 60)); MotionBlur mb = new MotionBlur(); mb.setRadius(15.0f); mb.setAngle(45.0f); t.setEffect(mb); t.setTranslateX(300); t.setTranslateY(150); return t; }
ドロップ・シャドウ効果
ドロップ・シャドウは、適用対象のコンテンツにシャドウをレンダリングする効果です。シャドウの色、半径、オフセットおよび他のパラメータを指定できます。
図5-6に、様々なオブジェクトに対するシャドウ効果を示します。
例5-6に、テキストと円に対してドロップ・シャドウを作成する方法を示します。
例5-6 シャドウが適用されたテキストと円
import javafx.collections.ObservableList; import javafx.application.Application; import javafx.scene.*; import javafx.stage.*; import javafx.scene.shape.*; import javafx.scene.effect.*; import javafx.scene.paint.*; import javafx.scene.text.*; public class HelloEffects extends Application { Stage stage; Scene scene; @Override public void start(Stage stage) { stage.show(); scene = new Scene(new Group(), 840, 680); ObservableList<Node> content = ((Group)scene.getRoot()).getChildren(); content.add(dropShadow()); stage.setScene(scene); } static Node dropShadow() { Group g = new Group(); DropShadow ds = new DropShadow(); ds.setOffsetY(3.0); ds.setOffsetX(3.0); ds.setColor(Color.GRAY); Text t = new Text(); t.setEffect(ds); t.setCache(true); t.setX(20.0f); t.setY(70.0f); t.setFill(Color.RED); t.setText("JavaFX drop shadow effect"); t.setFont(Font.font("null", FontWeight.BOLD, 32)); DropShadow ds1 = new DropShadow(); ds1.setOffsetY(4.0f); ds1.setOffsetX(4.0f); ds1.setColor(Color.CORAL); Circle c = new Circle(); c.setEffect(ds1); c.setCenterX(50.0f); c.setCenterY(325.0f); c.setRadius(30.0f); c.setFill(Color.RED); c.setCache(true); g.getChildren().add(t); g.getChildren().add(c); return g; } public static void main(String[] args) { Application.launch(args); } }
ヒント:
-
ドロップ・シャドウの幅を広くしすぎると、要素の外観が重くなります。シャドウの色は現実的なものにする必要があります。通常は、背景色より若干明るくします。
-
ドロップ・シャドウを適用するオブジェクトが複数ある場合は、すべてのオブジェクトに対して同じドロップ・シャドウを適用します。ドロップ・シャドウにより、1方向から光が差し込んでオブジェクトの影が生じた外観が実現されます。
インナー・シャドウ効果
インナー・シャドウは、指定した色、半径およびオフセットで特定のコンテンツの端の内側にシャドウをレンダリングする効果です。
図5-7に、プレーン・テキストと、インナー・シャドウ効果が適用された同じテキストを示します。
例5-7に、テキストに対してインナー・シャドウを作成する方法を示します。
例5-7 インナー・シャドウ
static Node innerShadow() { InnerShadow is = new InnerShadow(); is.setOffsetX(2.0f); is.setOffsetY(2.0f); Text t = new Text(); t.setEffect(is); t.setX(20); t.setY(100); t.setText("Inner Shadow"); t.setFill(Color.RED); t.setFont(Font.font("null", FontWeight.BOLD, 80)); t.setTranslateX(300); t.setTranslateY(300); return t; }
リフレクション
リフレクションは、実際のオブジェクトの下にオブジェクトのリフレクション・バージョンをレンダリングする効果です。
注意:
リフレクション効果が適用されたノードのリフレクションは、ノード上のマウス・イベントまたは包含メソッドには反応しません。
図5-8に、テキストに適用されたリフレクションを示します。表示可能なリフレクションの値を指定するには、setFraction
メソッドを使用します。
例5-8に、テキストに対してリフレクション効果を作成する方法を示します。
例5-8 リフレクションが適用されたテキスト
import javafx.scene.text.*; import javafx.scene.paint.*; import javafx.scene.effect.*; public class HelloEffects extends Application { Stage stage; Scene scene; @Override public void start(Stage stage) { stage.show(); scene = new Scene(new Group(), 840, 680); ObservableList<Node> content = ((Group)scene.getRoot()).getChildren(); content.add(reflection()); stage.setScene(scene); } static Node reflection() { Text t = new Text(); t.setX(10.0f); t.setY(50.0f); t.setCache(true); t.setText("Reflection in JavaFX..."); t.setFill(Color.RED); t.setFont(Font.font("null", FontWeight.BOLD, 30)); Reflection r = new Reflection(); r.setFraction(0.9); t.setEffect(r); t.setTranslateY(400); return t; } public static void main(String[] args) { Application.launch(args); } }
ライティング効果
ライティング効果では、特定のコンテンツを照らす光源をシミュレートします。これにより、平坦なオブジェクトにより現実的な3次元の外観を与えることができます。
図5-9に、テキストに対するライティング効果を示します。
例5-9に、テキストに対してライティング効果を作成する方法を示します。
例5-9 ライティング効果が適用されたテキスト
import javafx.application.Application; import javafx.collections.ObservableList; import javafx.geometry.VPos; import javafx.scene.effect.Light.Distant; import javafx.scene.*; import javafx.stage.*; import javafx.scene.shape.*; import javafx.scene.effect.*; import javafx.scene.paint.*; import javafx.scene.text.*; public class HelloEffects extends Application { Stage stage; Scene scene; @Override public void start(Stage stage) { stage.show(); scene = new Scene(new Group()); ObservableList<Node> content = ((Group)scene.getRoot()).getChildren(); content.add(lighting()); stage.setScene(scene); } static Node lighting() { Distant light = new Distant(); light.setAzimuth(-135.0f); Lighting l = new Lighting(); l.setLight(light); l.setSurfaceScale(5.0f); Text t = new Text(); t.setText("JavaFX"+"\n"+"Lighting!"); t.setFill(Color.RED); t.setFont(Font.font("null", FontWeight.BOLD, 70)); t.setX(10.0f); t.setY(10.0f); t.setTextOrigin(VPos.TOP); t.setEffect(l); t.setTranslateX(0); t.setTranslateY(320); return t; } public static void main(String[] args) { Application.launch(args); } }
パースペクティブ効果
パースペクティブ効果では、2次元のオブジェクトで3次元の効果を作成します。
図5-10に、パースペクティブ効果を示します。
パースペクティブ変換により、線の直線性を保持しながら任意の四角形を別の四角形にマップできます。アフィン変換とは異なり、出力においてソース内の線の平行度は必ずしも保持されるとはかぎりません。
注意:
この効果では、入力イベントやノード上の包含を測定するメソッドの座標は調整されません。ノードにパースペクティブ効果を適用する場合、マウスのクリックおよび包含メソッドは定義されません。
例5-10に、パースペクティブ効果を作成する方法を示すサンプル・アプリケーションのコード・スニペットを示します。
例5-10 パースペクティブ効果
static Node perspective() { Group g = new Group(); PerspectiveTransform pt = new PerspectiveTransform(); pt.setUlx(10.0f); pt.setUly(10.0f); pt.setUrx(210.0f); pt.setUry(40.0f); pt.setLrx(210.0f); pt.setLry(60.0f); pt.setLlx(10.0f); pt.setLly(90.0f); g.setEffect(pt); g.setCache(true); Rectangle r = new Rectangle(); r.setX(10.0f); r.setY(10.0f); r.setWidth(280.0f); r.setHeight(80.0f); r.setFill(Color.DARKBLUE); Text t = new Text(); t.setX(20.0f); t.setY(65.0f); t.setText("Perspective"); t.setFill(Color.RED); t.setFont(Font.font("null", FontWeight.BOLD, 36)); g.getChildren().add(r); g.getChildren().add(t); return g; }
図5-11に、生成されるイメージにどの座標が影響しているかを示します。
効果の連鎖の作成
一部の効果には、効果の連鎖を作成するために使用できる入力プロパティがあります。効果の連鎖は、ツリーのような構造である場合があります。これは、2つの入力がある効果や、入力のない効果があるからです。
図5-12では、リフレクション効果をドロップ・シャドウ効果の入力として使用しています。つまり、最初にリフレクション効果によって四角形をリフレクトしてから、その結果にドロップ・シャドウ効果を適用しています。
例5-11 シャドウとリフレクションが順に適用された四角形
import javafx.application.Application; import javafx.collections.ObservableList; import javafx.scene.*; import javafx.stage.*; import javafx.scene.shape.*; import javafx.scene.effect.*; import javafx.scene.paint.*; import javafx.scene.text.*; public class HelloEffects extends Application { Stage stage; Scene scene; @Override public void start(Stage stage) { stage.show(); scene = new Scene(new Group()); ObservableList<Node> content = ((Group)scene.getRoot()).getChildren(); content.add(chainEffects()); stage.setScene(scene); } static Node chainEffects() { Rectangle rect = new Rectangle(); rect.setFill(Color.RED); rect.setWidth(200); rect.setHeight(100); rect.setX(20.0f); rect.setY(20.0f); DropShadow ds = new DropShadow(); ds.setOffsetY(5.0); ds.setOffsetX(5.0); ds.setColor(Color.GRAY); Reflection reflection = new Reflection(); ds.setInput(reflection); rect.setEffect(ds); return rect; } public static void main(String[] args) { Application.launch(args); } }
注意:
chainEffects()
メソッド内の最後の2行をreflection.setInput(ds);
およびrect.setEffect(reflection);
に変更すると、最初に四角形にドロップ・シャドウ効果を適用してから、その結果がリフレクション効果によってリフレクトされます。
特定のクラス、メソッドまたは追加機能の詳細は、APIドキュメントを参照してください。