Я решил запустить простой анимированный образец 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



