🔥🔥🔥[实战] 小白实战-如何实现"粒子化星空"🔥🔥🔥

前言

🔥🔥🔥小白实战🔥🔥🔥

今天,我们来学习如何打造一个粒子化星空的效果!!!

正文

今天我们来学习,如何利用我们的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文件中:

  1. 我们首先建立了一个idcontainerdiv图层
  2. 引入了一个在线three.js库文件
  3. 引入了本地的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轴方向为500camear.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坐标进行一些计算后存储在mouseXmouseY变量中,这些值随后被用于更新相机和场景的位置。

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)
}

最后

我们粒子化星空的效果就这样实现了!!!

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

相关推荐
中工钱袋11 分钟前
Vue 中地址栏参数与 HTTP 请求参数的同步问题
前端·vue.js·http
一只月月鸟呀13 分钟前
Vue 过滤器 filter(s) 的使用
javascript·vue.js·ecmascript
zzlyx9915 分钟前
设备管理系统功能与.NET+VUE(IVIEW)技术实现
前端·vue.js·view design
秋月华星2 小时前
【flutter】TextField输入框工具栏文本为英文解决(不用安装插件版本
前端·javascript·flutter
—Qeyser3 小时前
用Deepseek写一个 HTML 和 JavaScript 实现一个简单的飞机游戏
javascript·游戏·html
千里码aicood3 小时前
[含文档+PPT+源码等]精品基于Python实现的校园小助手小程序的设计与实现
开发语言·前端·python
青红光硫化黑3 小时前
React基础之React.memo
前端·javascript·react.js
大麦大麦3 小时前
深入剖析 Sass:从基础到进阶的 CSS 预处理器应用指南
开发语言·前端·css·面试·rust·uni-app·sass
GDAL4 小时前
better-sqlite3之exec方法
javascript·sqlite
匹马夕阳5 小时前
基于Canvas和和原生JS实现俄罗斯方块小游戏
javascript·canva可画