console
const container = document.createElement('div');
container.id = 'container';
container.style.position = 'relative';
container.style.width = '400px';
container.style.height = '400px';
container.style.margin = '0 auto';
const hexagon = document.createElement('div');
hexagon.id = 'hexagon';
hexagon.style.position = 'absolute';
hexagon.style.width = '100%';
hexagon.style.height = '100%';
hexagon.style.backgroundColor = '#333';
hexagon.style.clipPath = 'polygon(25% 5%, 75% 5%, 95% 50%, 75% 95%, 25% 95%, 5% 50%)';
hexagon.style.transformOrigin = 'center';
const ball = document.createElement('div');
ball.id = 'ball';
ball.style.position = 'absolute';
ball.style.width = '30px';
ball.style.height = '30px';
ball.style.backgroundColor = '#e74c3c';
ball.style.borderRadius = '50%';
ball.style.transformOrigin = 'center';
container.appendChild(hexagon);
container.appendChild(ball);
document.body.appendChild(container);
document.body.style.margin = '0';
document.body.style.overflow = 'hidden';
document.body.style.display = 'flex';
document.body.style.justifyContent = 'center';
document.body.style.alignItems = 'center';
document.body.style.height = '100vh';
document.body.style.backgroundColor = '#f0f0f0';
const hexagonSize = 400;
const hexagonPoints = [
{x: 100, y: 20},
{x: 300, y: 20},
{x: 380, y: 200},
{x: 300, y: 380},
{x: 100, y: 380},
{x: 20, y: 200}
];
const ballSize = 30;
let ballPos = {x: 200, y: 200};
let ballVel = {x: 0, y: 0};
const gravity = 0.2;
const friction = 0.99;
const bounceFactor = 0.8;
const rotationSpeed = 0.5;
let rotationAngle = 0;
function getRotatedHexagonPoints() {
const centerX = hexagonSize / 2;
const centerY = hexagonSize / 2;
return hexagonPoints.map(point => {
const x = point.x - centerX;
const y = point.y - centerY;
const rotatedX = x * Math.cos(rotationAngle) - y * Math.sin(rotationAngle);
const rotatedY = x * Math.sin(rotationAngle) + y * Math.cos(rotationAngle);
return {
x: rotatedX + centerX,
y: rotatedY + centerY
};
});
}
function checkCollision() {
const points = getRotatedHexagonPoints();
for (let i = 0; i < points.length; i++) {
const p1 = points[i];
const p2 = points[(i + 1) % points.length];
const edge = {
x: p2.x - p1.x,
y: p2.y - p1.y
};
const normal = {
x: -edge.y,
y: edge.x
};
const length = Math.sqrt(normal.x * normal.x + normal.y * normal.y);
normal.x /= length;
normal.y /= length;
const ballToEdge = {
x: ballPos.x - p1.x,
y: ballPos.y - p1.y
};
const distance = ballToEdge.x * normal.x + ballToEdge.y * normal.y;
if (distance < ballSize / 2 && distance > -ballSize / 2) {
const edgeLength = Math.sqrt(edge.x * edge.x + edge.y * edge.y);
const edgeDir = {
x: edge.x / edgeLength,
y: edge.y / edgeLength
};
const projection = ballToEdge.x * edgeDir.x + ballToEdge.y * edgeDir.y;
if (projection >= 0 && projection <= edgeLength) {
const penetration = ballSize / 2 - distance;
ballPos.x += normal.x * penetration;
ballPos.y += normal.y * penetration;
const velocityProjection = ballVel.x * normal.x + ballVel.y * normal.y;
if (velocityProjection < 0) {
ballVel.x -= (1 + bounceFactor) * velocityProjection * normal.x;
ballVel.y -= (1 + bounceFactor) * velocityProjection * normal.y;
const tangentVel = {
x: ballVel.x - velocityProjection * normal.x,
y: ballVel.y - velocityProjection * normal.y
};
ballVel.x = tangentVel.x * friction + velocityProjection * normal.x * bounceFactor;
ballVel.y = tangentVel.y * friction + velocityProjection * normal.y * bounceFactor;
}
return true;
}
}
}
return false;
}
function animate() {
rotationAngle += rotationSpeed * Math.PI / 500;
hexagon.style.transform = `rotate(${rotationAngle}rad)`;
ballVel.y += gravity;
ballPos.x += ballVel.x;
ballPos.y += ballVel.y;
checkCollision();
ball.style.left = `${ballPos.x - ballSize / 2}px`;
ball.style.top = `${ballPos.y - ballSize / 2}px`;
requestAnimationFrame(animate);
}
ballPos = {x: 200, y: 250};
ballVel = {x: 2, y: 0};
animate();
<!-- <!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.1/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<main>
</main>
<script src="gTnKp.js"></script>
</body>
</html> -->
<!-- <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>震撼3D粒子交互动画</title>
<style>
body {
margin: 0;
overflow: hidden;
background: #000;
}
canvas {
display: block;
}
.info {
position: absolute;
top: 20px;
left: 20px;
color: white;
font-family: Arial, sans-serif;
pointer-events: none;
text-shadow: 0 0 5px #000;
}
</style>
</head>
<body>
<div class="info">移动鼠标与粒子互动</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xffffff, 1, 100);
pointLight.position.set(10, 10, 10);
scene.add(pointLight);
const particleCount = 15000;
const particles = new THREE.BufferGeometry();
const positions = new Float32Array(particleCount * 3);
const colors = new Float32Array(particleCount * 3);
const sizes = new Float32Array(particleCount);
for (let i = 0; i < particleCount; i++) {
const radius = 20;
const theta = Math.random() * Math.PI * 2;
const phi = Math.random() * Math.PI;
positions[i * 3] = radius * Math.sin(phi) * Math.cos(theta);
positions[i * 3 + 1] = radius * Math.sin(phi) * Math.sin(theta);
positions[i * 3 + 2] = radius * Math.cos(phi);
colors[i * 3] = Math.random() * 0.5 + 0.5;
colors[i * 3 + 1] = Math.random() * 0.3 + 0.2;
colors[i * 3 + 2] = Math.random() * 0.5 + 0.5;
sizes[i] = Math.random() * 0.5 + 0.5;
}
particles.setAttribute('position', new THREE.BufferAttribute(positions, 3));
particles.setAttribute('color', new THREE.BufferAttribute(colors, 3));
particles.setAttribute('size', new THREE.BufferAttribute(sizes, 1));
const particleMaterial = new THREE.PointsMaterial({
size: 0.2,
vertexColors: true,
transparent: true,
opacity: 0.8,
blending: THREE.AdditiveBlending,
sizeAttenuation: true
});
const particleSystem = new THREE.Points(particles, particleMaterial);
scene.add(particleSystem);
const mouse = new THREE.Vector2();
const mouseTarget = new THREE.Vector2();
const windowHalf = new THREE.Vector2(window.innerWidth / 2, window.innerHeight / 2);
document.addEventListener('mousemove', (event) => {
mouse.x = (event.clientX - windowHalf.x) / windowHalf.x;
mouse.y = (event.clientY - windowHalf.y) / windowHalf.y;
mouseTarget.x = (event.clientX - windowHalf.x) / windowHalf.x;
mouseTarget.y = (event.clientY - windowHalf.y) / windowHalf.y;
});
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
windowHalf.set(window.innerWidth / 2, window.innerHeight / 2);
});
let time = 0;
const originalPositions = particles.attributes.position.array.slice();
const noise = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount * 3; i++) {
noise[i] = Math.random() * 2 - 1;
}
camera.position.z = 30;
function animate() {
requestAnimationFrame(animate);
time += 0.005;
mouse.x += (mouseTarget.x - mouse.x) * 0.05;
mouse.y += (mouseTarget.y - mouse.y) * 0.05;
const positions = particles.attributes.position.array;
for (let i = 0; i < particleCount; i++) {
const i3 = i * 3;
const ox = originalPositions[i3];
const oy = originalPositions[i3 + 1];
const oz = originalPositions[i3 + 2];
const dx = mouse.x * 10;
const dy = mouse.y * 10;
const dist = Math.sqrt(
Math.pow(positions[i3] - dx, 2) +
Math.pow(positions[i3 + 1] - dy, 2)
);
const force = Math.max(0, 1 - dist / 15);
const angle = Math.atan2(positions[i3 + 1] - dy, positions[i3] - dx);
positions[i3] = ox +
Math.sin(time + oz * 0.1) * 2 +
noise[i3] * 0.3 +
Math.cos(angle) * force * 10;
positions[i3 + 1] = oy +
Math.cos(time + ox * 0.1) * 2 +
noise[i3 + 1] * 0.3 +
Math.sin(angle) * force * 10;
positions[i3 + 2] = oz +
Math.sin(time + oy * 0.1) * 2 +
noise[i3 + 2] * 0.3;
}
particles.attributes.position.needsUpdate = true;
particleSystem.rotation.x = time * 0.1;
particleSystem.rotation.y = time * 0.15;
renderer.render(scene, camera);
}
animate();
</script>
</body>
</html> -->