添加了一个修改

This commit is contained in:
rucky
2025-11-23 23:55:10 +08:00
commit cefc2a1653
46 changed files with 10659 additions and 0 deletions

124
src/views/Color.vue Normal file
View File

@@ -0,0 +1,124 @@
<template>
<div class="color-page">
<div class="color-header">
<h1>三维空间色彩粒子</h1>
<p>这是从旧项目抽离出来的第一个实验场景后续可以继续补充更多交互与玩法</p>
</div>
<div class="color-canvas" ref="canvasRoot"></div>
</div>
</template>
<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue'
import * as THREE from 'three'
const canvasRoot = ref<HTMLDivElement | null>(null)
let renderer: THREE.WebGLRenderer | null = null
let scene: THREE.Scene | null = null
let camera: THREE.PerspectiveCamera | null = null
let animationId = 0
onMounted(() => {
if (!canvasRoot.value) return
const container = canvasRoot.value
const width = container.clientWidth
const height = container.clientHeight
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(width, height)
container.appendChild(renderer.domElement)
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(55, width / height, 0.1, 2000)
camera.position.set(0, 0, 380)
const geometry = new THREE.IcosahedronGeometry(1, 3)
const group = new THREE.Group()
const gridSize = 64
const spacing = 8
for (let x = -gridSize; x <= gridSize; x += spacing) {
for (let y = -gridSize; y <= gridSize; y += spacing) {
const zLayerCount = 3
for (let zIndex = 0; zIndex < zLayerCount; zIndex++) {
if (Math.random() > 0.55) continue
const color = new THREE.Color()
color.setHSL(Math.random(), 0.7, Math.random() * 0.2 + 0.2)
const material = new THREE.MeshBasicMaterial({ color })
const mesh = new THREE.Mesh(geometry, material)
mesh.position.set(
x,
y + (Math.random() - 0.5) * 10,
zIndex * 18 + (Math.random() - 0.5) * 20,
)
const s = Math.random() * 3 + 1.2
mesh.scale.setScalar(s)
group.add(mesh)
}
}
}
scene.add(group)
const clock = new THREE.Clock()
const animate = () => {
animationId = requestAnimationFrame(animate)
const t = clock.getElapsedTime()
group.rotation.y = t * 0.16
group.rotation.x = Math.sin(t * 0.3) * 0.35
if (camera) {
camera.position.z = 360 + Math.sin(t * 0.5) * 40
camera.lookAt(0, 0, 0)
}
renderer?.render(scene as THREE.Scene, camera as THREE.PerspectiveCamera)
}
animate()
const onResize = () => {
if (!renderer || !camera) return
const w = container.clientWidth
const h = container.clientHeight
renderer.setSize(w, h)
camera.aspect = w / h
camera.updateProjectionMatrix()
}
window.addEventListener('resize', onResize)
onBeforeUnmount(() => {
cancelAnimationFrame(animationId)
window.removeEventListener('resize', onResize)
if (renderer) {
renderer.dispose()
}
if (scene) {
scene.traverse((obj) => {
if ((obj as THREE.Mesh).geometry) {
;(obj as THREE.Mesh).geometry.dispose()
}
if ((obj as THREE.Mesh).material) {
const mat = (obj as THREE.Mesh).material
if (Array.isArray(mat)) {
mat.forEach((m) => m.dispose())
} else {
mat.dispose()
}
}
})
}
if (canvasRoot.value && renderer) {
canvasRoot.value.removeChild(renderer.domElement)
}
})
})
</script>