Files
video-gen/write-file.js
2026-06-18 12:05:36 +08:00

171 lines
5.8 KiB
JavaScript

const fs = require('fs');
const content = `import { useEffect, useRef } from 'react';
import * as THREE from 'three';
const GalaxyBackground = () => {
const containerRef = useRef(null);
const animationIdRef = useRef(0);
useEffect(() => {
if (!containerRef.current) return;
const width = containerRef.current.clientWidth;
const height = containerRef.current.clientHeight;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
camera.position.z = 50;
const canvas = containerRef.current.querySelector('canvas');
if (!canvas) return;
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true,
alpha: true,
});
renderer.setSize(width, height);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
const particleCount = 5000;
const positions = new Float32Array(particleCount * 3);
const colors = new Float32Array(particleCount * 3);
const sizes = new Float32Array(particleCount);
const phases = new Float32Array(particleCount);
const color1 = new THREE.Color(0x6366f1);
const color2 = new THREE.Color(0x8b5cf6);
const color3 = new THREE.Color(0xec4899);
for (let i = 0; i < particleCount; i++) {
const i3 = i * 3;
const radius = 2 + Math.random() * 25;
const theta = Math.random() * Math.PI * 2;
const phi = Math.acos(2 * Math.random() - 1);
positions[i3] = radius * Math.sin(phi) * Math.cos(theta);
positions[i3 + 1] = radius * Math.sin(phi) * Math.sin(theta);
positions[i3 + 2] = radius * Math.cos(phi);
const colorMix = Math.random();
let color;
if (colorMix < 0.33) {
color = color1;
} else if (colorMix < 0.66) {
color = color2;
} else {
color = color3;
}
colors[i3] = color.r;
colors[i3 + 1] = color.g;
colors[i3 + 2] = color.b;
sizes[i] = 0.02 + Math.random() * 0.08;
phases[i] = Math.random() * Math.PI * 2;
}
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
geometry.setAttribute('size', new THREE.BufferAttribute(sizes, 1));
geometry.setAttribute('phase', new THREE.BufferAttribute(phases, 1));
const shaderMaterial = new THREE.ShaderMaterial({
uniforms: {
uTime: { value: 0 },
uPixelRatio: { value: renderer.getPixelRatio() },
uSize: { value: 40 },
},
vertexShader: "attribute float size; attribute float phase; varying vec3 vColor; uniform float uTime; uniform float uPixelRatio; uniform float uSize; void main() { vColor = color; float spiralOffset = phase + uTime * 0.1; float spiralRadius = length(position.xy) * 0.02; float x = position.x + cos(spiralOffset) * spiralRadius; float y = position.y + sin(spiralOffset) * spiralRadius; float z = position.z + sin(uTime * 0.05 + phase) * 0.5; vec4 mvPosition = modelViewMatrix * vec4(x, y, z, 1.0); gl_PointSize = size * uSize * (300.0 / -mvPosition.z) * uPixelRatio; gl_Position = projectionMatrix * mvPosition; }",
fragmentShader: "varying vec3 vColor; uniform float uTime; void main() { vec2 center = gl_PointCoord - vec2(0.5); float dist = length(center); if (dist > 0.5) discard; float gradient = 1.0 - smoothstep(0.0, 0.5, dist); float glow = 1.0 - smoothstep(0.15, 0.5, dist); vec3 finalColor = vColor * gradient; float alpha = glow * (0.7 + sin(uTime * 2.0 + gl_FragCoord.x * 0.05) * 0.3); gl_FragColor = vec4(finalColor, alpha); }",
transparent: true,
opacity: 0.9,
depthWrite: false,
blending: THREE.AdditiveBlending,
vertexColors: true,
});
const particles = new THREE.Points(geometry, shaderMaterial);
scene.add(particles);
const centerGlowGeometry = new THREE.SphereGeometry(8, 32, 32);
const centerGlowMaterial = new THREE.MeshBasicMaterial({
color: 0x6366f1,
transparent: true,
opacity: 0.08,
});
const centerGlow = new THREE.Mesh(centerGlowGeometry, centerGlowMaterial);
scene.add(centerGlow);
const animate = () => {
animationIdRef.current = requestAnimationFrame(animate);
const time = performance.now() * 0.001;
if (shaderMaterial.uniforms.uTime) {
shaderMaterial.uniforms.uTime.value = time;
}
particles.rotation.y += 0.0003;
particles.rotation.x += 0.0001;
centerGlow.rotation.y -= 0.0002;
const pulse = 0.08 + Math.sin(time * 1.5) * 0.03;
centerGlow.scale.setScalar(pulse);
renderer.render(scene, camera);
};
animate();
const handleResize = () => {
const newWidth = containerRef.current?.clientWidth || width;
const newHeight = containerRef.current?.clientHeight || height;
camera.aspect = newWidth / newHeight;
camera.updateProjectionMatrix();
renderer.setSize(newWidth, newHeight);
shaderMaterial.uniforms.uPixelRatio.value = renderer.getPixelRatio();
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
cancelAnimationFrame(animationIdRef.current);
geometry.dispose();
shaderMaterial.dispose();
renderer.dispose();
centerGlowGeometry.dispose();
centerGlowMaterial.dispose();
};
}, []);
return (
<div
ref={containerRef}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: 0,
overflow: 'hidden',
}}
>
<canvas style={{ display: 'block' }} />
</div>
);
};
export default GalaxyBackground;
`;
fs.writeFileSync('d:/ÃñÖÚÆÕ¿µ/video_item/video-gen-app/src/components/GalaxyBackground.tsx', content);
console.log('File written successfully');