欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

用 HTML、CSS 和 JS 创造浪漫的 3D 飘浮粒子动画效果

最编程 2024-08-10 11:29:07
...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>粒子</title>
</head>

<body>

<script src="js/three.min.js"></script>

<div></div>

<script>
var Stats = function() {
var e = Date.now(),
t = e,
i = 0,
n = 1 / 0,
r = 0,
s = 0,
o = 1 / 0,
a = 0,
l = 0,
h = 0,
c = document.createElement("div");
c.id = "stats", c.addEventListener("mousedown", function(e) {
e.preventDefault(), v(++h % 2)
}, !1), c.style.cssText = "width:80px;opacity:0.9;cursor:pointer";
var u = document.createElement("div");
u.id = "fps", u.style.cssText = "padding:0 0 3px 3px;text-align:left;background-color:#002", c.appendChild(u);
var d = document.createElement("div");
d.id = "fpsText", d.style.cssText = "color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px", d.innerHTML = "FPS", u.appendChild(d);
var p = document.createElement("div");
for (p.id = "fpsGraph", p.style.cssText = "position:relative;width:74px;height:30px;background-color:#0ff", u.appendChild(p); 74 > p.children.length;) {
var f = document.createElement("span");
f.style.cssText = "width:1px;height:30px;float:left;background-color:#113", p.appendChild(f)
}
var m = document.createElement("div");
m.id = "ms", m.style.cssText = "padding:0 0 3px 3px;text-align:left;background-color:#020;display:none", c.appendChild(m);
var g = document.createElement("div");
g.id = "msText", g.style.cssText = "color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px", g.innerHTML = "MS", m.appendChild(g);
var y = document.createElement("div");
for (y.id = "msGraph", y.style.cssText = "position:relative;width:74px;height:30px;background-color:#0f0", m.appendChild(y); 74 > y.children.length;) {
var f = document.createElement("span");
f.style.cssText = "width:1px;height:30px;float:left;background-color:#131", y.appendChild(f)
}
var v = function(e) {
switch (h = e) {
case 0:
u.style.display = "block", m.style.display = "none";
break;
case 1:
u.style.display = "none", m.style.display = "block"
}
},
b = function(e, t) {
var i = e.appendChild(e.firstChild);
i.style.height = t + "px"
};
return {
REVISION: 11,
domElement: c,
setMode: v,
begin: function() {
e = Date.now()
},
end: function() {
var h = Date.now();
return i = h - e, n = Math.min(n, i), r = Math.max(r, i), g.textContent = i + " MS (" + n + "-" + r + ")", b(y, Math.min(30, 30 - 30 * (i / 200))), l++, h > t + 1e3 && (s = Math.round(1e3 * l / (h - t)), o = Math.min(o, s), a = Math.max(a, s), d.textContent = s + " FPS (" + o + "-" + a + ")", b(p, Math.min(30, 30 - 30 * (s / 100))), t = h, l = 0), h
},
update: function() {
e = this.end()
}
}
};

(function() {
'use strict';
// 'To actually be able to display anything with Three.js, we need three things:
// A scene, a camera, and a renderer so we can render the scene with the camera.'
// - https://threejs.org/docs/#Manual/Introduction/Creating_a_scene

var scene, camera, renderer;

// I guess we need this stuff too
var container, HEIGHT,
WIDTH, fieldOfView, aspectRatio,
nearPlane, farPlane, stats,
geometry, particleCount,
i, h, color, size,
materials = [],
mouseX = 0,
mouseY = 0,
windowHalfX, windowHalfY, cameraZ,
fogHex, fogDensity, parameters = {},
parameterCount, particles;

init();
animate();

function init() {

HEIGHT = window.innerHeight;
WIDTH = window.innerWidth;
windowHalfX = WIDTH / 2;
windowHalfY = HEIGHT / 2;

fieldOfView = 75;
aspectRatio = WIDTH / HEIGHT;
nearPlane = 1;
farPlane = 300;

/* fieldOfView ? Camera frustum vertical field of view.
aspectRatio ? Camera frustum aspect ratio.
nearPlane ? Camera frustum near plane.
farPlane ? Camera frustum far plane.

- https://threejs.org/docs/#Reference/Cameras/PerspectiveCamera

In geometry, a frustum (plural: frusta or frustums)
is the portion of a solid (normally a cone or pyramid)
that lies between two parallel planes cutting it. - wikipedia. */

cameraZ = farPlane / 3; /* So, 1000? Yes! move on! */
fogHex = 0x000000; /* As black as your heart. */
fogDensity = 0.0007; /* So not terribly dense? */

camera = new THREE.PerspectiveCamera(fieldOfView, aspectRatio, nearPlane, farPlane);
camera.position.z = cameraZ;

scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(fogHex, fogDensity);

container = document.createElement('div');
document.body.appendChild(container);
document.body.style.margin = 0;
document.body.style.overflow = 'hidden';

geometry = new THREE.Geometry(); /* NO ONE SAID ANYTHING ABOUT MATH! UGH! */

particleCount = 20000; /* Leagues under the sea */

/* Hope you took your motion sickness pills;
We're about to get loopy. */

for (i = 0; i < particleCount; i++) {

var vertex = new THREE.Vector3();
vertex.x = Math.random() * 2000 - 1000;
vertex.y = Math.random() * 2000 - 1000;
vertex.z = Math.random() * 2000 - 1000;

geometry.vertices.push(vertex);
}

/* We can't stop here, this is bat country! */

parameters = [
[
[1, 1, 0.5], 5
],
[
[0.95, 1, 0.5], 4
],
[
[0.90, 1, 0.5], 3
],
[
[0.85, 1, 0.5], 2
],
[
[0.80, 1, 0.5], 1
]
];
parameterCount = parameters.length;

/* I told you to take those motion sickness pills.
Clean that vommit up, we're going again! */

for (i = 0; i < parameterCount; i++) {

color = parameters[i][0];
size = parameters[i][1];

materials[i] = new THREE.PointCloudMaterial({
size: size
});

particles = new THREE.PointCloud(geometry, materials[i]);

particles.rotation.x = Math.random() * 6;
particles.rotation.y = Math.random() * 6;
particles.rotation.z = Math.random() * 6;

scene.add(particles);
}

/* If my calculations are correct, when this baby hits 88 miles per hour...
you're gonna see some serious shit. */

renderer = new THREE.WebGLRenderer(); /* Rendererererers particles. */
renderer.setPixelRatio(window.devicePixelRatio); /* Probably 1; unless you're fancy. */
renderer.setSize(WIDTH, HEIGHT); /* Full screen baby Wooooo! */

container.appendChild(renderer.domElement); /* Let's add all this crazy junk to the page. */

/* I don't know about you, but I like to know how bad my
code is wrecking the performance of a user's machine.
Let's see some damn stats! */

stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.right = '0px';
container.appendChild(stats.domElement);

/* Event Listeners */

window.addEventListener('resize', onWindowResize, false);
document.addEventListener('mousemove', onDocumentMouseMove, false);
document.addEventListener('touchstart', onDocumentTouchStart, false);
document.addEventListener('touchmove', onDocumentTouchMove, false);

}

function animate() {
requestAnimationFrame(animate);
render();
stats.update();
}

function render() {
var time = Date.now() * 0.00005;

camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;

camera.lookAt(scene.position);

for (i = 0; i < scene.children.length; i++) {

var object = scene.children[i];

if (object instanceof THREE.PointCloud) {

object.rotation.y = time * (i < 4 ? i + 1 : -(i + 1));
}
}

for (i = 0; i < materials.length; i++) {

color = parameters[i][0];

h = (360 * (color[0] + time) % 360) / 360;
materials[i].color.setHSL(h, color[1], color[2]);
}

renderer.render(scene, camera);
}

function onDocumentMouseMove(e) {
mouseX = e.clientX - windowHalfX;
mouseY = e.clientY - windowHalfY;
}

/* Mobile users? I got your back homey */

function onDocumentTouchStart(e) {

if (e.touches.length === 1) {

e.preventDefault();
mouseX = e.touches[0].pageX - windowHalfX;
mouseY = e.touches[0].pageY - windowHalfY;
}
}

function onDocumentTouchMove(e) {

if (e.touches.length === 1) {

e.preventDefault();
mouseX = e.touches[0].pageX - windowHalfX;
mouseY = e.touches[0].pageY - windowHalfY;
}
}

function onWindowResize() {

windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
})();
</script>

</body>

</html>