JavaFX中的動畫可以分為時間軸動畫和過渡。
時間軸和過渡是javafx.animation.Animation類的子類。
JavaFX中的過渡提供了將動畫合并到內(nèi)部時間軸中的方法。JavaFX有內(nèi)置的過渡動畫,這是方便的類來執(zhí)行常見的動畫效果。這里是一些最常見的動畫過渡類
FadeTransition中定義的淡入淡出過渡目標(biāo)是節(jié)點的不透明屬性,用于淡入淡出的動畫效果。
PathTransition中定義的路徑過渡使節(jié)點能夠跟隨生成的路徑。
ScaleTransition中定義的縮放過渡定位節(jié)點的scaleX,scaleY和scaleZ屬性以調(diào)整節(jié)點大小。
TranslateTransition中定義的翻譯過渡定位了節(jié)點的translateX,translateY和translateZ屬性,以便在屏幕上移動節(jié)點。
import javafx.animation.FadeTransition; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { Group group = new Group(); Rectangle rect = new Rectangle(20,20,200,200); FadeTransition ft = new FadeTransition(Duration.millis(5000), rect); ft.setFromValue(1.0); ft.setToValue(0.0); ft.play(); group.getChildren().add(rect); Scene scene = new Scene(group, 300, 200); primaryStage.setScene(scene); primaryStage.show(); } }
上面的代碼生成以下結(jié)果。
import javafx.animation.FillTransition; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.effect.DropShadow; import javafx.scene.paint.Color; import javafx.scene.shape.Ellipse; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle(""); Group root = new Group(); Scene scene = new Scene(root, 300, 250, Color.WHITE); Group g = new Group(); DropShadow ds = new DropShadow(); ds.setOffsetY(3.0); ds.setColor(Color.color(0.4, 0.4, 0.4)); Ellipse ellipse = new Ellipse(); ellipse.setCenterX(50.0f); ellipse.setCenterY(50.0f); ellipse.setRadiusX(50.0f); ellipse.setRadiusY(25.0f); ellipse.setEffect(ds); FillTransition ft = new FillTransition(Duration.millis(3000), ellipse, Color.RED, Color.BLUE); ft.setAutoReverse(true); ft.play(); g.getChildren().add(ellipse); root.getChildren().add(g); primaryStage.setScene(scene); primaryStage.show(); } }
上面的代碼生成以下結(jié)果。
路徑過渡在一個給定時間內(nèi)沿著從一端到另一端的路徑移動節(jié)點。
/* * Copyright (c) 2011, Pro JavaFX Authors * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of JFXtras nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Metronome1Main.fx - A simple example of animation using a Timeline * * Developed 2011 by James L. Weaver jim.weaver [at] javafxpert.com * as a JavaFX SDK 2.0 example for the Pro JavaFX book. */ //package projavafx.metronomepathtransition.ui; import javafx.animation.Animation; import javafx.animation.Interpolator; import javafx.animation.PathTransition; import javafx.animation.PathTransition.OrientationType; import javafx.animation.PathTransitionBuilder; import javafx.animation.Timeline; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.GroupBuilder; import javafx.scene.Scene; import javafx.scene.SceneBuilder; import javafx.scene.control.Button; import javafx.scene.control.ButtonBuilder; import javafx.scene.layout.HBoxBuilder; import javafx.scene.paint.Color; import javafx.scene.shape.ArcToBuilder; import javafx.scene.shape.Ellipse; import javafx.scene.shape.EllipseBuilder; import javafx.scene.shape.MoveTo; import javafx.scene.shape.Path; import javafx.scene.shape.PathBuilder; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { Button startButton; Button pauseButton; Button resumeButton; Button stopButton; Ellipse ellipse = EllipseBuilder.create() .centerX(100) .centerY(50) .radiusX(4) .radiusY(8) .fill(Color.BLUE) .build(); Path path = PathBuilder.create() .elements( new MoveTo(100, 50), ArcToBuilder.create() .x(300) .y(50) .radiusX(350) .radiusY(350) .sweepFlag(true) .build() ) .build(); PathTransition anim = PathTransitionBuilder.create() .duration(new Duration(1000.0)) .node(ellipse) .path(path) .orientation(OrientationType.ORTHOGONAL_TO_TANGENT) .interpolator(Interpolator.LINEAR) .autoReverse(true) .cycleCount(Timeline.INDEFINITE) .build(); public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) { Scene scene = SceneBuilder.create() .width(400) .height(500) .root( GroupBuilder.create() .children( ellipse, HBoxBuilder.create() .layoutX(60) .layoutY(420) .spacing(10) .children( startButton = ButtonBuilder.create() .text("Start") .onAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { anim.playFromStart(); } }) .build(), pauseButton = ButtonBuilder.create() .text("Pause") .onAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { anim.pause(); } }) .build(), resumeButton = ButtonBuilder.create() .text("Resume") .onAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { anim.play(); } }) .build(), stopButton = ButtonBuilder.create() .text("Stop") .onAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent e) { anim.stop(); } }) .build() ) .build() ) .build() ) .build(); startButton.disableProperty().bind(anim.statusProperty() .isNotEqualTo(Animation.Status.STOPPED)); pauseButton.disableProperty().bind(anim.statusProperty() .isNotEqualTo(Animation.Status.RUNNING)); resumeButton.disableProperty().bind(anim.statusProperty() .isNotEqualTo(Animation.Status.PAUSED)); stopButton.disableProperty().bind(anim.statusProperty() .isEqualTo(Animation.Status.STOPPED)); stage.setScene(scene); stage.setTitle("Metronome using PathTransition"); stage.show(); } }
上面的代碼生成以下結(jié)果。
import javafx.animation.PathTransition; import javafx.animation.Timeline; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.CubicCurveTo; import javafx.scene.shape.MoveTo; import javafx.scene.shape.Path; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { @Override public void start(final Stage stage) throws Exception { final Group group = new Group(); final Scene scene = new Scene(group, 600, 400, Color.GHOSTWHITE); stage.setScene(scene); stage.setTitle("JavaFX 2 Animations"); stage.show(); final Circle circle = new Circle(20, 20, 15); circle.setFill(Color.DARKRED); final Path path = new Path(); path.getElements().add(new MoveTo(20, 20)); path.getElements().add(new CubicCurveTo(30, 10, 380, 120, 200, 120)); path.getElements().add(new CubicCurveTo(200, 1120, 110, 240, 380, 240)); path.setOpacity(0.5); group.getChildren().add(path); group.getChildren().add(circle); final PathTransition pathTransition = new PathTransition(); pathTransition.setDuration(Duration.seconds(8.0)); pathTransition.setDelay(Duration.seconds(.5)); pathTransition.setPath(path); pathTransition.setNode(circle); pathTransition .setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT); pathTransition.setCycleCount(Timeline.INDEFINITE); pathTransition.setAutoReverse(true); pathTransition.play(); } public static void main(final String[] arguments) { Application.launch(arguments); } }
上面的代碼生成以下結(jié)果。
并行過渡同時執(zhí)行多個過渡。
/* * Copyright (c) 2011, Pro JavaFX Authors * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of JFXtras nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Metronome1Main.fx - A simple example of animation using a Timeline * * Developed 2011 by James L. Weaver jim.weaver [at] javafxpert.com * as a JavaFX SDK 2.0 example for the Pro JavaFX book. */ import javafx.animation.FadeTransition; import javafx.animation.ParallelTransition; import javafx.animation.RotateTransition; import javafx.animation.ScaleTransition; import javafx.animation.Timeline; import javafx.animation.TranslateTransition; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { Group group = new Group(); Rectangle rectParallel = new Rectangle(20, 20, 200, 200); FadeTransition fadeTransition = new FadeTransition(Duration.millis(3000), rectParallel); fadeTransition.setFromValue(1.0f); fadeTransition.setToValue(0.3f); fadeTransition.setCycleCount(2); fadeTransition.setAutoReverse(true); TranslateTransition translateTransition = new TranslateTransition( Duration.millis(2000), rectParallel); translateTransition.setFromX(50); translateTransition.setToX(350); translateTransition.setCycleCount(2); translateTransition.setAutoReverse(true); RotateTransition rotateTransition = new RotateTransition( Duration.millis(3000), rectParallel); rotateTransition.setByAngle(180f); rotateTransition.setCycleCount(4); rotateTransition.setAutoReverse(true); ScaleTransition scaleTransition = new ScaleTransition( Duration.millis(2000), rectParallel); scaleTransition.setToX(2f); scaleTransition.setToY(2f); scaleTransition.setCycleCount(2); scaleTransition.setAutoReverse(true); ParallelTransition parallelTransition = new ParallelTransition(); parallelTransition.getChildren().addAll(fadeTransition, translateTransition, rotateTransition, scaleTransition); parallelTransition.setCycleCount(Timeline.INDEFINITE); parallelTransition.play(); group.getChildren().add(rectParallel); Scene scene = new Scene(group, 300, 200); primaryStage.setScene(scene); primaryStage.show(); } }
上面的代碼生成以下結(jié)果。
順序過渡一個接一個地執(zhí)行多個過渡。
/* * Copyright (c) 2011, Pro JavaFX Authors * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of JFXtras nor the names of its contributors may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * Metronome1Main.fx - A simple example of animation using a Timeline * * Developed 2011 by James L. Weaver jim.weaver [at] javafxpert.com * as a JavaFX SDK 2.0 example for the Pro JavaFX book. */ import javafx.animation.FadeTransition; import javafx.animation.RotateTransition; import javafx.animation.ScaleTransition; import javafx.animation.SequentialTransition; import javafx.animation.Timeline; import javafx.animation.TranslateTransition; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage primaryStage) { Group group = new Group(); Rectangle rectSeq = new Rectangle(20, 20, 200, 200); FadeTransition fadeTransition = new FadeTransition(Duration.millis(1000), rectSeq); fadeTransition.setFromValue(1.0f); fadeTransition.setToValue(0.3f); fadeTransition.setCycleCount(1); fadeTransition.setAutoReverse(true); TranslateTransition translateTransition = new TranslateTransition( Duration.millis(2000), rectSeq); translateTransition.setFromX(50); translateTransition.setToX(375); translateTransition.setCycleCount(1); translateTransition.setAutoReverse(true); RotateTransition rotateTransition = new RotateTransition( Duration.millis(2000), rectSeq); rotateTransition.setByAngle(180f); rotateTransition.setCycleCount(4); rotateTransition.setAutoReverse(true); ScaleTransition scaleTransition = new ScaleTransition( Duration.millis(2000), rectSeq); scaleTransition.setFromX(1); scaleTransition.setFromY(1); scaleTransition.setToX(2); scaleTransition.setToY(2); scaleTransition.setCycleCount(1); scaleTransition.setAutoReverse(true); SequentialTransition sequentialTransition = new SequentialTransition(); sequentialTransition.getChildren().addAll(fadeTransition, translateTransition, rotateTransition, scaleTransition); sequentialTransition.setCycleCount(Timeline.INDEFINITE); sequentialTransition.setAutoReverse(true); sequentialTransition.play(); group.getChildren().add(rectSeq); Scene scene = new Scene(group, 300, 200); primaryStage.setScene(scene); primaryStage.show(); } }
上面的代碼生成以下結(jié)果。
import javafx.animation.FadeTransition; import javafx.animation.PauseTransition; import javafx.animation.RotateTransition; import javafx.animation.ScaleTransition; import javafx.animation.SequentialTransition; import javafx.animation.TranslateTransition; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { @Override public void start(Stage stage) { Group root = new Group(); Scene scene = new Scene(root, 600, 400); stage.setScene(scene); stage.setTitle(""); Rectangle rect = new Rectangle(100, 40, 100, 100); rect.setArcHeight(50); rect.setArcWidth(50); rect.setFill(Color.VIOLET); PauseTransition pt = new PauseTransition(Duration.millis(1000)); FadeTransition ft = new FadeTransition(Duration.millis(2000)); ft.setFromValue(1.0f); ft.setToValue(0.3f); ft.setAutoReverse(true); TranslateTransition tt = new TranslateTransition(Duration.millis(2000)); tt.setFromX(-100f); tt.setToX(100f); tt.setAutoReverse(true); RotateTransition rt = new RotateTransition(Duration.millis(2000)); rt.setByAngle(180f); rt.setAutoReverse(true); ScaleTransition st = new ScaleTransition(Duration.millis(2000)); st.setByX(1.5f); st.setByY(1.5f); st.setAutoReverse(true); SequentialTransition seqT = new SequentialTransition(rect, pt, ft, tt, rt, st); seqT.play(); root.getChildren().add(rect); stage.show(); } public static void main(String[] args) { launch(args); } }
上面的代碼生成以下結(jié)果。
import javafx.animation.Animation; import javafx.animation.Transition; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.util.Duration; public class Main extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { Scene scene = new Scene(new Group()); stage.setTitle("Sample"); stage.setWidth(300); stage.setHeight(190); VBox vbox = new VBox(); vbox.setLayoutX(20); vbox.setLayoutY(20); final String content = "Lorem ipsum"; final Text text = new Text(10, 20, ""); final Animation animation = new Transition() { { setCycleDuration(Duration.millis(2000)); } protected void interpolate(double frac) { final int length = content.length(); final int n = Math.round(length * (float) frac); text.setText(content.substring(0, n)); } }; animation.play(); vbox.getChildren().add(text); vbox.setSpacing(10); ((Group) scene.getRoot()).getChildren().add(vbox); stage.setScene(scene); stage.show(); } }
上面的代碼生成以下結(jié)果。
更多建議: