hongjli
2025-04-08 6590930e7aeb1345539dc571ca8202d4825ec12d
主页优化
已修改1个文件
已添加1个文件
716 ■■■■■ 文件已修改
src/app/page.tsx 69 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/SupplyChainAIMindMap.tsx 647 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/app/page.tsx
@@ -3,6 +3,7 @@
import Link from 'next/link';
import { motion } from 'framer-motion';
import { useEffect, useState } from 'react';
import SupplyChainAIMindMap from '@/components/SupplyChainAIMindMap';
export default function Home() {
  const [mounted, setMounted] = useState(false);
@@ -20,13 +21,13 @@
  };
  
  const fadeInLeft = {
    hidden: { opacity: 0, x: -50 },
    visible: { opacity: 1, x: 0, transition: { duration: 0.7, ease: "easeOut" } }
    hidden: { opacity: 0, x: -100 },
    visible: { opacity: 1, x: 0, transition: { duration: 0.7, ease: [0.25, 0.1, 0.25, 1] } }
  };
  
  const fadeInRight = {
    hidden: { opacity: 0, x: 50 },
    visible: { opacity: 1, x: 0, transition: { duration: 0.7, ease: "easeOut" } }
    hidden: { opacity: 0, x: 100 },
    visible: { opacity: 1, x: 0, transition: { duration: 0.7, ease: [0.25, 0.1, 0.25, 1] } }
  };
  
  const fadeInScale = {
@@ -40,12 +41,48 @@
      <div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-[#1E2B63] to-[#0A1033] z-0"></div>
      
      <div className="max-w-7xl mx-auto py-0">
        {/* é¡µé¢å†…容 */}
        {/* ä¸»è¦å†…容部分 */}
        <div className="relative z-10 min-h-screen pt-32 pb-24">
          {/* æŠ€æœ¯ä¼˜åŠ¿éƒ¨åˆ† */}
          <section className="w-full py-6 relative">
          {/* äº¤äº’按钮组 - é¡¶éƒ¨ */}
          <div className="flex justify-center gap-8 mb-20">
            <motion.button
              initial="hidden"
              whileInView="visible"
              viewport={{ once: false, margin: "-150px" }}
              variants={fadeInLeft}
              whileHover={{ scale: 1.03 }}
              whileTap={{ scale: 0.97 }}
              className="relative px-12 py-3 rounded-lg overflow-hidden group backdrop-blur-sm bg-white/5 border border-[#6ADBFF]/30 hover:border-[#6ADBFF]/50 transition-all duration-300"
            >
              <div className="absolute inset-0 bg-gradient-to-r from-[#6ADBFF]/5 to-[#5E72EB]/5 group-hover:from-[#6ADBFF]/10 group-hover:to-[#5E72EB]/10 transition-all duration-300"></div>
              <div className="relative">
                <span className="text-white font-semibold">AI场景模拟</span>
              </div>
            </motion.button>
            <motion.button
              initial="hidden"
              whileInView="visible"
              viewport={{ once: false, margin: "-150px" }}
              variants={fadeInRight}
              whileHover={{ scale: 1.03 }}
              whileTap={{ scale: 0.97 }}
              className="relative px-12 py-3 rounded-lg overflow-hidden group backdrop-blur-sm bg-white/5 border border-[#FF6A88]/30 hover:border-[#FF6A88]/50 transition-all duration-300"
            >
              <div className="absolute inset-0 bg-gradient-to-r from-[#FF6A88]/5 to-[#5E72EB]/5 group-hover:from-[#FF6A88]/10 group-hover:to-[#5E72EB]/10 transition-all duration-300"></div>
              <div className="relative">
                <span className="text-white font-semibold">开始聊天</span>
              </div>
            </motion.button>
          </div>
          {/* AI赋能APS优势全景 - ç‹¬ç«‹åŒºå— */}
          <section className="w-full py-12 relative mb-24">
            <SupplyChainAIMindMap />
          </section>
          {/* AI赋能APS核心技术优势部分 */}
          <section className="w-full py-16 relative mb-20">
            {/* æ ‡é¢˜ */}
            <motion.div
              initial="hidden"
@@ -61,14 +98,14 @@
              </h2>
              <div className="h-1 w-24 mx-auto bg-gradient-to-r from-[#6ADBFF] to-[#FF6A88]"></div>
            </motion.div>
            {/* æŠ€æœ¯å¡ç‰‡ */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-12">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-12 mt-16">
              {/* å·¦ä¾§ï¼šé‡å­å¯å‘算法 */}
              <motion.div
                initial="hidden"
                whileInView="visible"
                viewport={{ once: false, margin: "-100px" }}
                viewport={{ once: false, margin: "-150px" }}
                variants={fadeInLeft}
                className="relative"
              >
@@ -85,7 +122,7 @@
              <motion.div
                initial="hidden"
                whileInView="visible"
                viewport={{ once: false, margin: "-100px" }}
                viewport={{ once: false, margin: "-150px" }}
                variants={fadeInRight}
                className="relative"
              >
@@ -101,11 +138,11 @@
            
            {/* æ•°å­—指标区域 */}
            <motion.div
              initial={{ opacity: 0, y: 20 }}
              initial={{ opacity: 0, y: 40 }}
              whileInView={{ opacity: 1, y: 0 }}
              viewport={{ once: false, margin: "-100px" }}
              transition={{ duration: 0.8, ease: "easeOut" }}
              className="mt-20 w-full grid grid-cols-2 md:grid-cols-4 gap-8 mb-20"
              viewport={{ once: false, margin: "-150px" }}
              transition={{ duration: 0.7, ease: [0.25, 0.1, 0.25, 1], delay: 0.2 }}
              className="mt-20 w-full grid grid-cols-2 md:grid-cols-4 gap-8"
            >
              <div className="text-center">
                <div className="text-4xl font-bold text-[#6ADBFF] mb-2">98%</div>
src/components/SupplyChainAIMindMap.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,647 @@
"use client";
import { useEffect, useRef } from 'react';
import { motion } from 'framer-motion';
interface Node {
  x: number;
  y: number;
  label: string;
  color: string;
  icon?: string;
  isAI?: boolean;
}
export default function SupplyChainAIMindMap() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;
    const setCanvasSize = () => {
      canvas.width = canvas.offsetWidth;
      canvas.height = canvas.offsetHeight;
    };
    setCanvasSize();
    window.addEventListener('resize', setCanvasSize);
    // é‡å­æ•°æ®ç²’子系统
    interface QuantumParticle {
      x: number;
      y: number;
      targetX: number;
      targetY: number;
      size: number;
      color: string;
      speed: number;
      energy: number;
      phase: number;
      orbitRadius: number;
      orbitSpeed: number;
      pathIndex: number;
      lifespan: number;
      maxLifespan: number;
    }
    interface Point {
      x: number;
      y: number;
    }
    interface Path {
      start: Point;
      end: Point;
      color: string;
      particles: QuantumParticle[];
    }
    const particles: QuantumParticle[] = [];
    // å®šä¹‰æ•°æ®æµè·¯å¾„
    const paths: Path[] = [
      { start: { x: 0.15, y: 0.3 }, end: { x: 0.35, y: 0.3 }, color: '#6ADBFF', particles: [] }, // é‡‡è´­åˆ°ç”Ÿäº§
      { start: { x: 0.35, y: 0.3 }, end: { x: 0.65, y: 0.3 }, color: '#5E72EB', particles: [] }, // ç”Ÿäº§åˆ°é…é€
      { start: { x: 0.65, y: 0.3 }, end: { x: 0.85, y: 0.3 }, color: '#FF6A88', particles: [] }, // é…é€åˆ°å®¢æˆ·
      { start: { x: 0.85, y: 0.3 }, end: { x: 0.85, y: 0.6 }, color: '#FF9D6A', particles: [] }, // å®¢æˆ·åˆ°éœ€æ±‚预测
      { start: { x: 0.85, y: 0.6 }, end: { x: 0.5, y: 0.5 }, color: '#FF6A88', particles: [] },  // éœ€æ±‚预测到AI
      { start: { x: 0.5, y: 0.5 }, end: { x: 0.15, y: 0.3 }, color: '#6ADBFF', particles: [] }   // AI到采购
    ];
    // åˆ›å»ºé‡å­ç²’子
    const createQuantumParticle = () => {
      const pathIndex = Math.floor(Math.random() * paths.length);
      const path = paths[pathIndex];
      const startX = path.start.x * canvas.width;
      const startY = path.start.y * canvas.height;
      const endX = path.end.x * canvas.width;
      const endY = path.end.y * canvas.height;
      const particle: QuantumParticle = {
        x: startX,
        y: startY,
        targetX: endX,
        targetY: endY,
        size: Math.random() * 2 + 1,
        color: path.color,
        speed: 0.5 + Math.random() * 1,
        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),
        pathIndex,
        lifespan: 0,
        maxLifespan: 150 + Math.random() * 100
      };
      particles.push(particle);
    };
    // æ›´æ–°é‡å­ç²’子
    const updateParticles = () => {
      const time = Date.now() * 0.001;
      for (let i = particles.length - 1; i >= 0; i--) {
        const p = particles[i];
        p.lifespan++;
        if (p.lifespan >= p.maxLifespan) {
          particles.splice(i, 1);
          continue;
        }
        // è®¡ç®—到目标的方向和距离
        const dx = p.targetX - p.x;
        const dy = p.targetY - p.y;
        const dist = Math.sqrt(dx * dx + dy * dy);
        if (dist < 5) {
          // åˆ°è¾¾ç›®æ ‡ç‚¹ï¼Œè®¾ç½®æ–°ç›®æ ‡
          const nextPathIndex = (p.pathIndex + 1) % paths.length;
          const nextPath = paths[nextPathIndex];
          p.pathIndex = nextPathIndex;
          p.targetX = nextPath.end.x * canvas.width;
          p.targetY = nextPath.end.y * canvas.height;
          p.phase = Math.random() * Math.PI * 2; // é‡ç½®ç›¸ä½
        }
        // é‡å­è½¨é“运动
        const progress = p.lifespan / p.maxLifespan;
        const orbitAmplitude = Math.sin(progress * Math.PI) * p.orbitRadius;
        const orbitPhase = p.phase + time * p.orbitSpeed;
        // è®¡ç®—主要移动方向
        const moveX = dx / dist * p.speed;
        const moveY = dy / dist * p.speed;
        // æ·»åŠ é‡å­è½¨é“åç§»
        const perpX = -dy / dist;
        const perpY = dx / dist;
        p.x += moveX + perpX * Math.sin(orbitPhase) * orbitAmplitude * 0.1;
        p.y += moveY + perpY * Math.sin(orbitPhase) * orbitAmplitude * 0.1;
        // æ›´æ–°èƒ½é‡å€¼
        p.energy = Math.sin(progress * Math.PI);
      }
    };
    // ç»˜åˆ¶åœºæ™¯
    const drawScene = () => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      // ç»˜åˆ¶ç§‘技感背景
      drawTechBackground();
      // ç»˜åˆ¶èƒ½é‡åœºè·¯å¾„
      drawEnergyFields();
      // ç»˜åˆ¶èŠ‚ç‚¹
      drawNodes();
      // ç»˜åˆ¶é‡å­ç²’子
      drawQuantumParticles();
    };
    // ç»˜åˆ¶ç§‘技感背景
    const drawTechBackground = () => {
      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) {
        ctx.beginPath();
        ctx.moveTo(0, y);
        ctx.lineTo(canvas.width, 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;
          ctx.lineTo(x, y + wave);
        }
        ctx.strokeStyle = 'rgba(70, 130, 180, 0.02)';
        ctx.stroke();
      }
      for (let x = 0; x < canvas.width; x += gridSize) {
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, canvas.height);
        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;
        const gradient = ctx.createRadialGradient(x, y, 0, x, y, size * 2);
        gradient.addColorStop(0, 'rgba(106, 219, 255, 0.2)');
        gradient.addColorStop(1, 'rgba(106, 219, 255, 0)');
        ctx.beginPath();
        ctx.fillStyle = gradient;
        ctx.arc(x, y, size * 2, 0, Math.PI * 2);
        ctx.fill();
      }
    };
    // ç»˜åˆ¶èƒ½é‡åœº
    const drawEnergyFields = () => {
      const time = Date.now() * 0.001;
      paths.forEach((path: Path) => {
        const startX = path.start.x * canvas.width;
        const startY = path.start.y * canvas.height;
        const endX = path.end.x * canvas.width;
        const endY = path.end.y * canvas.height;
        // åˆ›å»ºèƒ½é‡åœºæ•ˆæžœ
        const numPoints = 30;
        const fieldWidth = 40;
        // è®¡ç®—路径方向
        const dx = endX - startX;
        const dy = endY - startY;
        const length = Math.sqrt(dx * dx + dy * dy);
        const dirX = dx / length;
        const dirY = dy / length;
        // åž‚直方向
        const perpX = -dirY;
        const perpY = dirX;
        // ç»˜åˆ¶èƒ½é‡æµåŠ¨æ•ˆæžœ
        for (let i = 0; i < numPoints; i++) {
          const progress = i / (numPoints - 1);
          const x = startX + dx * progress;
          const y = startY + dy * progress;
          // åˆ›å»ºæ³¢æµªæ•ˆæžœ
          const waveAmplitude = Math.sin(progress * Math.PI * 4 + time * 3) * fieldWidth;
          const waveFrequency = Math.cos(progress * Math.PI * 2 - time * 2) * fieldWidth * 0.3;
          const x1 = x + perpX * waveAmplitude + dirX * waveFrequency;
          const y1 = y + perpY * waveAmplitude + dirY * waveFrequency;
          const x2 = x - perpX * waveAmplitude - dirX * waveFrequency;
          const y2 = y - perpY * waveAmplitude - dirY * waveFrequency;
          const gradient = ctx.createLinearGradient(x1, y1, x2, y2);
          const alpha = (Math.sin(progress * Math.PI + time) + 1) * 0.3;
          const alphaHex = Math.floor(alpha * 255).toString(16).padStart(2, '0');
          gradient.addColorStop(0, `${path.color}00`);
          gradient.addColorStop(0.5, `${path.color}${alphaHex}`);
          gradient.addColorStop(1, `${path.color}00`);
          ctx.beginPath();
          ctx.strokeStyle = gradient;
          ctx.lineWidth = 2;
          ctx.moveTo(x1, y1);
          ctx.lineTo(x2, y2);
          ctx.stroke();
        }
      });
    };
    // ç»˜åˆ¶èŠ‚ç‚¹
    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 time = Date.now() * 0.001;
      nodes.forEach(node => {
        const x = node.x * canvas.width;
        const y = node.y * canvas.height;
        if (node.isAI) {
          drawAINode(x, y);
        } else {
          // èŠ‚ç‚¹å…‰çŽ¯æ•ˆæžœ
          const pulseSize = 24 + Math.sin(time * 1.5 + x * 0.05) * 3;
          // å¤–发光
          const gradient = ctx.createRadialGradient(x, y, 15, x, y, pulseSize);
          gradient.addColorStop(0, `${node.color}30`);
          gradient.addColorStop(1, `${node.color}00`);
          ctx.beginPath();
          ctx.arc(x, y, pulseSize, 0, Math.PI * 2);
          ctx.fillStyle = gradient;
          ctx.fill();
          // èŠ‚ç‚¹ä¸»ä½“
          ctx.beginPath();
          ctx.arc(x, y, 20, 0, Math.PI * 2);
          ctx.fillStyle = `${node.color}20`;
          ctx.fill();
          ctx.beginPath();
          ctx.arc(x, y, 20, 0, Math.PI * 2);
          ctx.strokeStyle = node.color;
          ctx.lineWidth = 2;
          ctx.stroke();
          // å›¾æ ‡
          if (node.icon) {
            ctx.fillStyle = node.color;
            ctx.font = '16px monospace';
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            ctx.fillText(node.icon, x, y - 3);
          }
          // æ ‡ç­¾
          ctx.fillStyle = '#fff';
          ctx.font = '12px sans-serif';
          ctx.fillText(node.label, x, y + 25);
        }
      });
    };
    // ç»˜åˆ¶AI节点
    const drawAINode = (x: number, y: number) => {
      const time = Date.now() * 0.001;
      // ç¥žç»ç½‘络背景效果
      const neuronPoints = [
        { x: -20, y: -15 }, { x: 20, y: -15 },
        { x: -25, y: 0 }, { x: 25, y: 0 },
        { x: -20, y: 15 }, { x: 20, y: 15 },
        { x: 0, y: -20 }, { x: 0, y: 20 },
        { x: -15, y: -25 }, { x: 15, y: -25 },
        { x: -15, y: 25 }, { x: 15, y: 25 }
      ];
      // ç»˜åˆ¶ç¥žç»è¿žæŽ¥
      ctx.strokeStyle = 'rgba(106, 219, 255, 0.3)';
      ctx.lineWidth = 1;
      neuronPoints.forEach((point, i) => {
        for (let j = i + 1; j < neuronPoints.length; j++) {
          const p1 = { x: x + point.x, y: y + point.y };
          const p2 = { x: x + neuronPoints[j].x, y: y + neuronPoints[j].y };
          const pulsePhase = (time * 2 + i * 0.5 + j * 0.3) % (Math.PI * 2);
          const pulseIntensity = (Math.sin(pulsePhase) + 1) * 0.5;
          const gradient = ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y);
          gradient.addColorStop(0, `rgba(106, 219, 255, ${0.1 + pulseIntensity * 0.2})`);
          gradient.addColorStop(0.5, `rgba(94, 114, 235, ${0.2 + pulseIntensity * 0.3})`);
          gradient.addColorStop(1, `rgba(106, 219, 255, ${0.1 + pulseIntensity * 0.2})`);
          ctx.beginPath();
          ctx.strokeStyle = gradient;
          ctx.moveTo(p1.x, p1.y);
          // åˆ›å»ºåŠ¨æ€å¼§å½¢è¿žæŽ¥
          const controlPoint = {
            x: (p1.x + p2.x) / 2 + Math.sin(time + i) * 10,
            y: (p1.y + p2.y) / 2 + Math.cos(time + j) * 10
          };
          ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, p2.x, p2.y);
          ctx.stroke();
          // åœ¨è¿žæŽ¥çº¿ä¸Šæ·»åŠ æµåŠ¨ç²’å­
          const particlePos = Math.sin(time * 2 + i * 0.7 + j * 0.5) * 0.5 + 0.5;
          const px = p1.x + (p2.x - p1.x) * particlePos;
          const py = p1.y + (p2.y - p1.y) * particlePos;
          const particleGlow = ctx.createRadialGradient(px, py, 0, px, py, 3);
          particleGlow.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
          particleGlow.addColorStop(1, 'rgba(106, 219, 255, 0)');
          ctx.fillStyle = particleGlow;
          ctx.beginPath();
          ctx.arc(px, py, 3, 0, Math.PI * 2);
          ctx.fill();
        }
      });
      // ç»˜åˆ¶å¤§è„‘轮廓
      ctx.beginPath();
      ctx.moveTo(x - 25, y + 20);
      // å·¦åŠè¾¹å¤§è„‘
      const leftOffset = Math.sin(time * 2) * 2;
      ctx.bezierCurveTo(
        x - 40 + leftOffset, y + 10,  // æŽ§åˆ¶ç‚¹1
        x - 40 + leftOffset, y - 20,  // æŽ§åˆ¶ç‚¹2
        x - 25, y - 25   // ç»ˆç‚¹
      );
      // ä¸Šéƒ¨è¤¶çš±
      const topOffset = Math.sin(time * 2.5) * 2;
      ctx.bezierCurveTo(
        x - 20, y - 30 + topOffset,
        x - 10, y - 35 + topOffset,
        x, y - 25
      );
      // å³åŠè¾¹å¤§è„‘
      const rightOffset = Math.sin(time * 2 + Math.PI) * 2;
      ctx.bezierCurveTo(
        x + 10, y - 35 + topOffset,
        x + 20, y - 30 + topOffset,
        x + 25, y - 25
      );
      ctx.bezierCurveTo(
        x + 40 + rightOffset, y - 20,
        x + 40 + rightOffset, y + 10,
        x + 25, y + 20
      );
      // åº•部曲线
      const bottomOffset = Math.sin(time * 1.5) * 2;
      ctx.bezierCurveTo(
        x + 15, y + 25 + bottomOffset,
        x - 15, y + 25 + bottomOffset,
        x - 25, y + 20
      );
      // åˆ›å»ºå¤§è„‘渐变
      const brainGradient = ctx.createRadialGradient(x, y, 0, x, y, 40);
      brainGradient.addColorStop(0, 'rgba(94, 114, 235, 0.8)');
      brainGradient.addColorStop(0.5, 'rgba(106, 219, 255, 0.6)');
      brainGradient.addColorStop(1, 'rgba(94, 114, 235, 0.4)');
      ctx.fillStyle = brainGradient;
      ctx.fill();
      // æ·»åŠ è„‘æ³¢åŠ¨ç”»æ•ˆæžœ
      for (let i = 0; i < 3; i++) {
        const waveRadius = 35 + Math.sin(time * 2 + i * Math.PI / 3) * 5;
        const waveGradient = ctx.createRadialGradient(x, y, waveRadius - 5, x, y, waveRadius + 5);
        waveGradient.addColorStop(0, 'rgba(106, 219, 255, 0)');
        waveGradient.addColorStop(0.5, `rgba(94, 114, 235, ${0.1 - i * 0.03})`);
        waveGradient.addColorStop(1, 'rgba(106, 219, 255, 0)');
        ctx.beginPath();
        ctx.arc(x, y, waveRadius, 0, Math.PI * 2);
        ctx.fillStyle = waveGradient;
        ctx.fill();
      }
      // æ·»åŠ ç¥žç»å…ƒé—ªçƒæ•ˆæžœ
      neuronPoints.forEach((point, i) => {
        const neuronX = x + point.x;
        const neuronY = y + point.y;
        const pulseScale = Math.sin(time * 3 + i) * 0.5 + 1.5;
        const neuronGlow = ctx.createRadialGradient(
          neuronX, neuronY, 0,
          neuronX, neuronY, 4 * pulseScale
        );
        neuronGlow.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
        neuronGlow.addColorStop(0.5, 'rgba(106, 219, 255, 0.4)');
        neuronGlow.addColorStop(1, 'rgba(94, 114, 235, 0)');
        ctx.beginPath();
        ctx.arc(neuronX, neuronY, 4 * pulseScale, 0, Math.PI * 2);
        ctx.fillStyle = neuronGlow;
        ctx.fill();
      });
      // æ·»åŠ è„‘æ²Ÿçº¹ç†
      const numFolds = 8;
      for (let i = 0; i < numFolds; i++) {
        const angle = (Math.PI * 2 / numFolds) * i;
        const radius = 25;
        const x1 = x + Math.cos(angle) * radius;
        const y1 = y + Math.sin(angle) * radius;
        const x2 = x + Math.cos(angle + Math.PI / numFolds) * (radius * 0.7);
        const y2 = y + Math.sin(angle + Math.PI / numFolds) * (radius * 0.7);
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.strokeStyle = 'rgba(94, 114, 235, 0.3)';
        ctx.lineWidth = 1;
        ctx.stroke();
      }
      // æ ‡ç­¾
      ctx.fillStyle = '#FFFFFF';
      ctx.font = '13px sans-serif';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText('智能分析引擎', x, y + 45);
    };
    // ç»˜åˆ¶é‡å­ç²’子
    const drawQuantumParticles = () => {
      particles.forEach(p => {
        const time = Date.now() * 0.001;
        // é‡å­å…‰æ™•效果
        const glowSize = p.size * (2 + Math.sin(time * 3 + p.phase) * 0.5);
        const gradient = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, glowSize * 2);
        gradient.addColorStop(0, p.color + 'FF');
        gradient.addColorStop(0.5, p.color + '40');
        gradient.addColorStop(1, p.color + '00');
        ctx.beginPath();
        ctx.arc(p.x, p.y, glowSize, 0, Math.PI * 2);
        ctx.fillStyle = gradient;
        ctx.fill();
        // é‡å­æ ¸å¿ƒ
        ctx.beginPath();
        ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
        ctx.fillStyle = '#FFFFFF';
        ctx.fill();
        // é‡å­æ³¢çº¹
        if (Math.random() < 0.1) {
          const waveGradient = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, p.size * 4);
          waveGradient.addColorStop(0, p.color + '40');
          waveGradient.addColorStop(1, p.color + '00');
          ctx.beginPath();
          ctx.arc(p.x, p.y, p.size * 4, 0, Math.PI * 2);
          ctx.fillStyle = waveGradient;
          ctx.fill();
        }
      });
    };
    // åˆå§‹åŒ–粒子系统
    const initParticles = () => {
      for (let i = 0; i < 40; i++) {
        setTimeout(() => createQuantumParticle(), i * 100);
      }
    };
    // å®šæœŸæ·»åŠ æ–°ç²’å­
    const particleInterval = setInterval(() => {
      if (particles.length < 50) {
        createQuantumParticle();
      }
    }, 500);
    // åŠ¨ç”»å¾ªçŽ¯
    const animate = () => {
      updateParticles();
      drawScene();
      requestAnimationFrame(animate);
    };
    initParticles();
    animate();
    return () => {
      window.removeEventListener('resize', setCanvasSize);
      clearInterval(particleInterval);
    };
  }, []);
  return (
    <div className="w-full py-4">
      <motion.div
        initial={{ opacity: 0, y: 20 }}
        whileInView={{ opacity: 1, y: 0 }}
        viewport={{ once: false, margin: "-100px" }}
        transition={{ duration: 0.7, ease: "easeOut" }}
        className="text-center mb-8"
      >
        <h2 className="text-3xl md:text-4xl font-bold text-white mb-5">
          <span className="text-transparent bg-clip-text bg-gradient-to-r from-[#6ADBFF] to-[#5E72EB]">
            AI赋能APS
          </span> ä¼˜åŠ¿å…¨æ™¯
        </h2>
        <p className="text-gray-300 max-w-3xl mx-auto">
          å…¨å±€æ™ºèƒ½ååŒï¼Œä»Žä¾›åº”链各环节收集数据,基于深度学习与量子启发算法实现端到端的智能决策与优化
        </p>
      </motion.div>
      <motion.div
        initial={{ opacity: 0 }}
        whileInView={{ opacity: 1 }}
        viewport={{ once: false, margin: "-100px" }}
        transition={{ duration: 1, ease: "easeOut" }}
        className="relative h-[450px] w-full backdrop-blur-sm bg-white/5 rounded-xl border border-[#6ADBFF]/20 overflow-hidden"
      >
        <canvas
          ref={canvasRef}
          className="absolute inset-0 w-full h-full"
        />
        <div className="absolute bottom-0 left-0 right-0 flex justify-center gap-6 p-6 bg-gradient-to-t from-[#0A1033]/90 to-transparent">
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            viewport={{ once: false }}
            transition={{ duration: 0.7, delay: 0.2 }}
            className="backdrop-blur-sm bg-white/5 rounded-lg p-4 border border-[#6ADBFF]/20 w-[30%]"
          >
            <h3 className="text-lg font-semibold text-[#6ADBFF] mb-2">动态响应</h3>
            <p className="text-gray-300 text-sm">实时感知供应链变化,智能调整生产计划,提升40%响应速度</p>
          </motion.div>
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            viewport={{ once: false }}
            transition={{ duration: 0.7, delay: 0.3 }}
            className="backdrop-blur-sm bg-white/5 rounded-lg p-4 border border-[#5E72EB]/20 w-[30%]"
          >
            <h3 className="text-lg font-semibold text-[#5E72EB] mb-2">预测优化</h3>
            <p className="text-gray-300 text-sm">基于深度学习预测市场需求,降低25%库存成本,提高物料利用率</p>
          </motion.div>
          <motion.div
            initial={{ opacity: 0, y: 20 }}
            whileInView={{ opacity: 1, y: 0 }}
            viewport={{ once: false }}
            transition={{ duration: 0.7, delay: 0.4 }}
            className="backdrop-blur-sm bg-white/5 rounded-lg p-4 border border-[#FF6A88]/20 w-[30%]"
          >
            <h3 className="text-lg font-semibold text-[#FF6A88] mb-2">多维决策</h3>
            <p className="text-gray-300 text-sm">平衡成本、交期、质量多维目标,实现真正全局最优解</p>
          </motion.div>
        </div>
      </motion.div>
    </div>
  );
}