JavaFX台风动画

本文分享了一个使用JavaFX制作的台风路径动画,通过动态调整路径上的点和图标位置,实现了台风移动的视觉效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工作需要,写了一个台风动画,分享一下,请勿用于商业用途。

/**
 * Author:ZhangHao
 * Date:15:11 2018/11/20
 * Title:
 */

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.ArrayList;
import java.util.List;

public class Typhoon11 extends Application {
    private Pane root = new Pane();
    private List<Double[]> pointXAndY = getPointXAndY();
    private Circle[] circleArray = new Circle[pointXAndY.size()];
    private Line[] lineArray = new Line[pointXAndY.size() - 1];
    private ImageView imageView = new ImageView(new Image("typhoon.png"));

    private List<Double[]> getPointXAndY(){
        List<Double[]> pointXAndY = new ArrayList<>();
        pointXAndY.add(new Double[]{100.0,100.0});
        pointXAndY.add(new Double[]{200.0,200.0});
        pointXAndY.add(new Double[]{300.0,300.0});
        pointXAndY.add(new Double[]{400.0,500.0});
        pointXAndY.add(new Double[]{500.0,500.0});
        pointXAndY.add(new Double[]{600.0,600.0});
        return  pointXAndY;
    }

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setResizable(false);
        primaryStage.setScene(new Scene(createContent()));
        primaryStage.show();
    }

    public Parent createContent() {
        root.setPrefSize(1300, 700);

        Path path = new Path();
        path.getElements().add(new MoveTo(pointXAndY.get(0)[0], pointXAndY.get(0)[0]));
        for(int i = 0;i < pointXAndY.size();i++){
            path.getElements().add(new LineTo(pointXAndY.get(i)[0], pointXAndY.get(i)[1]));
        }

        imageView.setFitWidth(60);
        imageView.setFitHeight(60);
        imageView.setX(pointXAndY.get(0)[0]);
        imageView.setY(pointXAndY.get(0)[1]);
        root.getChildren().add(imageView);

        /*RotateTransition rotateTransition = new RotateTransition(Duration.seconds(2), imageView);
        rotateTransition.setFromAngle(0);
        rotateTransition.setToAngle(2*720);
        rotateTransition.setCycleCount(Timeline.INDEFINITE);
        rotateTransition.setAutoReverse(false);
        rotateTransition.play();*/
        // 旋转优化
        Timeline rotateTimeline = new Timeline();
        double timeDuration = Integer.MAX_VALUE;
        rotateTimeline.getKeyFrames().addAll(new KeyFrame(new Duration(0), new KeyValue(imageView.rotateProperty(), 0)), new KeyFrame(new Duration(1000*timeDuration), new KeyValue(imageView.rotateProperty(), 360*timeDuration)));
        rotateTimeline.play();

        for(int i = 0;i < lineArray.length;i++){
            lineArray[i] = new Line(pointXAndY.get(i)[0], pointXAndY.get(i)[1], pointXAndY.get(i)[0], pointXAndY.get(i)[1]);
            lineArray[i].setStroke(Color.rgb(30,144,255));
            lineArray[i].setStrokeWidth(2);
        }

        Timeline timeline = new Timeline();

        for(int i = 0;i < circleArray.length;i++){
            circleArray[i] = new Circle(pointXAndY.get(i)[0], pointXAndY.get(i)[1], 5);
            circleArray[i].setFill(Color.rgb(65,105,225));
        }

        DoubleProperty circleIndexProperty = new SimpleDoubleProperty(-1);
        circleIndexProperty.addListener(this::circleIndexChange);

        for(int i = 0;i < pointXAndY.size() - 1;i++){
            timeline.getKeyFrames().addAll(new KeyFrame(new Duration(1000*i), new KeyValue(imageView.xProperty(), pointXAndY.get(i)[0] - imageView.getFitWidth() / 2)), new KeyFrame(new Duration(1000*(i + 1)), new KeyValue(imageView.xProperty(), pointXAndY.get(i + 1)[0] - imageView.getFitWidth() / 2)));
            timeline.getKeyFrames().addAll(new KeyFrame(new Duration(1000*i), new KeyValue(imageView.yProperty(), pointXAndY.get(i)[1] - imageView.getFitHeight() / 2)), new KeyFrame(new Duration(1000*(i + 1)), new KeyValue(imageView.yProperty(), pointXAndY.get(i + 1)[1] - imageView.getFitHeight() / 2)));
            timeline.getKeyFrames().addAll(new KeyFrame(new Duration(1000*i), new KeyValue(lineArray[i].endXProperty(), pointXAndY.get(i)[0])), new KeyFrame(new Duration(1000*(i + 1)), new KeyValue(lineArray[i].endXProperty(), pointXAndY.get(i + 1)[0])));
            timeline.getKeyFrames().addAll(new KeyFrame(new Duration(1000*i), new KeyValue(lineArray[i].endYProperty(), pointXAndY.get(i)[1])), new KeyFrame(new Duration(1000*(i + 1)), new KeyValue(lineArray[i].endYProperty(), pointXAndY.get(i + 1)[1])));
            timeline.getKeyFrames().addAll(new KeyFrame(new Duration(1000*i), new KeyValue(circleIndexProperty, i)), new KeyFrame(new Duration(1000*(i + 1)), new KeyValue(circleIndexProperty, i + 1)));
        }

        timeline.play();
        return root;
    }

    private void circleIndexChange(ObservableValue<? extends Number> observable, Number oldValue, Number newValue){
        int indexValid = Integer.parseInt(((double)newValue + "").split("\\.")[0]);
        int indexInvalid = Integer.parseInt(((double)oldValue + "").split("\\.")[0]);
        if(indexInvalid == indexValid){
            return;
        }

        if(indexValid < pointXAndY.size() - 1){
            root.getChildren().add(circleArray[indexValid]);
            root.getChildren().add(lineArray[indexValid]);
        }
    }
}

使用的图标typhoon.png来自阿里矢量图标库,搜索台风可选择自己喜欢的图片下载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值