怎么用vue3+threejs实现仿iView官网大波浪特效
这篇文章主要介绍“怎么用vue3+threejs实现仿iView官网大波浪特效”,在日常操作中,相信很多人在怎么用vue3+threejs实现仿iView官网大波浪特效问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用vue3+threejs实现仿iView官网大波浪特效”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
前言
Threejs可以理解为是一个web端三维引擎(渲染模型,数据可视化),如果有接触过UnralEngine 4(虚幻四)等游戏引擎的,应该很容易理解在一个三维场景必备的每一个部件(场景,渲染器,网格模型,材质,光源,色相机)。好的,基础知识咱们先跳过,直接上实现的过程
一、效果图
先上最终效果图:
具体效果可参考iview官方界面iView - 一套高质量的UI组件库
大波浪效果,使用的是three.js的官方例子,需要先安装three.js支持,具体可以看官方实例 three.js examples (threejs.org)
二、代码
安装threejs
npm install --save three
代码(复制可用) components文件夹新建组件waves.vue,直接如下,可直接运行:
<template> <div id="iviewBg"></div></template><script>import * as THREE from "three";显示右上角fps框// import Stats from "./stats.module";import { onMounted } from "vue";export default { props: { //控制x轴波浪的长度 amountX: { type: Number, default: 50, }, //控制y轴波浪的长度 amountY: { type: Number, default: 50, }, //控制点颜色 color: { type: String, default: "#097bdb", }, //控制波浪的位置 top: { type: Number, default: 350, }, }, setup(props) { const SEPARATION = 100; // let stats; let container, camera, scene, renderer; let particles, count = 0; let mouseX = 0; let windowHalfX = window.innerWidth / 2; function init() { container = document.createElement("div"); document.getElementById("iviewBg").appendChild(container); //创建透视相机 camera = new THREE.PerspectiveCamera( 75, //摄像机视锥体垂直视野角度 window.innerWidth / window.innerHeight, //摄像机视锥体长宽比 1, //摄像机视锥体近端面 10000 //摄像机视锥体远端面 ); //设置相机z轴视野 camera.position.z = 1000; //创建场景 scene = new THREE.Scene(); const numParticles = props.amountX * props.amountY; const positions = new Float32Array(numParticles * 3); const scales = new Float32Array(numParticles); let i = 0, j = 0; // 初始化粒子位置和大小 for (let ix = 0; ix < props.amountX; ix++) { for (let iy = 0; iy < props.amountY; iy++) { positions[i] = ix * SEPARATION - (props.amountX * SEPARATION) / 2; // x positions[i + 1] = 0; // y positions[i + 2] = iy * SEPARATION - (props.amountY * SEPARATION) / 2; // z scales[j] = 1; i += 3; j++; } } //是面片、线或点几何体的有效表述。包括顶点位置,面片索引、法相量、颜色值、UV 坐标和自定义缓存属性值。使用 BufferGeometry 可以有效减少向 GPU 传输上述数据所需的开销 const geometry = new THREE.BufferGeometry(); geometry.setAttribute( "position", new THREE.BufferAttribute(positions, 3) ); geometry.setAttribute("scale", new THREE.BufferAttribute(scales, 1)); //着色器材质(ShaderMaterial),设置球的大小,颜色,等 const material = new THREE.ShaderMaterial({ uniforms: { //设置球的颜色 color: { value: new THREE.Color(props.color) }, }, //控制球的大小 vertexShader: "attribute float scale; void main() {vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );gl_PointSize = scale * ( 300.0 / - mvPosition.z );gl_Position = projectionMatrix * mvPosition;}", fragmentShader: "uniform vec3 color;void main() {if ( length( gl_PointCoord - vec2( 0.5, 0.5 ) ) > 0.475 ) discard;gl_FragColor = vec4( color, 1.0 );}", }); //一个用于显示点的类。 particles = new THREE.Points(geometry, material); //往场景中添加点 scene.add(particles); //alpha - canvas是否包含alpha (透明度)。默认为 false。 //渲染器的背景色默认为黑色,设置渲染器的背景色为透明 renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setClearAlpha(0); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); //显示右上角fps框 // stats = new Stats(); // container.appendChild(stats.dom); container.style.touchAction = "none"; //监听鼠标移动事件 container.addEventListener("pointermove", onPointerMove); //调整波浪的位置 container.style.position = "relative"; container.style.top = `${props.top}px`; window.addEventListener("resize", onWindowResize); } function render() { camera.position.x += (mouseX - camera.position.x) * 0.05; camera.position.y = 400; camera.lookAt(scene.position); const positions = particles.geometry.attributes.position.array; const scales = particles.geometry.attributes.scale.array; // 设置粒子位置和大小 let i = 0, j = 0; for (let ix = 0; ix < props.amountX; ix++) { for (let iy = 0; iy < props.amountY; iy++) { positions[i + 1] = Math.sin((ix + count) * 0.3) * 50 + Math.sin((iy + count) * 0.5) * 50; scales[j] = (Math.sin((ix + count) * 0.3) + 1) * 10 + (Math.sin((iy + count) * 0.5) + 1) * 10; i += 3; j++; } } particles.geometry.attributes.position.needsUpdate = true; particles.geometry.attributes.scale.needsUpdate = true; renderer.render(scene, camera); count += 0.1; } function onWindowResize() { windowHalfX = window.innerWidth / 2; camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } //监听鼠标移动事件 function onPointerMove(event) { console.log(event); if (event.isPrimary === false) return; mouseX = event.clientX - windowHalfX; } function animate() { requestAnimationFrame(animate); render(); //fps 实时更新 // stats.update(); } onMounted(() => { init(); animate(); }); return {}; },};</script><style lang="scss" scoped>#iviewBg { width: 100%; height: 100vh; background: url("../assets/wavesBg.png") no-repeat; overflow: hidden;}</style>
使用
直接在login登录页面引入组件使用
<template> <wavesBg :top="250"></wavesBg> <div class="login-container"> </div></template><script>import wavesBg from "../components/wavesBg";export default { name: "", components: { wavesBg, }, setup() { return { }; },};</script>
三、背景图片素材
如果不清晰可以去官方界面f12拿,iView - 一套高质量的UI组件库
如下图所示
到此,关于“怎么用vue3+threejs实现仿iView官网大波浪特效”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341