You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现JavaFX自定义Shape从Pane中心向外的填充动画

JavaFX实现从Pane中心向外填充通用Shape的动画

我用JavaFX的Path创建了自定义Shape,想要在指定时间内实现从Pane中心向外扩散的填充动画。目前已经实现了矩形从底部填充的简单版本,但这套逻辑没法适配通用Shape,也做不到从中心向外填充的效果。

当前效果:从Shape底部向上填充
目标效果:从Pane中心点向外扩散填充


解决方案思路

原来的平移矩形遮罩只适合线性方向的填充,要实现通用Shape的中心向外填充,改用圆形遮罩缩放动画+裁剪的方案:

  1. 准备两个同形状的图形:一个作为轮廓(透明填充、描边),一个作为填充图形(纯色填充)。
  2. 给填充图形添加圆形遮罩,初始半径极小(仅中心一点),通过动画将遮罩半径放大到能完全覆盖整个Shape的尺寸。
  3. 计算Shape的边界范围,确定遮罩需要的最大半径,确保动画结束时完全覆盖目标Shape。

完整代码示例

package com.example.javafx21;

import javafx.animation.ScaleTransition;
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.LineTo;
import javafx.stage.Stage;
import javafx.util.Duration;

public class HelloApplication extends Application {
    @Override
    public void start(Stage primaryStage) {
        Pane pane = new Pane();
        pane.setPrefSize(300, 300);
        
        // 自定义Path形状(示例:五角星,可替换为任意自定义Shape)
        Path outlineShape = createStarShape(150, 150, 50);
        outlineShape.setStroke(Color.BLACK);
        outlineShape.setFill(Color.TRANSPARENT);

        // 填充用的同形状图形
        Path fillShape = createStarShape(150, 150, 50);
        fillShape.setFill(Color.BLUE);

        // 获取Shape边界,计算遮罩最大半径(中心到最远边界的距离)
        Bounds shapeBounds = outlineShape.getBoundsInParent();
        double centerX = shapeBounds.getCenterX();
        double centerY = shapeBounds.getCenterY();
        double maxRadius = Math.max(
                Math.max(centerX - shapeBounds.getMinX(), shapeBounds.getMaxX() - centerX),
                Math.max(centerY - shapeBounds.getMinY(), shapeBounds.getMaxY() - centerY)
        );

        // 创建圆形遮罩,初始半径为0(仅中心一点)
        Circle mask = new Circle(centerX, centerY, 0);
        mask.setFill(Color.WHITE);
        fillShape.setClip(mask);

        pane.getChildren().addAll(fillShape, outlineShape);

        Button button = new Button("开始填充");
        button.setLayoutX(120);
        button.setLayoutY(250);
        pane.getChildren().add(button);

        // 缩放动画:2秒内将遮罩从中心小点放大到覆盖整个Shape
        ScaleTransition fillTransition = new ScaleTransition(Duration.seconds(2), mask);
        fillTransition.setFromX(0);
        fillTransition.setFromY(0);
        fillTransition.setToX(maxRadius / mask.getRadius());
        fillTransition.setToY(maxRadius / mask.getRadius());
        fillTransition.setCycleCount(1);
        fillTransition.setAutoReverse(false);

        button.setOnAction(e -> fillTransition.play());

        Scene scene = new Scene(pane);
        primaryStage.setTitle("中心向外填充动画");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // 生成五角星Path的工具方法,可替换为自定义Path逻辑
    private Path createStarShape(double centerX, double centerY, double radius) {
        Path path = new Path();
        double angle = Math.PI / 5;
        for (int i = 0; i < 10; i++) {
            double r = (i % 2 == 0) ? radius : radius / 2;
            double x = centerX + r * Math.cos(i * angle - Math.PI / 2);
            double y = centerY + r * Math.sin(i * angle - Math.PI / 2);
            PathElement element = (i == 0) ? new MoveTo(x, y) : new LineTo(x, y);
            path.getElements().add(element);
        }
        path.getElements().add(new LineTo(centerX + radius * Math.cos(-Math.PI / 2), centerY + radius * Math.sin(-Math.PI / 2)));
        return path;
    }

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

代码说明

  • createStarShape方法是示例自定义Shape生成逻辑,你可以直接替换成自己的Path或任意Shape实现。
  • 通过getBoundsInParent()获取Shape的边界范围,计算出中心到最远边缘的距离,确保遮罩放大后能完全覆盖目标Shape。
  • 使用ScaleTransition实现遮罩的平滑缩放,若需要自定义动画曲线(如缓入缓出),可以改用Timeline直接动画Circle的radiusProperty()。

内容的提问来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 12:05:08