程序实现思路: 在javafx中Node对象有一个effect属性,可以用于实现各种特效。PerspectiveTransform特效可以使Node对象实现透视变换。因此我们可以通过计算透视变换中每个点的位置来实现3D翻转特效。
实现步骤: 1、定义FlipView对象。包含以下属性:
//正面视图 public Node frontNode; //反面视图 public Node backNode; //是否翻转 boolean flipped = false; //翻转角度 DoubleProperty time = new SimpleDoubleProperty(Math.PI / 2); //正面翻转特效 PerspectiveTransform frontEffect = new PerspectiveTransform(); //反面翻转特效 PerspectiveTransform backEffect = new PerspectiveTransform();
create方法返回需要显示的内容:
private void create() { time.addListener(new ChangeListener() { @Override public void changed(ObservableValue arg0, Number arg1, Number arg2) { setPT(frontEffect, time.get()); setPT(backEffect, time.get()); } }); anim.getKeyFrames().addAll(frame1, frame2); backNode.visibleProperty().bind( Bindings.when(time.lessThan(0)).then(true).otherwise(false)); frontNode.visibleProperty().bind( Bindings.when(time.lessThan(0)).then(false).otherwise(true)); setPT(frontEffect, time.get()); setPT(backEffect, time.get()); frontNode.setEffect(frontEffect); backNode.setEffect(backEffect); getChildren().addAll(backNode, frontNode); }
以上代码需要注意的是: 随着time值的变化frontEffect和backEffect的值也会随着变换。 2、PerspectiveTransform特效的实现使用了Math.sin()和Math.cos()方法模拟3D角度变换。 具体实现如下:
private void setPT(PerspectiveTransform pt, double t) { double width = 200; double height = 200; double radius = width / 2; double back = height / 10; pt.setUlx(radius - Math.sin(t) * radius); pt.setUly(0 - Math.cos(t) * back); pt.setUrx(radius + Math.sin(t) * radius); pt.setUry(0 + Math.cos(t) * back); pt.setLrx(radius + Math.sin(t) * radius); pt.setLry(height - Math.cos(t) * back); pt.setLlx(radius - Math.sin(t) * radius); pt.setLly(height + Math.cos(t) * back); }
3、角度变换在1秒的时间内从3.14/2变换到-3.14/2。
KeyFrame frame1 = new KeyFrame(Duration.ZERO, new KeyValue(time, Math.PI / 2, Interpolator.LINEAR)); KeyFrame frame2 = new KeyFrame(Duration.seconds(1), new EventHandler() { @Override public void handle(ActionEvent event) { flipped = !flipped; } }, new KeyValue(time, -Math.PI / 2, Interpolator.LINEAR));
4、FlipView对象的创建:通过构造函数可以很方便的创建FlipView对象.
ImageView image1 = new ImageView(new Image(getClass() .getResourceAsStream("lion1.png")));ImageView image2 = new ImageView(new Image(getClass() .getResourceAsStream("lion2.png")));FlipView flip = new FlipView(image1, image2);
5、效果图: