package com.excellent.archimedes.fx.controller;
/**
* @author zhaoyong
* @Date 2024/10/12
* @Description
*/
import com.alibaba.fastjson.JSON;
import com.excellent.archimedes.util.AlertUtils;
import com.excellent.archimedes.util.UIViewContextUtils;
import javafx.animation.*;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Point2D;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.util.Duration;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
@Component
public class SeeCacheController implements Initializable {
/* ===================== 以下为原控件 ===================== */
@FXML private Pane userPane;
@FXML private Button reset;
@FXML private Button returnHomepage;
/* ===================== 新增动画节点 ===================== */
private Canvas animCanvas; // 360°圆环+碎片
private GraphicsContext gc;
private final double RING_RADIUS = 80; // 圆环半径
private final double RING_STROKE = 6; // 圆环粗细
private final int FRAG_COUNT = 12; // 碎片数量
private final List<Fragment> fragments = new ArrayList<>();
@Override
public void initialize(URL location, ResourceBundle resources) {
/* 把 Canvas 放到原 Pane 里,居中 */
animCanvas = new Canvas(300, 300);
userPane.getChildren().add(animCanvas);
animCanvas.setLayoutX(20); // 自己按实际布局微调
animCanvas.setLayoutY(30);
gc = animCanvas.getGraphicsContext2D();
}
/* ===================== 原业务方法不动 ===================== */
@FXML void returnHome(ActionEvent event) { UIViewContextUtils.subStage.close(); }
@FXML void returnToHome(ActionEvent event) { UIViewContextUtils.subStage.hide(); }
@FXML
void checkCache(ActionEvent event) {
try {
String cacheContent = JSON.toJSONString(UIViewContextUtils.subStage.getUserData());
if (StringUtils.isNotBlank(cacheContent) && !cacheContent.equals("null")) {
AlertUtils.alert("查看缓存", cacheContent);
} else {
AlertUtils.alert("查看缓存", "缓存已清空");
}
} catch (Exception e) {
e.printStackTrace();
}
}
/* ===================== 清空缓存 + 360°特效 ===================== */
@FXML
void clearCache(ActionEvent event) {
boolean go = AlertUtils.prompt("要清空缓存", "确定要清空缓存吗?");
if (!go) return;
initFragments(); // 生成 12 片扇形碎片
Timeline master = new Timeline(new KeyFrame(Duration.millis(16), e -> drawFrame())); // 60 fps
master.setCycleCount(Timeline.INDEFINITE);
master.play();
/* 3 秒后结束动画并真正清理 */
PauseTransition end = new PauseTransition(Duration.seconds(3));
end.setOnFinished(e -> {
master.stop();
fragments.clear();
gc.clearRect(0, 0, animCanvas.getWidth(), animCanvas.getHeight());
UIViewContextUtils.thirdSubStage.setUserData(null);
UIViewContextUtils.subStage.setUserData(null);
UIViewContextUtils.primaryStage.setUserData(null);
AlertUtils.alert("清空缓存", "缓存已清空完毕");
});
end.play();
}
/* ===================== 碎片内部类 ===================== */
private static class Fragment {
double startAngle; // 初始角度
double distance; // 当前已飞出距离
double speed; // 每帧飞出速度
double opacity; // 当前透明度
final double MAX_DIST = 120;
Fragment(double angle) {
this.startAngle = angle;
this.distance = 0;
this.speed = 2 + Math.random() * 2;
this.opacity = 1.0;
}
void fly() {
distance += speed;
opacity = Math.max(0, 1 - distance / MAX_DIST);
}
}
private void initFragments() {
fragments.clear();
for (int i = 0; i < FRAG_COUNT; i++) {
fragments.add(new Fragment(i * 360.0 / FRAG_COUNT));
}
}
/* ===================== 每帧绘制 ===================== */
private double ringAngle = 0;
private void drawFrame() {
gc.clearRect(0, 0, animCanvas.getWidth(), animCanvas.getHeight());
double cx = animCanvas.getWidth() / 2;
double cy = animCanvas.getHeight() / 2;
/* 1. 旋转圆环 */
ringAngle += 4;
gc.save();
gc.translate(cx, cy);
gc.rotate(ringAngle);
gc.setStroke(Color.rgb(30, 144, 255));
gc.setLineWidth(RING_STROKE);
gc.strokeOval(-RING_RADIUS, -RING_RADIUS, RING_RADIUS * 2, RING_RADIUS * 2);
/* 画 60 条刻度 */
for (int i = 0; i < 60; i++) {
double a = Math.toRadians(i * 6);
double len = (i % 5 == 0) ? 10 : 5;
gc.strokeLine(RING_RADIUS - len, 0, RING_RADIUS, 0);
gc.rotate(6);
}
gc.restore();
/* 2. 碎片向外飞 */
gc.setFill(Color.ORANGE);
fragments.removeIf(f -> f.opacity <= 0);
for (Fragment f : fragments) {
double rad = Math.toRadians(f.startAngle);
Point2D p = new Point2D(
cx + Math.cos(rad) * (RING_RADIUS * 0.7 + f.distance),
cy + Math.sin(rad) * (RING_RADIUS * 0.7 + f.distance));
gc.setGlobalAlpha(f.opacity);
gc.fillOval(p.getX() - 4, p.getY() - 4, 8, 8);
f.fly();
}
gc.setGlobalAlpha(1.0);
}
}