threeJs实现波纹扩散及光标浮动效果详解

Three.js实现波纹扩散及光标浮动效果详解

概述

本教程将介绍如何使用Three.js库实现波纹扩散效果及光标浮动效果。波纹扩散效果常见于网页设计中,而光标浮动效果则经常出现在用户交互的UI设计中。

本文主要分为以下三个部分:

  1. 前置知识
  2. 波纹扩散效果实现
  3. 光标浮动效果实现

本文中的所有代码都可在 codepen 中找到。

一、前置知识

要实现本教程中的效果,需要有一定的WebGL以及Three.js基础。

如果你需要进行回顾或学习,可以看看 Three.js官方文档 或者 WebGL Fundamentals

二、波纹扩散效果实现

下面将详细介绍如何使用Three.js库实现波纹扩散效果。

1. 创建场景

在 HTML 中创建一个容器(例如一个div标签),并指定其宽度和高度,作为Three.js场景的载体。

<div id="canvas-container"></div>

在 JS 中,使用 THREE 对象创建场景、相机和渲染器。

const container = document.getElementById('canvas-container');
const renderer = new THREE.WebGLRenderer({ antialias: true });
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);

renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement);

camera.position.z = 10;

2. 创建网格

使用 Three.js 中的 Mesh 类创建一个平面网格,作为波纹的扩散面。

const geometry = new THREE.PlaneBufferGeometry(10, 10, 500, 500);
const material = new THREE.MeshBasicMaterial({ color: 0x7ec0ee });
const mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);

3. 实现shader

在Three.js的材质中,使用自定义的着色器代码是可以实现更加复杂的视觉效果的。这里,我们需要实现一个实时扩散波纹的着色器。

首先,在 HTML 文件中添加一个代表着色器的script标签。

<script type="x-shader/x-vertex" id="vertexShader">
  void main() {
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
  uniform float time;
  uniform vec2 resolution;

  const float speed = 0.1;
  const float frequency = 30.0;

  void main() {
    vec2 uv = gl_FragCoord.xy / resolution.xy;
    vec2 o = vec2(0.5, 0.5);
    vec2 ref = vec2(0.5, 0.5);
    float dist = distance(ref, uv);
    float radius = smoothstep(0.15, 0.51, fract(time * speed));

    gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0) * (1.0 - smoothstep(radius, radius + 0.005, dist));
  }
</script>

着色器代码中,我们用了两个 uniform 变量,time 和 resolution。

这里的time变量代表当前的时间,它在每帧渲染时都会更新。

$resolution$ 是屏幕尺寸,我们把它传入到着色器中作为一个uniform变量。

界面的波纹扩散效果通过改变radius来实现。从代码中你可以看到,radius的值由一个smoothstep函数产生。当时间增加时,参数x对应的值将从0到1变化,而smoothstep(x, y, a)返回一个在x和y之间的a的平滑插值,使得x到y之间的变化更加平稳。

最后,我们需要把着色器代码编译成 THREE.ShaderMaterial() 来使用。

const vertexShader = document.getElementById('vertexShader').textContent;
const fragmentShader = document.getElementById('fragmentShader').textContent;

const uniforms = {
  time: { value: 0 },
  resolution: { value: new THREE.Vector2(container.offsetWidth, container.offsetHeight) },
};
const material = new THREE.ShaderMaterial({
  uniforms,
  vertexShader,
  fragmentShader,
});

mesh.material = material;

4. 实现动画

最后,我们需要在每一帧中更新 uniforms 中的 time,以便在材料中使用。

function animate() {
  requestAnimationFrame(animate);

  mesh.material.uniforms.time.value = performance.now() / 1000;

  renderer.render(scene, camera);
}

animate();

三、光标浮动效果实现

下面将详细介绍如何使用Three.js库实现光标浮动效果。

1. 创建场景

和上面的步骤一致,我们需要在 HTML 中创建一个容器以及在 JS 中创建一个场景、相机和渲染器。

const container = document.getElementById('canvas-container');
const renderer = new THREE.WebGLRenderer({ antialias: true });
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);

renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild(renderer.domElement);

camera.position.z = 10;

2. 添加网格

使用 Three.js 中的 Mesh 类创建一个浮动网格,作为光标的浮动面。

const geometry = new THREE.PlaneBufferGeometry(1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0xffffff });
const mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);

3. 实现鼠标跟踪

当鼠标移动时,我们需要把单击位置转换成屏幕空间坐标。此时需要使用 THREE.Vector2()THREE.Raycaster()

const mouse = new THREE.Vector2();
const raycaster = new THREE.Raycaster();

container.addEventListener('mousemove', onDocumentMouseMove, false);

function onDocumentMouseMove(event) {
  mouse.x = (event.clientX / container.offsetWidth) * 2 - 1;
  mouse.y = - (event.clientY / container.offsetHeight) * 2 + 1;
}

4. 实现动画

最后,我们需要在每一帧中更新网格的位置,使其跟随鼠标移动。

function animate() {
  requestAnimationFrame(animate);

  mesh.position.x += (mouse.x * 10 - mesh.position.x) * 0.1;
  mesh.position.y += (mouse.y * 10 - mesh.position.y) * 0.1;

  renderer.render(scene, camera);
}

animate();

结论

到这里,我们已经成功实现了波纹扩散效果和光标浮动效果。

以上代码也可在 codepen 中找到,并可以进行自由修改和运行。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:threeJs实现波纹扩散及光标浮动效果详解 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 可以读取EXCEL文件的js代码第1/2页

    下面我来详细讲解一下如何读取Excel文件的JS代码攻略。 1. 使用JavaScript的FileReader对象 使用JavaScript的FileReader对象可以读取文件。下面是读取Excel文件的演示代码。 var reader = new FileReader(); reader.onload = function (e) { var data…

    JavaScript 2023年5月27日
    00
  • JS实现字符串中去除指定子字符串方法分析

    下面是对“JS实现字符串中去除指定子字符串方法”的解析和攻略: 什么是JS实现字符串中去除指定子字符串方法? JS实现字符串去除指定子字符串的方法是指通过JS代码编写,去掉字符串中特定的子字符串的方法。这种方法通常使用常规的JS字符串操作函数(如replace()等)来实现。 JS实现字符串中去除指定子字符串方法的解决方案 常见的JS实现字符串中去除指定子字…

    JavaScript 2023年5月28日
    00
  • 小程序云开发初探(小结)

    小程序云开发初探(小结) 本文主要介绍小程序云开发的基础知识和使用方法。小程序云开发是微信小程序提供的一项新功能,可以通过云数据库、云存储和云函数来快速搭建一个完整的小程序。 1. 云开发环境配置 要使用小程序云开发,需要在微信公众平台上创建小程序,并在小程序后台开启云开发。 注册微信小程序账号 登录小程序后台,点击“设置”-“开发设置”,在云开发中开启开发…

    JavaScript 2023年6月10日
    00
  • Move.js入门

    Move.js入门攻略 什么是Move.js Move.js是一个轻量级的JavaScript动画库,用于实现Web页面中的动画效果。它支持常用的CSS动画属性以及自定义路径和缓动效果,同时具有跨浏览器兼容性和高性能特点。 安装Move.js 可以通过以下两种方式来安装Move.js: 从官方网站下载move.min.js文件并引入到HTML文件中: &lt…

    JavaScript 2023年6月10日
    00
  • javascript按钮禁用和启用的效果实例代码

    下面我将详细讲解“JavaScript按钮禁用和启用的效果实例代码”的完整攻略。 禁用按钮 原理:使用disabled属性禁用按钮。 示例代码 HTML代码: <button id="myBtn">提交</button> JavaScript代码: var myBtn = document.getElementBy…

    JavaScript 2023年6月10日
    00
  • 只出现一次的提示信息(js+cookies)

    下面是关于“只出现一次的提示信息(js+cookies)”的详细攻略: 问题描述 常见的网站应用场景是,用户在第一次访问网站时,我们需要给用户一些说明或提示信息,但是当用户再次访问网站时,我们希望这些提示信息仅在第一次访问时出现,之后访问也无需再次出现。 解决方案 我们可以使用js和cookies来解决这个问题。具体实现过程分为以下几条: 1. 判断是否是第…

    JavaScript 2023年6月11日
    00
  • js针对图片加载失败的处理方法分析

    “js针对图片加载失败的处理方法分析”是前端开发中常见的问题之一。下面我会为大家详细讲解一下如何处理图片加载失败的情况。具体攻略分为以下几步: 1. 在HTML中添加图像元素 我们可以在HTML中通过添加<img>元素来加载图片,通常的写法为: <img src="图片地址" alt="图片描述"&g…

    JavaScript 2023年5月28日
    00
  • js中函数调用的两种常用方法使用介绍

    JS中函数调用的两种常用方法是函数声明与函数表达式,下面我将对这两种方法进行介绍和举例子说明。 1. 函数声明 函数声明的形式如下: function functionName(parameters) { //函数体 } 其中,functionName 是函数名,parameters 是参数列表,函数体里面可以写任何合法的 JS 代码。函数声明完之后,我们可…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部