记录–vue+three,制作iview大波浪特效

  • 记录–vue+three,制作iview大波浪特效已关闭评论
  • 145 次浏览
  • A+
所属分类:Web前端
摘要

具体效果可参考iview官方界面iView – 一套高质量的UI组件库 大波浪效果,使用的是three.js的官方例子,需要先安装three.js支持


这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--vue+three,制作iview大波浪特效

一、效果图

具体效果可参考iview官方界面iView - 一套高质量的UI组件库

 记录--vue+three,制作iview大波浪特效

大波浪效果,使用的是three.js的官方例子,需要先安装three.js支持

npm install --save three

具体可以看 three.js examples (threejs.org)

二、代码

//添加容器 <div id="iviewUi" />

 

<script> //引入three.js import * as THREE from 'three'   export default {   props: {     amountX: {       type: Number,       default: 50     },     amountY: {       type: Number,       default: 50     },     //控制点颜色     color: {       type: Number,       default: '#097bdb'     },     top: {       type: Number,       default: 350     }   },   data() {     return {       count: 0,       // 用来跟踪鼠标水平位置       mouseX: 0,       windowHalfX: null,       // 相机       camera: null,       // 场景       scene: null,       // 批量管理粒子       particles: null,       // 渲染器       renderer: null     }   },   mounted() {     this.init()     this.animate()   },   methods: {     init: function() {       const SEPARATION = 100       const SCREEN_WIDTH = window.innerWidth       const SCREEN_HEIGHT = window.innerHeight       const container = document.createElement('div')       this.windowHalfX = window.innerWidth / 2       container.style.position = 'relative'       container.style.top = `${this.top}px`       container.style.height = `${(SCREEN_HEIGHT - this.top)}px`       document.getElementById('iviewUi').appendChild(container)         this.camera = new THREE.PerspectiveCamera(75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000)       this.camera.position.z = 1000         this.scene = new THREE.Scene()         const numParticles = this.amountX * this.amountY       const positions = new Float32Array(numParticles * 3)       const scales = new Float32Array(numParticles)       // 初始化粒子位置和大小       let i = 0       let j = 0       for (let ix = 0; ix < this.amountX; ix++) {         for (let iy = 0; iy < this.amountY; iy++) {           positions[i] = ix * SEPARATION - ((this.amountX * SEPARATION) / 2)           positions[i + 1] = 0           positions[i + 2] = iy * SEPARATION - ((this.amountY * SEPARATION) / 2)           scales[j] = 1           i += 3           j++         }       }         const geometry = new THREE.BufferGeometry()       geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3))       geometry.addAttribute('scale', new THREE.BufferAttribute(scales, 1))       // 初始化粒子材质       const material = new THREE.ShaderMaterial({         uniforms: {           color: { value: new THREE.Color(this.color) }         },         vertexShader: `           attribute float scale;           void main() {             vec4 mvPosition = modelViewMatrix * vec4( position, 2.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 );           }         `       })         this.particles = new THREE.Points(geometry, material)       this.scene.add(this.particles)         this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })       this.renderer.setSize(container.clientWidth, container.clientHeight)       this.renderer.setPixelRatio(window.devicePixelRatio)       this.renderer.setClearAlpha(0)       container.appendChild(this.renderer.domElement)         window.addEventListener('resize', this.onWindowResize, { passive: false })       document.addEventListener('mousemove', this.onDocumentMouseMove, { passive: false })       document.addEventListener('touchstart', this.onDocumentTouchStart, { passive: false })       document.addEventListener('touchmove', this.onDocumentTouchMove, { passive: false })     },     render: function() {       this.camera.position.x += (this.mouseX - this.camera.position.x) * 0.05       this.camera.position.y = 400       this.camera.lookAt(this.scene.position)       const positions = this.particles.geometry.attributes.position.array       const scales = this.particles.geometry.attributes.scale.array       // 计算粒子位置及大小       let i = 0       let j = 0       for (let ix = 0; ix < this.amountX; ix++) {         for (let iy = 0; iy < this.amountY; iy++) {           positions[i + 1] = (Math.sin((ix + this.count) * 0.3) * 100) + (Math.sin((iy + this.count) * 0.5) * 100)           scales[j] = (Math.sin((ix + this.count) * 0.3) + 1) * 8 + (Math.sin((iy + this.count) * 0.5) + 1) * 8           i += 3           j++         }       }       // 重新渲染粒子       this.particles.geometry.attributes.position.needsUpdate = true       this.particles.geometry.attributes.scale.needsUpdate = true       this.renderer.render(this.scene, this.camera)       this.count += 0.1     },     animate: function() {       requestAnimationFrame(this.animate)       this.render()     },     onDocumentMouseMove: function(event) {       this.mouseX = event.clientX - this.windowHalfX     },     onDocumentTouchStart: function(event) {       if (event.touches.length === 1) {         this.mouseX = event.touches[0].pageX - this.windowHalfX       }     },     onDocumentTouchMove: function(event) {       if (event.touches.length === 1) {         event.preventDefault()         this.mouseX = event.touches[0].pageX - this.windowHalfX       }     },     onWindowResize: function() {       this.windowHalfX = window.innerWidth / 2       this.camera.aspect = window.innerWidth / window.innerHeight       this.camera.updateProjectionMatrix()       this.renderer.setSize(window.innerWidth, window.innerHeight)     }   } } </script>

三、背景素材

记录--vue+three,制作iview大波浪特效

如果不清晰可以去官方界面拿,如下图所示

 记录--vue+three,制作iview大波浪特效

本文转载于:

https://juejin.cn/post/7038372456519696421

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--vue+three,制作iview大波浪特效