Using vue3+threejs to imitate the iView official website big wave special effects example

Using vue3+threejs to imitate the iView official website big wave special effects example

Preface

Threejs can be understood as a web-based 3D engine (rendering model, data visualization). If you have been exposed to game engines such as Unreal Engine 4, it should be easy to understand every component necessary in a 3D scene (scene, renderer, mesh model, material, light source, color camera). Okay, let's skip the basics and go directly to the implementation process.

1. Rendering

First, the final effect picture:

For specific effects, please refer to the iview official interface iView - a set of high-quality UI component libraries

The big wave effect uses the official example of three.js. You need to install three.js support first. For details, please see the official example three.js examples (threejs.org)

2. Code

1. Install threejs

npm install --save three

2. Code (copy available) Create a new component waves.vue in the components folder, copy the code as follows, and run it directly:

<template>
  <div id="iviewBg"></div>
</template>

<script>
import * as THREE from "three";
Display the fps box in the upper right corner // import Stats from "./stats.module";
import { onMounted } from "vue";
export default {
  props: {
  	//Control the length of the x-axis wave amountX: {
      type: Number,
      default: 50,
    },
    //Control the length of the y-axis wave amountY: {
      type: Number,
      default: 50,
    },
    //Control point colorcolor: {
      type: String,
      default: "#097bdb",
    },
    //Control the position of the wave 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);

      //Create a perspective camera camera = new THREE.PerspectiveCamera(
        75, //Vertical field of view of camera cone window.innerWidth / window.innerHeight, //Aspect ratio of camera cone 1, //Near side of camera cone 10000 //Far side of camera cone);

      //Set the camera's z-axis field of view camera.position.z = 1000;

      //Create scene 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;

      // Initialize particle position and size 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++;
        }
      }

      // is a valid representation of a patch, line, or point geometry. Includes vertex positions, patch indices, normals, color values, UV coordinates, and custom cache attribute values. Using BufferGeometry can effectively reduce the overhead required to transfer the above data to the GPU const geometry = new THREE.BufferGeometry();
      geometry.setAttribute(
        "position",
        new THREE.BufferAttribute(positions, 3)
      );
      geometry.setAttribute("scale", new THREE.BufferAttribute(scales, 1));

      //ShaderMaterial, set the ball's size, color, etc. const material = new THREE.ShaderMaterial({
        uniforms:
          //Set the color of the ball color: { value: new THREE.Color(props.color) },
        },
        //Control the size of the ball 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 );}",
      });

      //A class for displaying points.
      particles = new THREE.Points(geometry, material);
      //Add points to the scene scene.add(particles);

      //alpha - whether the canvas contains alpha (transparency). The default value is false.
      //The default background color of the renderer is black. Set the background color of the renderer to transparent. 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);

      //Show the upper right corner fps box //stats = new Stats();
      // container.appendChild(stats.dom);

      container.style.touchAction = "none";
      //Listen for mouse movement events container.addEventListener("pointermove", onPointerMove);

      //Adjust the position of the wave 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;

      // Set particle position and size 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);
    }

    //Listen for mouse movement events function onPointerMove(event) {
      console.log(event);
      if (event.isPrimary === false) return;
      mouseX = event.clientX - windowHalfX;
    }

    function animate() {
      requestAnimationFrame(animate);
      render();
      //fps real-time update// 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. Use

Directly introduce components on the login page

<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>

3. Background picture material

If it is not clear, you can go to the official interface f12 to get it, iView - a set of high-quality UI component libraries

As shown in the figure below

Summarize

This is the end of this article about using vue3 + threejs to imitate the big wave special effects of iView official website. For more relevant vue3 + threejs imitation of big wave special effects content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue page introduces three.js to realize 3D animation scene operation
  • A complete example of using three.js to realize panorama in Vue

<<:  5 ways to quickly remove the blank space of Inline-Block in HTML

>>:  Tutorial on installing AutoFs mount service under Linux

Recommend

Loading animation implemented with CSS3

Achieve results Implementation Code <h1>123...

Install Apache2.4+PHP7.0+MySQL5.7.16 on macOS Sierra

Although Mac systems come with PHP and Apache, so...

Solution to the timeout problem when installing docker-compose with PIP

1: Installation command pip install docker-compos...

Vue2.0 implements adaptive resolution

This article shares the specific code of Vue2.0 t...

Implementation code for using CSS text-emphasis to emphasize text

1. Introduction In the past, if you wanted to emp...

Detailed steps for configuring virtual hosts in nginx

Virtual hosts use special software and hardware t...

Installation and configuration of mysql 8.0.15 under Centos7

This article shares with you the installation and...

Analysis of the Poor Performance Caused by Large Offset of LIMIT in MySQL Query

Preface We all know that MySQL query uses the sel...

Detailed explanation of Linux DMA interface knowledge points

1. Two types of DMA mapping 1.1. Consistent DMA m...

How to build php7 with docker custom image

First, perform a simple Docker installation. To c...

Steps of an excellent registration process

For a website, it is the most basic function. So l...

Detailed explanation of using top command to analyze Linux system performance

Introduction to Linux top command The top command...

Solve the problem that IN subquery in MySQL will cause the index to be unusable

Today I saw a case study on MySQL IN subquery opt...

Detailed explanation of map overlay in openlayers6

1. Overlay Overview Overlay means covering, as th...