欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

利用vue3+threejs仿iView官网大波浪特效实例

程序员文章站 2022-03-09 22:58:39
目录前言一、效果图二、代码三、背景图片素材总结前言threejs可以理解为是一个web端三维引擎(渲染模型,数据可视化),如果有接触过unralengine 4(虚幻四)等游戏引擎的,应该很容易理解在...

前言

threejs可以理解为是一个web端三维引擎(渲染模型,数据可视化),如果有接触过unralengine 4(虚幻四)等游戏引擎的,应该很容易理解在一个三维场景必备的每一个部件(场景,渲染器,网格模型,材质,光源,色相机)。好的,基础知识咱们先跳过,直接上实现的过程

一、效果图

先上最终效果图:

利用vue3+threejs仿iView官网大波浪特效实例

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

大波浪效果,使用的是three.js的官方例子,需要先安装three.js支持,具体可以看官方实例 three.js examples (threejs.org)

二、代码

1.安装threejs

npm install --save three

2.代码(复制可用) 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>

3.使用

直接在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>

三、背景图片素材

利用vue3+threejs仿iView官网大波浪特效实例

如果不清晰可以去官方界面f12拿,iview - 一套高质量的ui组件库

如下图所示

利用vue3+threejs仿iView官网大波浪特效实例

总结

到此这篇关于利用vue3 + threejs仿iview官网大波浪特效的文章就介绍到这了,更多相关vue3+threejs仿大波浪特效内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!