hongjli
2025-04-08 8ef173c7d836c382f9c33d299c5c8e52f6447530
src/components/SupplyChainAIMindMap.tsx
@@ -14,6 +14,14 @@
export default function SupplyChainAIMindMap() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const nodesRef = useRef<Node[]>([
    { x: 0.15, y: 0.3, label: '采购', color: '#6ADBFF', icon: '📦' },
    { x: 0.35, y: 0.3, label: '生产', color: '#5E72EB', icon: '🏭' },
    { x: 0.65, y: 0.3, label: '配送', color: '#FF6A88', icon: '🚚' },
    { x: 0.85, y: 0.3, label: '客户', color: '#FF9D6A', icon: '👥' },
    { x: 0.85, y: 0.6, label: '需求预测', color: '#FF6A88', icon: '📊' },
    { x: 0.5, y: 0.5, label: '智能分析引擎', color: '#5E72EB', isAI: true },
  ]);
  
  useEffect(() => {
    const canvas = canvasRef.current;
@@ -88,17 +96,22 @@
        targetY: endY,
        size: Math.random() * 2 + 1,
        color: path.color,
        speed: 0.5 + Math.random() * 1,
        speed: 0.5 + Math.random() * 0.5, // 降低速度
        energy: 1,
        phase: Math.random() * Math.PI * 2,
        orbitRadius: Math.random() * 20 + 10,
        orbitSpeed: (Math.random() * 0.1 + 0.05) * (Math.random() < 0.5 ? 1 : -1),
        orbitRadius: Math.random() * 15 + 5, // 减小轨道半径
        orbitSpeed: (Math.random() * 0.08 + 0.03) * (Math.random() < 0.5 ? 1 : -1), // 降低轨道速度
        pathIndex,
        lifespan: 0,
        maxLifespan: 150 + Math.random() * 100
        maxLifespan: 150 + Math.random() * 50 // 减少最大寿命
      };
      
      particles.push(particle);
      // 限制粒子总数,防止性能问题
      if (particles.length > 30) {
        particles.shift();
      }
    };
    
    // 更新量子粒子
@@ -152,10 +165,18 @@
    
    // 绘制场景
    const drawScene = () => {
      if (!ctx) return;
      // 清除画布
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      
      // 绘制科技感背景
      drawTechBackground();
      // 减少重复计算,预先计算常用值
      const canvasWidth = canvas.width;
      const canvasHeight = canvas.height;
      const time = Date.now() * 0.001;
      // 绘制技术背景
      drawTechBackground(ctx, canvasWidth, canvasHeight, time);
      
      // 绘制能量场路径
      drawEnergyFields();
@@ -165,46 +186,52 @@
      
      // 绘制量子粒子
      drawQuantumParticles();
      // 绘制AI节点
      const aiNode = nodesRef.current.find(node => node.isAI);
      if (aiNode) {
        drawAINode(aiNode.x * canvasWidth, aiNode.y * canvasHeight);
      }
    };
    
    // 绘制科技感背景
    const drawTechBackground = () => {
    const drawTechBackground = (ctx: CanvasRenderingContext2D, canvasWidth: number, canvasHeight: number, time: number) => {
      const gridSize = 40;
      const time = Date.now() * 0.001;
      
      // 绘制动态网格
      // 降低网格密度,仅绘制较少的线条
      ctx.strokeStyle = 'rgba(70, 130, 180, 0.05)';
      ctx.lineWidth = 0.5;
      
      for (let y = 0; y < canvas.height; y += gridSize) {
      // 降低网格线频率
      for (let y = 0; y < canvasHeight; y += gridSize * 1.5) {
        ctx.beginPath();
        ctx.moveTo(0, y);
        ctx.lineTo(canvas.width, y);
        ctx.lineTo(canvasWidth, y);
        ctx.stroke();
        
        // 添加波动效果
        // 对波动效果采样率降低
        ctx.beginPath();
        for (let x = 0; x < canvas.width; x += 5) {
          const wave = Math.sin(x * 0.02 + time + y * 0.01) * 2;
        for (let x = 0; x < canvasWidth; x += 10) {
          const wave = Math.sin(x * 0.01 + time + y * 0.005) * 2;
          ctx.lineTo(x, y + wave);
        }
        ctx.strokeStyle = 'rgba(70, 130, 180, 0.02)';
        ctx.stroke();
      }
      
      for (let x = 0; x < canvas.width; x += gridSize) {
      for (let x = 0; x < canvasWidth; x += gridSize * 1.5) {
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, canvas.height);
        ctx.lineTo(x, canvasHeight);
        ctx.strokeStyle = 'rgba(70, 130, 180, 0.05)';
        ctx.stroke();
      }
      
      // 添加随机光点
      for (let i = 0; i < 15; i++) {
        const x = Math.random() * canvas.width;
        const y = Math.random() * canvas.height;
        const size = 2 + Math.sin(time * 2 + i) * 1;
      // 减少光点数量
      for (let i = 0; i < 10; i++) {
        const x = Math.random() * canvasWidth;
        const y = Math.random() * canvasHeight;
        const size = 2 + Math.sin(time * 1.5 + i) * 1;
        
        const gradient = ctx.createRadialGradient(x, y, 0, x, y, size * 2);
        gradient.addColorStop(0, 'rgba(106, 219, 255, 0.2)');
@@ -277,16 +304,8 @@
    
    // 绘制节点
    const drawNodes = () => {
      // 节点配置
      const nodes: Node[] = [
        { x: 0.15, y: 0.3, label: '采购', color: '#6ADBFF', icon: '📦' },
        { x: 0.35, y: 0.3, label: '生产', color: '#5E72EB', icon: '🏭' },
        { x: 0.65, y: 0.3, label: '配送', color: '#FF6A88', icon: '🚚' },
        { x: 0.85, y: 0.3, label: '客户', color: '#FF9D6A', icon: '👥' },
        { x: 0.85, y: 0.6, label: '需求预测', color: '#FF6A88', icon: '📊' },
        { x: 0.5, y: 0.5, label: '智能分析引擎', color: '#5E72EB', isAI: true },
      ];
      // 使用引用中的节点数据
      const nodes = nodesRef.current;
      const time = Date.now() * 0.001;
      
      nodes.forEach(node => {
@@ -546,33 +565,53 @@
      });
    };
    
    // 初始化粒子系统
    // 初始化粒子
    const initParticles = () => {
      for (let i = 0; i < 40; i++) {
      // 减少初始粒子数量
      for (let i = 0; i < 20; i++) {
        setTimeout(() => createQuantumParticle(), i * 100);
      }
    };
    
    // 定期添加新粒子
    // 定期添加新粒子,降低频率
    const particleInterval = setInterval(() => {
      if (particles.length < 50) {
      if (particles.length < 30) {
        createQuantumParticle();
      }
    }, 500);
    }, 800);
    
    // 动画循环
    const animate = () => {
    let lastTime = 0;
    const targetFPS = 30; // 降低目标FPS以提高性能
    const frameInterval = 1000 / targetFPS;
    const animate = (timestamp = 0) => {
      const animationId = requestAnimationFrame(animate);
      // 限制帧率以提高性能
      const deltaTime = timestamp - lastTime;
      if (deltaTime < frameInterval) {
        return animationId;
      }
      // 记录当前时间
      lastTime = timestamp - (deltaTime % frameInterval);
      // 更新和绘制
      updateParticles();
      drawScene();
      requestAnimationFrame(animate);
      return animationId;
    };
    
    initParticles();
    animate();
    const animationId = animate();
    
    return () => {
      window.removeEventListener('resize', setCanvasSize);
      clearInterval(particleInterval);
      // 清理动画帧
      cancelAnimationFrame(animationId);
    };
  }, []);