javafx - 具有动态背景 JavaFX 的霜玻璃效果

标签 javafx cpu blur effect panes

我正在开发 JavaFX 应用程序:

http://i.stack.imgur.com/Q24i4.png

在这里,我希望左 Pane 具有模糊背景效果,即当用户滚动 map 时,左 Pane 后面的内容会发生变化,我想使用该内容(模糊)作为背景的左 Pane 。 & 我几乎完成了。

每当我滚动 map 时,它确实有效,后面的内容得到更新,但在系统监视器中我可以看到 CPU 使用率、温度和整体功耗急剧上升。

为了实现霜玻璃效果,我向 webEngine(包含 map )添加了一个事件监听器(用于检测鼠标移动):

Document doc = webEngine.getDocument();
((EventTarget) doc).addEventListener("mousemove", listener, false);

监听器执行一个方法:

  1. 检索左 Pane ( map )下的实际内容。

  2. 模糊图像。

  3. 更新屏幕

为了更新屏幕,该方法删除了左 Pane (VBox) 和上一张图像(即背景)。 & 然后再次首先添加模糊图像 Pane ,然后将左 Pane 添加到根 Pane 。

所以,我认为我遇到性能问题的原因是,它必须非常快速地删除 Pane (左 Pane 和背景图像)并将其添加到根 Pane ,同时用户正在拖动 map 。

Problem : Very High CPU Usage

那么,JavaFX 中还有其他方法不需要如此高的 CPU 使用率吗?

类似的东西,不需要一直删除和添加 Pane 。

最佳答案

在 HBox 中创建两个 Pane ,将 map 相关部分的 View 渲染到每个 Pane 中。在左 Pane 中设置模糊效果。不需要监听器、快照或动态添加或删除 Pane 。

如果需要,尝试使用不同设置的几种不同模糊效果(有 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,

对左侧 Pane 使用堆栈 Pane ,左侧 map 部分位于堆栈底部(应用了模糊效果),透明叠加层位于堆栈顶部(未应用任何效果)。

Is there a way , i can blur a part of a pane, so the part lying under the left Pane could be selected & blurred?

是的,您使用的技术类似于:

样本

这是一个快速示例,只是作为概念证明,显然对于您的解决方案,您需要稍微不同的东西。

map

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 - 具有动态背景 JavaFX 的霜玻璃效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34180439/

相关文章:

hardware - 更多的 CPU 缓存是否有助于 Visual Studio 2008 中的编译/开发?

javascript - 使用 GSAP 制作动画模糊滤镜

ios - 圆形 UIVisualEffectView

javascript - jQuery Blur() 或 focusout() 在 Internet Explorer 中未触发

JavaFX 如何保存 TableView 的状态

JavaFX - 使用 CSS 为文本字段设置焦点边框

java - ChoiceBox onShown\onHidden 方法对 JavaFX 不起作用

amazon-ec2 - Amazon EC2 和 Linode 之间的性能差异

Javafx AreaChart效率低——如何让滚动更流畅?

python - 限制 Python 脚本的 RAM 和 CPU 使用