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

目录
  • 前言
  • 一、效果图
  • 二、代码
  • 三、背景图片素材
  • 总结

前言

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

一、效果图

先上最终效果图:

具体效果可参考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>

三、背景图片素材

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

如下图所示

总结

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

(0)

相关推荐

  • vue页面引入three.js实现3d动画场景操作

    vue中安装Three.js 近来无聊顺便研究一些关于3D图形化库.three.js是JavaScript编写的WebGL第三方库.Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它通过控制相机.视角.材质等相关属性来创造大量3D动画场景. 我们开始引入three.js相关插件. 1.首先利用淘宝镜像,操作命令为: cnpm install three 2.接下来利用npm安装轨道控件插件: 关注我的微信公众号[前端基础教程从0开始],加我微信,可以免费为您解答问题.回复"1&qu

  • vue中利用three.js实现全景图的完整示例

    粗暴一点,直接上代码: 第一步: 通过指令下载three.js npm install three -S 第二步: 在组件中引用 import * as THREE from 'three' 第三步: html部分 <div id="container"></div> js部分 <script> import * as THREE from 'three'; var camera; var renderer; var scene; export de

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

    目录 前言 一.效果图 二.代码 三.背景图片素材 总结 前言 Threejs可以理解为是一个web端三维引擎(渲染模型,数据可视化),如果有接触过UnralEngine 4(虚幻四)等游戏引擎的,应该很容易理解在一个三维场景必备的每一个部件(场景,渲染器,网格模型,材质,光源,色相机).好的,基础知识咱们先跳过,直接上实现的过程 一.效果图 先上最终效果图: 具体效果可参考iview官方界面iView - 一套高质量的UI组件库 大波浪效果,使用的是three.js的官方例子,需要先安装thr

  • 使用jQuery仿苹果官网焦点图特效

    这次我们要分享的这款jQuery焦点图非常特别,它的外观特别简单,但是又相当大气.焦点图的整体样式是仿苹果样式的,由于jQuery的运用,我们只要点击图片下方的缩略图即可达到图片切换的焦点图特效,这款jQuery焦点图插件非常适合在产片展示的网页上使用. 接下来我们一起分享一下实现这款苹果焦点图的过程及源码. HTML代码: 复制代码 代码如下: <div id="gallery">     <div id="slides" style="

  • JavaScript仿小米官网注册登录功能的实现

    目录 首先我们需要搭建好页面布局 JS功能1 JS功能2 JS功能3 JS功能4 效果图如下: 首先我们需要搭建好页面布局 html的代码如下: ​ <div class="contentrightbottom"> <div class="contentrightbottombox"> <div class="crbottomlogin"> <div class="login">

  • Threejs实现滴滴官网首页地球动画功能

    偶然翻滴滴官网看到首页下翻第六栏(大概)有个绚丽的地球的三维动画,试着用there.js实现了下,基本实现了动画效果,不过还是有些问题:这个动画看似简单,但也用到好的绘制方法和计算,这里先写一下主要功能的实现: 先看示例:http://39.106.166.212:8080/webgl/t4(由于是写dome的一个项目,内容较多没做优化,第一次加载会会比较慢,需多等待几秒) (lice这个截图工具也是很不好用,每次都截到一半 ╮(╯﹏╰)╭) 一. 3d绘制场景的构建 绘制一个3d程序首先需要添

  • JavaScript仿小米商城官网完整页面实现流程

    目录 一.首页的制作 1.下载APP的制作 2.导航栏的制作 3.轮播图的制作 二.登录.注册页面的制作 1.盒子布局 2.复选框样式更改 三.页面跳转 不知不觉学习前端已经快4个月啦,之前没学JavaScript之前做的项目都只能看不能玩,小米官网这个页面算上写出的第一个相对完整一点的项目,虽然需要进步的地方还有很多,但是未来可期! 本篇博客主要是针对在书写这个项目时遇到的一些问题,找出对应的方法,记录一下自己在写这个项目时踩过的坑. 一.首页的制作 首页的主要效果有如下几个: 下载APP.购

  • js仿小米官网图片轮播特效

    小米官网给我的感觉是大气.干净.很多特效的加入让人觉得耳目一新,big满满. 看到他们首页的轮播图实现挺有意思,于是自己模仿着写了一个. 大致的感觉出来了,贴个图先: 通过前端神器chrom的F12观察小米官网的html代码,不难看到他们使用5个div包裹图片并使用了定位通过z-index来控制div层级,通过控制每个div的opacity属性和display属性进行元素的显示.隐藏. 截图如下(红框内的opacity属性): 好的,实现的手段知道了,那么页面布局先搞出来. <!DOCTYPE

  • jQuery + html + css 实现王者荣耀官网首页效果 附实例代码

    访问地址 reset.css /** * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/) * http://cssreset.com */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, cod

  • ThinkPHP实现ajax仿官网搜索功能实例

    本文实例讲述了ThinkPHP实现ajax仿官网搜索功能的方法.分享给大家供大家参考. 具体实现方法如下: 后台代码: 复制代码 代码如下: //搜索,如果在1不在0  function search(){      $keyword = $_POST['search'];      $Goods=M('goods');    //这里我做的一个模糊查询到名字或者对应的id,主要目的因为我这个系统是    //商城系统里面用到直接看产品ID      $map['goods_id|goods_n

  • 利用Vue3+Element-plus实现大文件分片上传组件

    目录 一.背景 二.技术栈 三.核心代码实现 四.总结 一.背景 实际项目中遇到需要上传几十个G的3d模型文件,传统上传就不适用了. 结合element提供的上传组件自己封装了文件分片上传的组件. 思路: 把文件拆分成若干分片 依次上传分片(每次上传前可校验该分片是否已经上传) 发起合并分片的请求 二.技术栈 Vue3+Ts+Element-Plus 其他库:spark-md5 后端接口: 上传分片接口 校验分片是否已上传接口 合并分片接口 三.核心代码实现 Element组件基础配置 <el-

  • 利用vue3+ts实现管理后台(增删改查)

    简单的管理后台基本上就是数据的增删改查.主要就是 列表 + form 表单.每个页面的逻辑基本上都相同.不同的地方就是每个页面需要调用的具体 API 及参数. 以前 vue2 的时候最简单的做法是写出来一个页面的逻辑,然后直接 copy 到各个页面中,修改 API 及参数即可.高级一点的是利用 mixin 函数,将可复用逻辑抽离,每个页面引入 mixin. vue3 之后新增了composition API.本文就是利用composition API,将可复用的逻辑抽离到composition

随机推荐