前言
🔥🔥🔥小白实战🔥🔥🔥
今天,我们来学习如何打造一个粒子化星空的效果!!!
正文
今天我们来学习,如何利用我们的html
打造一个粒子化星空效果!
在我们的页面中有着无数的小粒子随机的分布在整个页面空间当中。并且这些粒子是在飘动的,同时粒子的飘动能够随着随着鼠标的移动和移动。
首先上效果图:

要实现这样一个效果!我们需要一个html
文件和js
文件。
实现html
文件-实现JS引入和页面样式
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
文件中:
- 我们首先建立了一个
id
为container
的div
图层 - 引入了一个在线
three.js
库文件 - 引入了本地的
index.js
文件,实现3D效果渲染和鼠标动画设置。
在head
中的style
中设置样式:
css
* {
margin: 0;
padding: 0;
}
初始化页面的内外边距。以便在不同的页面上效果相同。
css
html, body {
width: 100%;
height: 100%;
}
让body
的高度和宽度覆盖住整个屏幕。
css
#container{
color: red;
width: 100%;
height: 100%;
}
创建了一个全屏的红色容器。
好啦!写好我们的html
文件之后,来到我们最最最重要的3D渲染环节
编写JS文件-实现3D渲染的效果和动作编排
我们的js文件是基于Three.js创建的3D渲染场景(Three.js是一个运行在浏览器上的3D库)实现你需要的3D效果。
1.首先,我们声明let scene, camear, renderer, material, mouseX = 0, mouseY = 0
六个变量,其中前五个是用来存储Three.js场景、相机、渲染器、材质以及鼠标位置的。
javascript
let scene
let camear
let renderer
let material
let mouseX = 0
let mouseY = 0
2.我们定义了一个function init()
函数在这个函数中:
- 我们用
camear = new THREE.PerspectiveCamera()
:创建一个透视相机,这是用来捕捉3D场景的。 - 我们设置相机的位置在z轴方向为500
camear.position.z = 500
- 我们创建一个新的3D场景
scene = new THREE.Scene()
。 - 我们场景设置一种雾效果。
scene.fog = new THREE.FogExp2(0x000ff, 0.001)
- 我们创建一个新的BufferGeometry对象,这是用于存储3D对象的顶点和索引的数据。
const geometry = new THREE.BufferGeometry()
- 创建一个数组来存储顶点的位置
var vertices = []
。 - 定义一个常数变量
size
,值为2000:const size = 2000
- 接下来的for循环用于生成20000个随机的顶点位置,这些顶点将被用于创建粒子效果。
- 将顶点数据添加到geometry对象的'position'属性中。每个顶点的位置由三个数字(x,y,z)表示,因此使用了
THREE.Float32BufferAttribute
所以我们可以写这样一段代码:geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3))
- 创建一个点材质模型,设置点的大小为2,颜色为白色
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)
- 使用渲染器将场景渲染到屏幕上:
renderer.render(scene, camear)
document.getElementById('container').appendChild(renderer.domElement)
将渲染器的DOM元素添加到id为"container"的HTML元素中。document.getElementById('container').addEventListener('pointermove', onPointerMove)
:为"container"元素添加了一个鼠标移动事件监听器,当鼠标在元素上移动时,会调用onPointerMove
函数
于是我们可以写出这样一段函数:
js
function init() {
camear = new THREE.PerspectiveCamera()
camear.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)
renderer = new THREE.WebGLRenderer()
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.render(scene, camear)
document.getElementById('container').appendChild(renderer.domElement)
document.getElementById('container').addEventListener('pointermove', onPointerMove)
}
3.定义function animate()
函数控制摄像头动起来!!动画函数,通过requestAnimationFrame
来实现动画循环。在每一帧动画中,都会调用render
函数来渲染场景,动画循环。
js
function animate() {
// 控制摄像头动起来
requestAnimationFrame(animate)
render()
}
4.定义function render()
函数,负责渲染场景。它更新相机的位置以跟踪鼠标,并将场景渲染到屏幕上。
js
function render() {
camear.position.x += (mouseX * 2 - camear.position.x) * 0.02
camear.position.y += (-mouseY * 2 - camear.position.y) * 0.02
camear.lookAt(scene.position)
renderer.render(scene, camear)
scene.rotation.x += 0.001
scene.rotation.y += 0.002
}
在这一段代码当中,我们进行逐行分析!!:
camear.position.x += (mouseX * 2 - camear.position.x) * 0.02
:这一行根据鼠标在水平方向上的位置(mouseX
)来改变相机的x坐标。这个效果是当你移动鼠标时,相机将会在x轴方向上平移。camear.position.y += (-mouseY * 2 - camear.position.y) * 0.02
:这一行根据鼠标在垂直方向上的位置(mouseY
)来改变相机的y坐标。这个效果是当你移动鼠标时,相机将会在y轴方向上平移。camear.lookAt(scene.position)
:这一行使相机始终朝向场景的原点(scene.position
)。这意味着当你移动相机时,它会始终面对场景的中心。renderer.render(scene, camear)
:这一行使用WebGL渲染器将当前场景和相机配置渲染到屏幕上。scene.rotation.x += 0.001
:这一行会使场景绕x轴旋转一小部分(大约0.1度)。scene.rotation.y += 0.002
:这一行会使场景绕y轴旋转一小部分(大约0.2度)。
5.定义function onPointerMove(event)
实现当鼠标在"container"元素上移动时,此函数被调用。它将鼠标的x和y坐标进行一些计算后存储在mouseX
和mouseY
变量中,这些值随后被用于更新相机和场景的位置。
js
function onPointerMove(event) {
mouseX = event.clientX - (window.innerWidth / 2)
mouseY = event.clientY - (window.innerHeight / 2)
}
JS文件总览
js
let scene
let camear
let renderer
let material
let mouseX = 0
let mouseY = 0
function init() {
camear = new THREE.PerspectiveCamera()
camear.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)
renderer = new THREE.WebGLRenderer()
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.render(scene, camear)
document.getElementById('container').appendChild(renderer.domElement)
document.getElementById('container').addEventListener('pointermove', onPointerMove)
}
init()
animate()
function animate() {
// 控制摄像头动起来
requestAnimationFrame(animate)
render()
}
function render() {
camear.position.x += (mouseX * 2 - camear.position.x) * 0.02
camear.position.y += (-mouseY * 2 - camear.position.y) * 0.02
camear.lookAt(scene.position)
renderer.render(scene, camear)
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)
}
最后
我们粒子化星空的效果就这样实现了!!!

如果大家有任何想法和改进欢迎大家评论留言!!点个小赞支持一下吧!!🌹🌹🌹