<template>
  <div class="particle-container">
    <canvas ref="canvasRef"></canvas>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import * as THREE from 'three';

// 参数配置
const particleCount = 1000; // 粒子数量
const maxRange = 1000; // 粒子生成的坐标范围
const particleSize = 5; // 粒子大小
const rotationSpeed = 0.0005; // 背景粒子旋转速度
const layerDepth = [-500, -600, -700]; // Z轴上不同平面的深度

const canvasRef = ref<HTMLCanvasElement | null>(null);

let scene: THREE.Scene, camera: THREE.PerspectiveCamera, renderer: THREE.WebGLRenderer;
let xBgPoints: THREE.Points, yBgPoints: THREE.Points, zBgPoints: THREE.Points;
let animationId: number;
let pointTexture: THREE.Texture;

// 初始化场景
function initScene() {
  const canvas = canvasRef.value;
  if (!canvas) return;

  // 场景
  scene = new THREE.Scene();
  scene.fog = new THREE.FogExp2(0x000000, 0.0005); // 添加雾化效果
  scene.background = new THREE.Color(0x0c0c18);

  // 相机
  camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 3000);
  camera.position.z = 1000;

  // 渲染器
  renderer = new THREE.WebGLRenderer({ canvas, alpha: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(window.devicePixelRatio);

  // 纹理加载
  const loader = new THREE.TextureLoader();
  pointTexture = loader.load('/gradient.png'); // 替换为您自己的纹理路径

  // 初始化粒子背景
  initBackgroundPoints();
}

// 随机坐标生成
function randomPosition(min: number, max: number) {
  return Math.random() * (max - min) + min;
}

// 初始化背景粒子
function initBackgroundPoints() {
  const geometry = new THREE.BufferGeometry();
  const positions = [];
  const colors = [];

  for (let i = 0; i < particleCount; i++) {
    positions.push(
      randomPosition(-maxRange, maxRange),
      randomPosition(-maxRange, maxRange),
      randomPosition(-maxRange, maxRange),
    );
    colors.push(1, 1, 1); // 白色
  }

  geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
  geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

  const material = new THREE.PointsMaterial({
    size: particleSize,
    map: pointTexture,
    blending: THREE.AdditiveBlending,
    depthWrite: false,
    transparent: true,
    vertexColors: true,
  });

  // 创建三层粒子
  xBgPoints = new THREE.Points(geometry, material);
  xBgPoints.position.z = layerDepth[0];

  yBgPoints = new THREE.Points(geometry, material);
  yBgPoints.position.z = layerDepth[1];

  zBgPoints = new THREE.Points(geometry, material);
  zBgPoints.position.z = layerDepth[2];

  scene.add(xBgPoints, yBgPoints, zBgPoints);
}

// 动画渲染逻辑
function animate() {
  animationId = requestAnimationFrame(animate);

  // 旋转粒子背景
  xBgPoints.rotation.y += rotationSpeed;
  yBgPoints.rotation.y -= rotationSpeed;
  zBgPoints.rotation.z += rotationSpeed / 2;

  renderer.render(scene, camera);
}

// 处理窗口大小变化
function onResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

// 生命周期管理
onMounted(() => {
  initScene();
  animate();
  window.addEventListener('resize', onResize);
});

onUnmounted(() => {
  cancelAnimationFrame(animationId);
  window.removeEventListener('resize', onResize);
});
</script>

<style scoped>
.particle-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: #000;
}
</style>
