Eidos

No description provided.

import React, { useEffect, useRef } from "react";

// themes: 现实世界是理型世界的投影 - 柏拉图哲学
// visualization: 完美几何图形向右投射形成扭曲影子,展现理念与现象的层次关系

const PlatonicProjection = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext("2d")!;
    let time = 0;

    const animate = () => {
      // 清空画布
      ctx.fillStyle = "#F0EEE6";
      ctx.fillRect(0, 0, 550, 550);

      const centerY = 275;

      // 绘制理型世界 - 左侧的完美几何图形
      ctx.save();
      ctx.translate(150, centerY);
      
      // 理型世界的光环效果
      const gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 100);
      gradient.addColorStop(0, "rgba(51, 51, 51, 0.1)");
      gradient.addColorStop(1, "rgba(51, 51, 51, 0)");
      ctx.fillStyle = gradient;
      ctx.fillRect(-100, -100, 200, 200);

      // 完美的几何图形 - 理型
      ctx.strokeStyle = "#333333";
      ctx.lineWidth = 2;
      
      // 旋转的完美正多边形
      for (let i = 0; i < 3; i++) {
        ctx.save();
        ctx.rotate(time * 0.3 + i * Math.PI / 3);
        
        // 绘制正六边形(完美的理型)
        ctx.beginPath();
        const radius = 40 + i * 15;
        for (let j = 0; j < 6; j++) {
          const angle = (j * Math.PI) / 3;
          const x = Math.cos(angle) * radius;
          const y = Math.sin(angle) * radius;
          if (j === 0) ctx.moveTo(x, y);
          else ctx.lineTo(x, y);
        }
        ctx.closePath();
        ctx.stroke();
        ctx.restore();
      }

      // 理型中心的完美圆
      ctx.beginPath();
      ctx.arc(0, 0, 20, 0, Math.PI * 2);
      ctx.fillStyle = "#333333";
      ctx.fill();
      
      ctx.restore();

      // 绘制投射光线 - 从左到右
      ctx.strokeStyle = "rgba(51, 51, 51, 0.3)";
      ctx.lineWidth = 1;
      
      for (let i = 0; i < 8; i++) {
        const angle = (i * Math.PI) / 4 + time * 0.2;
        const startX = 150 + Math.cos(angle) * 60;
        const startY = centerY + Math.sin(angle) * 60;
        const endX = 400 + Math.cos(angle) * 60 + Math.sin(time + i) * 15;
        const endY = centerY + Math.sin(angle) * 80 + Math.cos(time + i) * 20;
        
        ctx.beginPath();
        ctx.moveTo(startX, startY);
        ctx.lineTo(endX, endY);
        ctx.stroke();
      }

      // 绘制现实世界 - 右侧的扭曲投影
      ctx.save();
      ctx.translate(400, centerY);

      // 现实世界的阴影背景
      const shadowGradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 120);
      shadowGradient.addColorStop(0, "rgba(51, 51, 51, 0.05)");
      shadowGradient.addColorStop(1, "rgba(51, 51, 51, 0.15)");
      ctx.fillStyle = shadowGradient;
      ctx.fillRect(-120, -120, 240, 240);

      // 扭曲的投影图形 - 现实世界
      ctx.strokeStyle = "rgba(51, 51, 51, 0.7)";
      ctx.lineWidth = 1.5;
      
      for (let i = 0; i < 3; i++) {
        ctx.save();
        
        // 投影的不稳定旋转
        const distortedRotation = time * 0.25 + i * Math.PI / 3 + Math.sin(time * 2) * 0.1;
        ctx.rotate(distortedRotation);
        
        // 绘制扭曲的六边形投影
        ctx.beginPath();
        const baseRadius = 35 + i * 12;
        
        for (let j = 0; j < 6; j++) {
          const angle = (j * Math.PI) / 3;
          // 添加扭曲效果
          const distortion = Math.sin(time * 3 + j) * 0.2 + Math.cos(time * 2 + i) * 0.15;
          const radius = baseRadius * (1 + distortion);
          const x = Math.cos(angle) * radius * 0.8 + Math.sin(time + j) * 3; // X轴压缩模拟投影
          const y = Math.sin(angle) * radius + Math.cos(time * 1.5 + j) * 2;
          
          if (j === 0) ctx.moveTo(x, y);
          else ctx.lineTo(x, y);
        }
        ctx.closePath();
        ctx.stroke();
        ctx.restore();
      }

      // 现实世界中心的不完美圆
      ctx.beginPath();
      const imperfectRadius = 15 + Math.sin(time * 4) * 2;
      ctx.arc(Math.sin(time) * 2, Math.cos(time * 1.5) * 1, imperfectRadius, 0, Math.PI * 2);
      ctx.fillStyle = "rgba(51, 51, 51, 0.6)";
      ctx.fill();

      ctx.restore();

      // 绘制垂直分界线 - 象征理型与现实的边界
      ctx.strokeStyle = "rgba(51, 51, 51, 0.2)";
      ctx.lineWidth = 1;
      ctx.setLineDash([5, 5]);
      ctx.beginPath();
      ctx.moveTo(275, 50);
      ctx.lineTo(275, 500);
      ctx.stroke();
      ctx.setLineDash([]);

      // 添加水平波动效果,象征理型向现实的传递
      ctx.strokeStyle = "rgba(51, 51, 51, 0.1)";
      for (let i = 0; i < 5; i++) {
        ctx.beginPath();
        for (let y = 0; y < 550; y += 2) {
          const x = 275 + Math.sin((y * 0.02) + time * 2 + i * 0.5) * (5 - i);
          if (y === 0) ctx.moveTo(x, y);
          else ctx.lineTo(x, y);
        }
        ctx.stroke();
      }

      time += 0.008;
      requestAnimationFrame(animate);
    };

    animate();
  }, []);

  return (
    <div style={{ backgroundColor: "#F0EEE6" }}>
      <canvas ref={canvasRef} width={550} height={550} />
    </div>
  );
};

export default PlatonicProjection;

Information

Author
Mayne
Type
m_block
Latest Version
0.0.1
Last Updated
05/25/2025
Published
05/25/2025

Version History

  • v0.0.1 05/25/2025