likes
comments
collection
share

🌟🌟🌟用Three.js写一个简单的3D粒子小Demo🌠🌠🌠

作者站长头像
站长
· 阅读数 10

序言

今天我们来尝试写一个酷炫的小Demo,之前在某博客类网站(好像记得不清楚噜OwO)看见一个很有意思的动态背景,在文章后面有很多粒子星星,当我们鼠标在页面上滑动的时候,这个背景还能根据我们的鼠标滑动进行场景的旋转,于是我们今天也来尝试一下,写一个这样的Demo,话不多说,先看效果🥰🥰🥰

🌟🌟🌟用Three.js写一个简单的3D粒子小Demo🌠🌠🌠

接下来我会从Demo中的Html重要代码和JS重要代码开始来为大家解释,搞清楚这个Demo的实现过程🐱‍🏍🐱‍🏍🐱‍🏍

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文件。

主体部分

<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部分

  1. * { margin: 0; padding: 0; }

    • 这里我们选择所有元素(通配符 * 表示所有元素)并将它们的外边距和内边距都设置为0。这是为了消除不同浏览器默认样式的差异,用来实现在不同浏览器中呈现出一致的外观。
  2. html, body { width: 100%; height: 100%; }

    • 选择 HTML 元素和 body 元素,并将它们的宽度和高度都设置为100%。这样就可以确保 HTML 和 body 占据整个浏览器窗口。
  3. #container { color: red; width: 100%; height: 100%; }

    • 选择 id 为 "container" 的元素,并将其文本颜色设置为红色、容器的宽度和高度设置为100%。因为之前我们将所有元素的外边距和内边距都设为0,但是这里我们需要其有特殊效果,所以这里会覆盖原来的样式。

总的来说,我们这个StyleCSS的目的就是确保整个页面充满整个浏览器窗口,并且消除了默认的外边距和内边距,使得不同浏览器上的渲染效果更加一致。其中id为container的容器里面的文本元素颜色设置为红色并且出现在整个浏览器窗口。

这里我将CSS部分直接写在了HTML中,实际当样式部分过多时应该将代码模块化编写,单独写在一个文件中,或者用Vue框架编写实现代码的复用等等,这里我们CSS样式代码不多,我就直接放一起了哈👻👻👻

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代码解释

  1. 全局变量:

    • scene, camera, renderer, material: 我们首先创建了这四个变量用于存储Three.js场景相机渲染器粒子材质
    • mouseX, mouseY: 用于记录鼠标的位置(X、Y分别代表从浏览器窗口左上原点开始的横坐标和纵坐标)。
  2. 初始化函数 (init):

    • 创建透视相机 (PerspectiveCamera) 并设置其位置。
    • 创建场景 (Scene) 并设置雾效果。
    • 创建粒子的几何体 (BufferGeometry)。
    • 通过循环生成大量粒子的随机坐标,并将它们存储在顶点数组中。
    • 将顶点数组设置为几何体的位置属性。
    • 创建粒子的材质 (PointsMaterial)。
    • 使用几何体和材质创建粒子系统 (Points)。
    • 将粒子系统添加到场景中。
    • 创建 WebGL 渲染器,并将其添加到页面中。
    • 监听鼠标移动事件。
  3. 动画循环 (animate):

    • 使用 requestAnimationFrame 实现动画循环,不断调用 render 函数。
  4. 渲染函数 (render):

    • 控制相机位置和朝向,使其根据鼠标位置进行变化。
    • 使用 lookAt 方法确保相机一直朝向场景的中心。
    • 渲染场景。
  5. 鼠标移动事件处理函数 (onPointermove):

    • 更新 mouseXmouseY 变量,以记录鼠标相对于窗口中心的偏移。

总的来说,我们首先需要通过Three.js库创建一个包含粒子效果的交互式3D场景。然后我们用到了透视相机,并且创建了一个有雾效果的场景,然后生成大量的随机粒子并添加合适的样式来模拟夜空中的繁星,并在鼠标移动时动态调整相机的位置,这样就可以实现动态视角的切换。今天这个代码给大家演示了如何使用Three.js库创建一个简单的粒子效果,并通过交互动态改变场景的展示。

结语

那么到了这里我们今天的文章就结束啦~

创作不易,如果感觉这个文章对你有帮助的话,点个赞吧♥