利用vue3+threejs仿iView官網(wǎng)大波浪特效實(shí)例
前言
Threejs可以理解為是一個(gè)web端三維引擎(渲染模型,數(shù)據(jù)可視化),如果有接觸過(guò)UnralEngine 4(虛幻四)等游戲引擎的,應(yīng)該很容易理解在一個(gè)三維場(chǎng)景必備的每一個(gè)部件(場(chǎng)景,渲染器,網(wǎng)格模型,材質(zhì),光源,色相機(jī))。好的,基礎(chǔ)知識(shí)咱們先跳過(guò),直接上實(shí)現(xiàn)的過(guò)程
一、效果圖
先上最終效果圖:
具體效果可參考iview官方界面iView - 一套高質(zhì)量的UI組件庫(kù)
大波浪效果,使用的是three.js的官方例子,需要先安裝three.js支持,具體可以看官方實(shí)例 three.js examples (threejs.org)
二、代碼
1.安裝threejs
npm install --save three
2.代碼(復(fù)制可用) components文件夾新建組件waves.vue,直接復(fù)制代碼如下,可直接運(yùn)行:
<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軸波浪的長(zhǎng)度 amountX: { type: Number, default: 50, }, //控制y軸波浪的長(zhǎng)度 amountY: { type: Number, default: 50, }, //控制點(diǎn)顏色 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); //創(chuàng)建透視相機(jī) camera = new THREE.PerspectiveCamera( 75, //攝像機(jī)視錐體垂直視野角度 window.innerWidth / window.innerHeight, //攝像機(jī)視錐體長(zhǎng)寬比 1, //攝像機(jī)視錐體近端面 10000 //攝像機(jī)視錐體遠(yuǎn)端面 ); //設(shè)置相機(jī)z軸視野 camera.position.z = 1000; //創(chuàng)建場(chǎng)景 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++; } } //是面片、線或點(diǎn)幾何體的有效表述。包括頂點(diǎn)位置,面片索引、法相量、顏色值、UV 坐標(biāo)和自定義緩存屬性值。使用 BufferGeometry 可以有效減少向 GPU 傳輸上述數(shù)據(jù)所需的開(kāi)銷 const geometry = new THREE.BufferGeometry(); geometry.setAttribute( "position", new THREE.BufferAttribute(positions, 3) ); geometry.setAttribute("scale", new THREE.BufferAttribute(scales, 1)); //著色器材質(zhì)(ShaderMaterial),設(shè)置球的大小,顏色,等 const material = new THREE.ShaderMaterial({ uniforms: { //設(shè)置球的顏色 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 );}", }); //一個(gè)用于顯示點(diǎn)的類。 particles = new THREE.Points(geometry, material); //往場(chǎng)景中添加點(diǎn) scene.add(particles); //alpha - canvas是否包含alpha (透明度)。默認(rèn)為 false。 //渲染器的背景色默認(rèn)為黑色,設(shè)置渲染器的背景色為透明 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"; //監(jiān)聽(tīng)鼠標(biāo)移動(dòng)事件 container.addEventListener("pointermove", onPointerMove); //調(diào)整波浪的位置 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; // 設(shè)置粒子位置和大小 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); } //監(jiān)聽(tīng)鼠標(biāo)移動(dòng)事件 function onPointerMove(event) { console.log(event); if (event.isPrimary === false) return; mouseX = event.clientX - windowHalfX; } function animate() { requestAnimationFrame(animate); render(); //fps 實(shí)時(shí)更新 // 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>
3.使用
直接在login登錄頁(yè)面引入組件使用
<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 - 一套高質(zhì)量的UI組件庫(kù)
如下圖所示
總結(jié)
到此這篇關(guān)于利用vue3 + threejs仿iView官網(wǎng)大波浪特效的文章就介紹到這了,更多相關(guān)vue3+threejs仿大波浪特效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)表單單獨(dú)移除一個(gè)字段驗(yàn)證
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)表單單獨(dú)移除一個(gè)字段驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03vue實(shí)現(xiàn)簡(jiǎn)單無(wú)縫滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)簡(jiǎn)單無(wú)縫滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04vue實(shí)現(xiàn)聊天框自動(dòng)滾動(dòng)的示例代碼
本文主要介紹了vue實(shí)現(xiàn)聊天框自動(dòng)滾動(dòng)的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05實(shí)例詳解vue.js淺度監(jiān)聽(tīng)和深度監(jiān)聽(tīng)及watch用法
這篇文章主要介紹了vue.js淺度監(jiān)聽(tīng)和深度監(jiān)聽(tīng)及watch用法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-08-08Vue中Number方法將字符串轉(zhuǎn)換為數(shù)字的過(guò)程
這篇文章主要介紹了Vue中Number方法將字符串轉(zhuǎn)換為數(shù)字,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06Vue3組合式函數(shù)Composable實(shí)戰(zhàn)ref和unref使用
這篇文章主要為大家介紹了Vue3組合式函數(shù)Composable實(shí)戰(zhàn)ref和unref使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06