Я решил запустить простой анимированный образец JavaFX 2, когда посетители вошли в комнату для моей презентации RMOUG Training Days 2012 . Желаемый результат был достигнут, когда участники спросили, было ли реализовано работающее приложение. Несколько человек были удивлены тем, что это было реализовано в «чистой Java» без Flash или HTML5. Я предоставляю исходный код для этого простого примера вместе с некоторыми снимками экрана в этом посте. Попутно этот пример демонстрирует анимацию нескольких экземпляров Text вдоль пути одновременно.
Ранее я писал в блоге об анимации по заданному пути с помощью PathTransition . Я адаптировал этот пример к этому новому примеру, изменив движущуюся фигуру с круга на текстовую «фигуру» и сделав так, чтобы три из этих «фигур» двигались по траектории одновременно через ParallelTransition .
Чтобы добавить немного больше к демонстрации, в этом примере я также использовал эффекты JavaFX , размер шрифта и спецификацию, а также раскраску символов. Список кодов для всего простого демонстрационного примера показан ниже.
RmougTd2012Animation.java
package dustin.examples; import javafx.animation.ParallelTransition; import javafx.animation.PathTransition; import javafx.animation.PathTransition.OrientationType; import javafx.animation.Timeline; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.effect.Glow; import javafx.scene.effect.Reflection; import javafx.scene.paint.Color; import javafx.scene.shape.CubicCurveTo; import javafx.scene.shape.MoveTo; import javafx.scene.shape.Path; import javafx.scene.shape.Shape; import javafx.scene.text.Font; import javafx.scene.text.Text; import javafx.scene.text.TextBuilder; import javafx.stage.Stage; import javafx.util.Duration; /** * Simple animation of labels related to RMOUG Training Days 2012 using JavaFX. * * @author Dustin */ public class RmougTd2012Animation extends Application { /** * Generate Path upon which animation will occur. * * @return Generated path. */ private Path generateCurvyPath() { final Path path = new Path(); path.getElements().add(new MoveTo(70,20)); path.getElements().add(new CubicCurveTo(430, 0, 430, 120, 250, 120)); path.getElements().add(new CubicCurveTo(50, 120, 50, 240, 430, 240)); path.setOpacity(0.0); return path; } /** * Generate the path transition. * * @param shape Shape to travel along path. * @param path Path to be traveled upon. * @param duration Duration of single animation. * @param delay Delay before beginning first animation. * @param orientation Orientation of shape during animation. * @return PathTransition. */ private PathTransition generatePathTransition( final Shape shape, final Path path, final Duration duration, final Duration delay, final OrientationType orientation) { final PathTransition pathTransition = new PathTransition(); pathTransition.setDuration(duration); pathTransition.setDelay(delay); pathTransition.setPath(path); pathTransition.setNode(shape); pathTransition.setOrientation(orientation); pathTransition.setCycleCount(Timeline.INDEFINITE); pathTransition.setAutoReverse(true); return pathTransition; } /** * Generate RMOUG text string with appropriate fill, font, and effect. * * @return "RMOUG" text string with fill, font, and effect. */ private Text generateRmougText() { return TextBuilder.create().text("RMOUG").x(20).y(20).fill(Color.DARKGRAY) .font(Font.font(java.awt.Font.SERIF, 75)) .effect(new Glow(0.25)).build(); } /** * Generate "Training Days 2012" text string with appropriate position, fill, * and font. * * @return "Training Days 2012" with specified font, fill, and position. */ private Text generateTrainingDaysText() { return TextBuilder.create().text("Training Days 2012") .x(380).y(240).fill(Color.DARKOLIVEGREEN) .font(Font.font(java.awt.Font.SERIF, 50)).build(); } /** * Location String with specifed effect, font, and position. * * @return Location String with specified effect, font, and position. */ private Text generateDenverText() { final Reflection reflection = new Reflection(); reflection.setFraction(1.0); return TextBuilder.create() .text("Denver, Colorado").x(20).y(20) .font(Font.font(java.awt.Font.SANS_SERIF, 25)) .effect(reflection) .build(); } /** * Apply animation. * * @param group Group to which animation is to be applied. */ private void applyAnimation(final Group group) { final Path path = generateCurvyPath(); group.getChildren().add(path); final Shape rmoug = generateRmougText(); group.getChildren().add(rmoug); final Shape td = generateTrainingDaysText(); group.getChildren().add(td); final Shape denver = generateDenverText(); group.getChildren().add(denver); final PathTransition rmougTransition = generatePathTransition( rmoug, path, Duration.seconds(8.0), Duration.seconds(0.5), OrientationType.NONE); final PathTransition tdTransition = generatePathTransition( td, path, Duration.seconds(5.5), Duration.seconds(0.1), OrientationType.NONE); final PathTransition denverTransition = generatePathTransition( denver, path, Duration.seconds(30), Duration.seconds(3), OrientationType.ORTHOGONAL_TO_TANGENT); final ParallelTransition parallelTransition = new ParallelTransition(rmougTransition, tdTransition, denverTransition); parallelTransition.play(); } /** * JavaFX Application starting method. * * @param stage Primary stage. * @throws Exception Potential JavaFX application exception. */ @Override public void start(Stage stage) throws Exception { final Group rootGroup = new Group(); final Scene scene = new Scene(rootGroup, 500, 400, Color.GHOSTWHITE); stage.setScene(scene); stage.setTitle("JavaFX 2 RMOUG Training Days 2012 Animations"); stage.show(); applyAnimation(rootGroup); } /** * Main function for running JavaFX animation demo. * * @param arguments Command-line arguments; none expected. */ public static void main(final String[] arguments) { Application.launch(arguments); } }
Следующая серия снимков экрана пытается дать представление о том, как это выглядит при его выполнении.
Этот пример демонстрирует, что текст может быть анимирован вдоль пути, а также демонстрирует разницу между типами OrientationType NONE и ORTHOGONAL_TO_TANGENT . Первая спецификация ориентации имеет текст, обращенный вверх с абсолютистской точки зрения, в то время как последняя смещает направление текста в соответствии с поворотами пути. Javadoc для каждого типа обеспечивает более точное объяснение, где NONE определяется как «Матрица вращения целевого узла остается неизменной вдоль геометрического пути», тогда как ORTHOGONAL_TO_TANGENT определяется как «Матрица вращения целевого узла устанавливается так, чтобы держать узел перпендикулярно касательной к траектории пути вдоль геометрический путь. «
Для меня более интересной частью этого примера является то, как легко задать несколько анимаций, которые будут выполняться параллельно. Как показывает метод applyAnimation примера кода, три текстовых строки связаны с тремя различными экземплярами PathTransition . Хотя каждый из этих трех экземпляров PathTransition использует один и тот же путь , время начала и продолжительность каждого перехода различаются. Ни один из экземпляров PathTransition не имеет своих отдельных методов play (). Скорее, каждый связан с одним ParallelTransitionэкземпляр, и это тот метод play () экземпляра ParallelTransition, который вызывается. Поскольку три экземпляра PathTransition были связаны с экземпляром ParallelTransition, вызов функции play () для него вызывает play () для всех трех отдельных экземпляров PathTransition параллельно.
Вывод
JavaFX 2 позволяет легко выполнять несколько переходов параллельно. Один просто устанавливает каждый отдельный переход предпочтительным образом, а затем связывает каждый из этих переходов с экземпляром ParallelTransition и вызывает метод play () для этого экземпляра ParallelTransition. Анимация не ограничивается фигурами, но может использоваться и для текста.
От http://marxsoftware.blogspot.com/2012/02/javafx-2-simrallelous-animated-text.html