加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

JavaFX中的磨砂玻璃效果?

发布时间:2020-12-15 07:38:56 所属栏目:Java 来源:网络整理
导读:我正在制作一个以iOS7为主题的 JavaFX2 / FXML项目,我想知道如何让Rectangle对象具有类似iOS7的磨砂玻璃效果. 我也喜欢它有一个小阴影.这很棘手,因为您可能能够看到半透明对象后面的阴影.我只是希望它出现在边缘. 这可能吗?这是一张显示所需效果的图片(不包
我正在制作一个以iOS7为主题的 JavaFX2 / FXML项目,我想知道如何让Rectangle对象具有类似iOS7的磨砂玻璃效果.

我也喜欢它有一个小阴影.这很棘手,因为您可能能够看到半透明对象后面的阴影.我只是希望它出现在边缘.

这可能吗?这是一张显示所需效果的图片(不包括小阴影):

更新:Here’s问题的延续.这看起来很神奇:D.

解决方法

样品溶液

frost

运行下面的程序并向上滚动或向上滑动以显示玻璃窗格.

该计划的目的只是为了对所涉及的技术进行抽样,而不是充当霜冻效应的通用库.

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.geometry.Rectangle2D;
import javafx.scene.*;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.effect.*;
import javafx.scene.image.*;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

// slides a frost pane in on scroll or swipe up; slides it out on scroll or swipe down.
public class Frosty extends Application {

    private static final double W = 330;
    private static final double H = 590;

    private static final double BLUR_AMOUNT = 60;
    private static final Duration SLIDE_DURATION = Duration.seconds(0.4);

    private static final double UPPER_SLIDE_POSITION = 100;

    private static final Effect frostEffect =
        new BoxBlur(BLUR_AMOUNT,BLUR_AMOUNT,3);

    @Override public void start(Stage stage) {
        DoubleProperty y = new SimpleDoubleProperty(H);

        Node background = createBackground();
        Node frost      = freeze(background,y);
        Node content    = createContent();
        content.setVisible(false);

        Scene scene = new Scene(
                new StackPane(
                        background,frost,content
                )
        );

        stage.setScene(scene);
        stage.show();

        addSlideHandlers(y,content,scene);
    }

    // create a background node to be frozen over.
    private Node createBackground() {
        Image backgroundImage = new Image(
                getClass().getResourceAsStream("ios-screenshot.png")
        );
        ImageView background = new ImageView(backgroundImage);
        Rectangle2D viewport = new Rectangle2D(0,W,H);
        background.setViewport(viewport);

        return background;
    }

    // create some content to be displayed on top of the frozen glass panel.
    private Label createContent() {
        Label label = new Label("The overlaid text is clear and the background below is frosty.");

        label.setStyle("-fx-font-size: 25px; -fx-text-fill: midnightblue;");
        label.setEffect(new Glow());
        label.setMaxWidth(W - 20);
        label.setWrapText(true);

        return label;
    }

    // add handlers to slide the glass panel in and out.
    private void addSlideHandlers(DoubleProperty y,Node content,Scene scene) {
        Timeline slideIn = new Timeline(
                new KeyFrame(
                        SLIDE_DURATION,new KeyValue(
                                y,UPPER_SLIDE_POSITION
                        )
                )
        );

        slideIn.setOnFinished(e -> content.setVisible(true));

        Timeline slideOut = new Timeline(
                new KeyFrame(
                        SLIDE_DURATION,H
                        )
                )
        );

        scene.setOnSwipeUp(e -> {
            slideOut.stop();
            slideIn.play();
        });

        scene.setOnSwipeDown(e -> {
            slideIn.stop();
            slideOut.play();
            content.setVisible(false);
        });

        // scroll handler isn't necessary if you have a touch screen.
        scene.setOnScroll((ScrollEvent e) -> {
            if (e.getDeltaY() < 0) {
                slideOut.stop();
                slideIn.play();
            } else {
                slideIn.stop();
                slideOut.play();
                content.setVisible(false);
            }
        });
    }

    // create a frosty pane from a background node.
    private StackPane freeze(Node background,DoubleProperty y) {
        Image frostImage = background.snapshot(
                new SnapshotParameters(),null
        );
        ImageView frost = new ImageView(frostImage);

        Rectangle filler = new Rectangle(0,H);
        filler.setFill(Color.AZURE);

        Pane frostPane = new Pane(frost);
        frostPane.setEffect(frostEffect);

        StackPane frostView = new StackPane(
                filler,frostPane
        );

        Rectangle clipShape = new Rectangle(0,y.get(),H);
        frostView.setClip(clipShape);

        clipShape.yProperty().bind(y);

        return frostView;
    }

    public static void main(String[] args) { launch(args); }
}

来源图片

将此图像与Java源并行保存为名为ios-screenshot.png的文件,并让构建系统将其复制到目标目录,以获取构建的二进制输出.

ios-screenshot

其他问题的答案

“JDK 8,” would that happen to be a requirement of this?

上面的示例代码是针对JDK 8编写的.通过将lambda调用替换为匿名内部类将其移植回JDK 7非常简单.

一般来说,Java 7对于JavaFX工作来说非常过时.我建议您尽早升级以使用Java 8最低版本.

initiating your Panes with arguments

大多数父节点的更方便的构造函数是Java 8 feature.您可以轻松转换Java 8格式:

StackPane stack = new StackPane(child1,child2);

到Java 7:

StackPane stack = new StackPane();
 stack.getChildren().setAll(child1,child2);

will this working if the desktop is behind a frosty pane?

不是直接的,你可以为此创建一个新问题.

更新:相关问题

用户创建:JavaFX effect on background以允许磨砂效果应用于桌面背景上的窗口.

另一个用户创建:How do I create a JavaFX transparent stage with shadows on only the border?在该窗口周围应用光晕阴影效果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读