具有动态背景 JavaFX 的霜玻璃效果
Frost Glass Effect with dynamic Background JavaFX
我正在开发 JavaFX 应用程序:
在这里,我希望左窗格具有模糊背景效果,即每当用户滚动地图时,左窗格后面的内容都会发生变化,我想使用该内容(模糊),如左窗格的背景。 & 我快完成了。
每当我滚动地图时,它都会工作,后面的内容也会更新,但在系统监视器中我可以看到 CPU 使用情况、温度和整体功耗急剧上升。
为了实现霜玻璃效果,我在 webEngine(包含地图)中添加了一个事件监听器(用于检测鼠标移动):
Document doc = webEngine.getDocument();
((EventTarget) doc).addEventListener("mousemove", listener, false);
侦听器执行一个方法:
检索左窗格(地图)下方的实际内容。
模糊图像。
更新屏幕
为了更新屏幕,该方法删除了左窗格 (VBox) 和上一张图像(它是背景)。 & 然后再次首先添加模糊图像窗格,然后将左窗格添加到根窗格。
所以,我认为我遇到性能问题的原因是,当用户拖动地图.
Problem : Very High CPU Usage
那么,JavaFX 中是否还有其他方法不需要如此高的 CPU 使用率?
类似的东西,不需要一直删除和添加窗格。
在 HBox 中创建两个窗格,将地图相关部分的视图渲染到每个窗格中。在左窗格中设置模糊效果。不需要侦听器、快照或动态添加或删除窗格。
如果需要,尝试使用不同设置的几种不同模糊效果(有 BoxBlur 和 GuassianBlur)以调整性能特征。
setting the Blur effect directly on the left Pane, blur's everything (Button text), and as i've set Transparency effect, this setup only blur's the left Pane,
对左侧窗格使用堆栈窗格,左侧地图部分位于堆栈底部(应用了模糊效果),透明叠加层位于堆栈顶部(未应用任何效果)。
Is there a way , i can blur a part of a pane, so the part lying under the left Pane could be selected & blurred?
是的,您使用的技术类似于:
- How to implement a transparent Pane with non-transparent children?
- Frosted Glass Effect in JavaFX?
样本
这是一个快速示例,只是作为概念证明,显然对于您的解决方案,您需要稍微不同的东西。
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
/**
* Constructs a scene with a pannable Map background.
*/
public class FrostedPannableView extends Application {
private Image backgroundImage;
private static final double W = 800;
private static final double H = 600;
@Override
public void init() {
backgroundImage = new Image("http://www.narniaweb.com/wp-content/uploads/2009/08/NarniaMap.jpg");
}
@Override
public void start(Stage stage) {
stage.setTitle("Drag the mouse to pan the map");
stage.setResizable(false);
// make a transparent pale blue overlay with non transparent blue writing on it.
final Label label = new Label("Map\nof\nNarnia");
label.setTextAlignment(TextAlignment.CENTER);
label.setStyle("-fx-text-fill: midnightblue; -fx-font: bold italic 40 'serif'; -fx-padding: 0 0 20 0;");
StackPane glass = new StackPane();
StackPane.setAlignment(label, Pos.BOTTOM_CENTER);
glass.getChildren().addAll(label);
glass.setStyle("-fx-background-color: rgba(0, 100, 100, 0.5);");
glass.setMaxWidth(W * 1/4);
glass.setMaxHeight(H);
StackPane.setAlignment(glass, Pos.CENTER_LEFT);
// construct a partitioned node with left side blurred.
ImageView leftMap = new ImageView(backgroundImage);
ImageView rightMap = new ImageView(backgroundImage);
// wrap the partitioned node in a pannable scroll pane.
ScrollPane leftScroll = createScrollPane(leftMap);
Rectangle leftClip = new Rectangle(W * 1/4, H);
leftScroll.setClip(leftClip);
leftScroll.setEffect(new GaussianBlur());
ScrollPane rightScroll = createScrollPane(rightMap);
Rectangle rightClip = new Rectangle(W * 1/4, 0, W * 3/4, H);
rightScroll.setClip(rightClip);
StackPane composite = new StackPane();
composite.getChildren().setAll(
leftScroll,
rightScroll
);
StackPane layout = new StackPane(
composite,
glass
);
// show the scene.
Scene scene = new Scene(layout);
stage.setScene(scene);
stage.show();
// bind the scroll values together and center the scroll contents.
leftScroll.hvalueProperty().bind(rightScroll.hvalueProperty());
leftScroll.vvalueProperty().bind(rightScroll.vvalueProperty());
rightScroll.setHvalue(rightScroll.getHmin() + (rightScroll.getHmax() - rightScroll.getHmin()) / 2);
rightScroll.setVvalue(rightScroll.getVmin() + (rightScroll.getVmax() - rightScroll.getVmin()) / 2);
}
/**
* @return a ScrollPane which scrolls the node.
*/
private ScrollPane createScrollPane(Node node) {
ScrollPane scroll = new ScrollPane();
scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroll.setPannable(true);
scroll.setMinSize(ScrollPane.USE_PREF_SIZE, ScrollPane.USE_PREF_SIZE);
scroll.setPrefSize(W, H);
scroll.setMaxSize(ScrollPane.USE_PREF_SIZE, ScrollPane.USE_PREF_SIZE);
scroll.setContent(node);
return scroll;
}
public static void main(String[] args) {
launch(args);
}
}
我正在开发 JavaFX 应用程序:
在这里,我希望左窗格具有模糊背景效果,即每当用户滚动地图时,左窗格后面的内容都会发生变化,我想使用该内容(模糊),如左窗格的背景。 & 我快完成了。
每当我滚动地图时,它都会工作,后面的内容也会更新,但在系统监视器中我可以看到 CPU 使用情况、温度和整体功耗急剧上升。
为了实现霜玻璃效果,我在 webEngine(包含地图)中添加了一个事件监听器(用于检测鼠标移动):
Document doc = webEngine.getDocument();
((EventTarget) doc).addEventListener("mousemove", listener, false);
侦听器执行一个方法:
检索左窗格(地图)下方的实际内容。
模糊图像。
更新屏幕
为了更新屏幕,该方法删除了左窗格 (VBox) 和上一张图像(它是背景)。 & 然后再次首先添加模糊图像窗格,然后将左窗格添加到根窗格。
所以,我认为我遇到性能问题的原因是,当用户拖动地图.
Problem : Very High CPU Usage
那么,JavaFX 中是否还有其他方法不需要如此高的 CPU 使用率?
类似的东西,不需要一直删除和添加窗格。
在 HBox 中创建两个窗格,将地图相关部分的视图渲染到每个窗格中。在左窗格中设置模糊效果。不需要侦听器、快照或动态添加或删除窗格。
如果需要,尝试使用不同设置的几种不同模糊效果(有 BoxBlur 和 GuassianBlur)以调整性能特征。
setting the Blur effect directly on the left Pane, blur's everything (Button text), and as i've set Transparency effect, this setup only blur's the left Pane,
对左侧窗格使用堆栈窗格,左侧地图部分位于堆栈底部(应用了模糊效果),透明叠加层位于堆栈顶部(未应用任何效果)。
Is there a way , i can blur a part of a pane, so the part lying under the left Pane could be selected & blurred?
是的,您使用的技术类似于:
- How to implement a transparent Pane with non-transparent children?
- Frosted Glass Effect in JavaFX?
样本
这是一个快速示例,只是作为概念证明,显然对于您的解决方案,您需要稍微不同的东西。
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
/**
* Constructs a scene with a pannable Map background.
*/
public class FrostedPannableView extends Application {
private Image backgroundImage;
private static final double W = 800;
private static final double H = 600;
@Override
public void init() {
backgroundImage = new Image("http://www.narniaweb.com/wp-content/uploads/2009/08/NarniaMap.jpg");
}
@Override
public void start(Stage stage) {
stage.setTitle("Drag the mouse to pan the map");
stage.setResizable(false);
// make a transparent pale blue overlay with non transparent blue writing on it.
final Label label = new Label("Map\nof\nNarnia");
label.setTextAlignment(TextAlignment.CENTER);
label.setStyle("-fx-text-fill: midnightblue; -fx-font: bold italic 40 'serif'; -fx-padding: 0 0 20 0;");
StackPane glass = new StackPane();
StackPane.setAlignment(label, Pos.BOTTOM_CENTER);
glass.getChildren().addAll(label);
glass.setStyle("-fx-background-color: rgba(0, 100, 100, 0.5);");
glass.setMaxWidth(W * 1/4);
glass.setMaxHeight(H);
StackPane.setAlignment(glass, Pos.CENTER_LEFT);
// construct a partitioned node with left side blurred.
ImageView leftMap = new ImageView(backgroundImage);
ImageView rightMap = new ImageView(backgroundImage);
// wrap the partitioned node in a pannable scroll pane.
ScrollPane leftScroll = createScrollPane(leftMap);
Rectangle leftClip = new Rectangle(W * 1/4, H);
leftScroll.setClip(leftClip);
leftScroll.setEffect(new GaussianBlur());
ScrollPane rightScroll = createScrollPane(rightMap);
Rectangle rightClip = new Rectangle(W * 1/4, 0, W * 3/4, H);
rightScroll.setClip(rightClip);
StackPane composite = new StackPane();
composite.getChildren().setAll(
leftScroll,
rightScroll
);
StackPane layout = new StackPane(
composite,
glass
);
// show the scene.
Scene scene = new Scene(layout);
stage.setScene(scene);
stage.show();
// bind the scroll values together and center the scroll contents.
leftScroll.hvalueProperty().bind(rightScroll.hvalueProperty());
leftScroll.vvalueProperty().bind(rightScroll.vvalueProperty());
rightScroll.setHvalue(rightScroll.getHmin() + (rightScroll.getHmax() - rightScroll.getHmin()) / 2);
rightScroll.setVvalue(rightScroll.getVmin() + (rightScroll.getVmax() - rightScroll.getVmin()) / 2);
}
/**
* @return a ScrollPane which scrolls the node.
*/
private ScrollPane createScrollPane(Node node) {
ScrollPane scroll = new ScrollPane();
scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroll.setPannable(true);
scroll.setMinSize(ScrollPane.USE_PREF_SIZE, ScrollPane.USE_PREF_SIZE);
scroll.setPrefSize(W, H);
scroll.setMaxSize(ScrollPane.USE_PREF_SIZE, ScrollPane.USE_PREF_SIZE);
scroll.setContent(node);
return scroll;
}
public static void main(String[] args) {
launch(args);
}
}