序言
今天我们来尝试写一个酷炫的小Demo,之前在某博客类网站(好像记得不清楚噜OwO)看见一个很有意思的动态背景,在文章后面有很多粒子星星,当我们鼠标在页面上滑动的时候,这个背景还能根据我们的鼠标滑动进行场景的旋转,于是我们今天也来尝试一下,写一个这样的Demo,话不多说,先看效果🥰🥰🥰
接下来我会从Demo中的Html重要代码和JS重要代码开始来为大家解释,搞清楚这个Demo的实现过程🐱🏍🐱🏍🐱🏍
Html
代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>粒子化</title>
<style>
*{
margin: 0;
padding: 0;
}
html,body{
width: 100%;
height: 100%;
}
#container{
color:red;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.150.1/three.js"></script>
<script src="./index.js"></script>
</body>
</html>
Html代码解释
首先我们一共需要用到Three.js,CSS,HTMl来实现今天的Demo。所以在Html文件中我们分别对Three.js库进行引用以及一个名为index.js的外部JavaScript文件。
主体部分
html
<body>
<!-- 带有id "container"的容器div -->
<div id="container"></div>
<!-- Three.js库和自定义JavaScript文件的脚本标签 -->
<script src="https://cdn.bootcdn.net/ajax/libs/three.js/0.150.1/three.js"></script>
<script src="./index.js"></script>
</body>
主体部分我们添加一个带有id为"container"
的容器div用来将所有元素添加到这个容器中,然后引用Three.js库和我自己自定义的JavaScript文件。
CSS部分
-
* { margin: 0; padding: 0; }
:- 这里我们选择所有元素(通配符 * 表示所有元素)并将它们的外边距和内边距都设置为0。这是为了消除不同浏览器默认样式的差异,用来实现在不同浏览器中呈现出一致的外观。
-
html, body { width: 100%; height: 100%; }
:- 选择 HTML 元素和 body 元素,并将它们的宽度和高度都设置为100%。这样就可以确保 HTML 和 body 占据整个浏览器窗口。
-
#container { color: red; width: 100%; height: 100%; }
:- 选择 id 为 "container" 的元素,并将其文本颜色设置为红色、容器的宽度和高度设置为100%。因为之前我们将所有元素的外边距和内边距都设为0,但是这里我们需要其有特殊效果,所以这里会覆盖原来的样式。
总的来说,我们这个StyleCSS的目的就是确保整个页面充满整个浏览器窗口,并且消除了默认的外边距和内边距,使得不同浏览器上的渲染效果更加一致。其中id为
container
的容器里面的文本元素颜色设置为红色并且出现在整个浏览器窗口。
这里我将CSS部分直接写在了HTML中,实际当样式部分过多时应该将代码模块化编写,单独写在一个文件中,或者用Vue框架编写实现代码的复用等等,这里我们CSS样式代码不多,我就直接放一起了哈👻👻👻
JS
代码
js
let scene;
let camera;
let renderer;
let material;
let mouseX = 0;
let mouseY = 0;
function init() {
// 创建透视相机
camera = new THREE.PerspectiveCamera();
camera.position.z = 500;
// 创建场景,并设置雾效果
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x000ff, 0.001);
// 创建粒子的几何体
const geometry = new THREE.BufferGeometry();
var vertices = [];
const size = 2000;
// 随机生成大量粒子的坐标
for (let i = 0; i < 20000; i++) {
const x = (Math.random() * size + Math.random() * size) / 2 - size / 2;
const y = (Math.random() * size + Math.random() * size) / 2 - size / 2;
const z = (Math.random() * size + Math.random() * size) / 2 - size / 2;
vertices.push(x, y, z);
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
// 创建粒子的材质
material = new THREE.PointsMaterial({
size: 2,
color: 0xffffff
});
// 使用几何体和材质创建粒子系统
const particles = new THREE.Points(geometry, material);
// 将粒子系统添加到场景中
scene.add(particles);
// 创建 WebGL 渲染器
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// 渲染场景并将结果添加到 DOM 中
document.getElementById('container').appendChild(renderer.domElement);
// 监听鼠标移动事件
document.getElementById('container').addEventListener('pointermove', onPointermove);
}
// 初始化函数
init();
// 启动动画循环
animate();
function animate() {
// 控制摄像头动起来
requestAnimationFrame(animate);
render();
}
function render() {
// 控制相机位置和朝向
camera.position.x += (mouseX * 2 - camera.position.x) * 0.02;
camera.position.y += (-mouseY * 2 - camera.position.y) * 0.02;
camera.lookAt(scene.position);
// 渲染场景
renderer.render(scene, camera);
// 使场景自旋
scene.rotation.x += 0.001;
scene.rotation.y += 0.002;
}
function onPointermove(event) {
// 更新鼠标位置
mouseX = event.clientX - (window.innerWidth / 2);
mouseY = event.clientY - (window.innerHeight / 2);
}
JS代码解释
-
全局变量:
scene
,camera
,renderer
,material
: 我们首先创建了这四个变量用于存储Three.js场景
、相机
、渲染器
和粒子材质
。mouseX
,mouseY
: 用于记录鼠标的位置(X、Y分别代表从浏览器窗口左上原点开始的横坐标和纵坐标)。
-
初始化函数 (
init
):- 创建透视相机 (
PerspectiveCamera
) 并设置其位置。 - 创建场景 (
Scene
) 并设置雾效果。 - 创建粒子的几何体 (
BufferGeometry
)。 - 通过循环生成大量粒子的随机坐标,并将它们存储在顶点数组中。
- 将顶点数组设置为几何体的位置属性。
- 创建粒子的材质 (
PointsMaterial
)。 - 使用几何体和材质创建粒子系统 (
Points
)。 - 将粒子系统添加到场景中。
- 创建 WebGL 渲染器,并将其添加到页面中。
- 监听鼠标移动事件。
- 创建透视相机 (
-
动画循环 (
animate
):- 使用
requestAnimationFrame
实现动画循环,不断调用render
函数。
- 使用
-
渲染函数 (
render
):- 控制相机位置和朝向,使其根据鼠标位置进行变化。
- 使用
lookAt
方法确保相机一直朝向场景的中心。 - 渲染场景。
-
鼠标移动事件处理函数 (
onPointermove
):- 更新
mouseX
和mouseY
变量,以记录鼠标相对于窗口中心的偏移。
- 更新
总的来说,我们首先需要通过Three.js库创建一个包含粒子效果的交互式3D场景。然后我们用到了透视相机,并且创建了一个有雾效果的场景,然后生成大量的随机粒子并添加合适的样式来模拟夜空中的繁星,并在鼠标移动时动态调整相机的位置,这样就可以实现动态视角的切换。今天这个代码给大家演示了如何使用Three.js库创建一个简单的粒子效果,并通过交互动态改变场景的展示。
结语
那么到了这里我们今天的文章就结束啦~
创作不易,如果感觉这个文章对你有帮助的话,点个赞吧♥
更多内容:用 HTML5实战打击乐Demo 虚拟类应用开发你真的掌握吗?
博主的开源Git仓库: gitee.com/cheng-bingw...