“This is the 10th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

background

I saw a gold digger use it the other daythreejsRealized a 1000 fans of their own medal animation, feel very powerful, so I want to imitate him to write a similar demo, and then see the Nuggets logo is symmetrical graphics, very simple atmosphere, not too good (PS: in the nuggets write which can not pat the nuggets ass, haha…) Without further ado, let’s get started!

technology

  • vue3.0
  • typescript
  • threejs

implementation

Get the Nuggets logo

It is also very easy to get the nuggets logo, f12 check the elements, and then place the mouse over the logo image to see the link, as follows:

The nuggets logo:lf3-cdn-tos.bytescm.com/obj/static/…

Create a project

We will skip this step, because this vue3.0 + TS + Threejs implementation of the simple demo has been covered, if not can see the previous article, step by step can be.

Create a demo page

First create a demo.vue page, then write some code inside and create a route

<template>
  <div class="demo"></div>
</template>

<script lang="ts">
import ThreeJs from "./index";
import { defineComponent, onMounted } from "vue";
export default defineComponent({
  name: "Demo".props: {},
  setup() {
    onMounted(() = > {
      newThreeJs(); }); }});</script>
<style scoped lang="scss"></style>
Copy the code

Introduce Threejs and related plug-ins

  1. indemo.vueNew folderindex.tsFile;
  2. The introduction ofthreejs;
  3. Introducing SVG loader and logo.svg;
  4. Introducing camera controlsOrbitControls
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { SVGLoader } from "three/examples/jsm/loaders/SVGLoader";
Copy the code

Default values and initialization

export default class ThreeJs {
  scene: THREE.Scene | null = null;
  camera: THREE.PerspectiveCamera | null = null;
  renderer: THREE.WebGLRenderer | null = null;
  ambientLight: THREE.AmbientLight | null = null;
  group: THREE.Group | null = null;
  controls: OrbitControls | null = null;
  axesHelper: THREE.AxesHelper | null = null;

  constructor() {
    this.init();
  }

  init(): void {
    this.setScene();
    this.setCamera();
    this.setRenderer();
    this.setCube();
    this.setControls();
    this.animate();
    this.onWindowResize();
    this.setAxesHelper(); }}Copy the code

Window change control

onWindowResize(): void {
    window.addEventListener("resize".() = > {
      if (this.camera && this.renderer) {
        this.camera.aspect = window.innerWidth / window.innerHeight;
        this.camera.updateProjectionMatrix();
        this.render();
        this.renderer.setSize(window.innerWidth, window.innerHeight); }}); }Copy the code

Auxiliary tool

setAxesHelper(): void {
    const helper = new THREE.AxesHelper(10);
    this.scene && this.scene.add(helper);
  }
Copy the code

Create a new scene

setScene(): void {
    this.scene = new THREE.Scene();
  }
Copy the code

New Perspective Camera

setCamera(): void {
    // The second argument is the length to width ratio. The default is the internal width and height of the window returned by the browser in pixels
    this.camera = new THREE.PerspectiveCamera(
      45.window.innerWidth / window.innerHeight,
      1.1000
    );
    this.camera.position.set(0.0.400);
  }
Copy the code

Setting up the renderer

setRenderer(): void {
    this.renderer = new THREE.WebGLRenderer({ antialias: true });
    // Set the canvas size
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    // This is actually canvas renderer.domElement
    document.body.appendChild(this.renderer.domElement);
  }
Copy the code

Setting ambient Light

setLight(): void {
    if (this.scene) {
      // this.ambientLight = new THREE.AmbientLight(0xffffff); / / the ambient light
      // this.scene.add(this.ambientLight);

      this.scene.add(new THREE.AmbientLight(0x404040));

      const light = new THREE.DirectionalLight(0xffffff);
      light.position.set(1.1.1);
      this.scene.add(light); }}Copy the code

Creating a Logo Model

  1. Create a logo method
setCube(): void {
/ / code
}
Copy the code
  1. Create an SVG loader
const loader = new SVGLoader();
loader.load(url, func, func, func);
Copy the code
  1. Load the SVG
loader.load(
      "/assets/imgs/logo.svg", func, func, func
      )
Copy the code
  1. Successful callback and model creation
(data) => {
        const paths = data.paths;
        for (let i = 0; i < paths.length; i++) {
          const path = paths[i];
          this.group = new THREE.Group();

          const material = new THREE.MeshBasicMaterial({
            color: path.color,
            side: THREE.DoubleSide,
            depthWrite: false});const shapes = SVGLoader.createShapes(path);

          for (let j = 0; j < shapes.length; j++) {
            const shape = shapes[j];
            const geometry = new THREE.ShapeGeometry(shape);

            geometry.center();
            const mesh = new THREE.Mesh(geometry, material);
            j == 1 && mesh.translateY(6);
            j == 2 && mesh.translateY(12);
            this.group && this.group.add(mesh); }}this.group && (this.group.position.y = 10);
        this.group && this.group.rotateX(-3.14);
        this.scene && this.group && this.scene.add(this.group);
      },
Copy the code

Complete code:

setCube(): void {
    const loader = new SVGLoader();
    loader.load(
      "/assets/imgs/logo.svg".(data) = > {
        const paths = data.paths;
        for (let i = 0; i < paths.length; i++) {
          const path = paths[i];
          this.group = new THREE.Group();

          const material = new THREE.MeshBasicMaterial({
            color: path.color,
            side: THREE.DoubleSide,
            depthWrite: false});const shapes = SVGLoader.createShapes(path);

          for (let j = 0; j < shapes.length; j++) {
            const shape = shapes[j];
            const geometry = new THREE.ShapeGeometry(shape);

            geometry.center();
            const mesh = new THREE.Mesh(geometry, material);
            j == 1 && mesh.translateY(6);
            j == 2 && mesh.translateY(12);
            this.group && this.group.add(mesh); }}this.group && (this.group.position.y = 10);
        this.group && this.group.rotateX(-3.14);
        this.scene && this.group && this.scene.add(this.group);
      },
      // called when loading is in progresses
      function (xhr) {
        console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
      },
      // called when loading has errors
      function (error) {
        console.log("An error happened", error); }); }Copy the code

Apply colours to a drawing

 render(): void {
    if (this.renderer && this.scene && this.camera) {
      this.renderer.render(this.scene, this.camera); }}Copy the code

Rotating animation

 animate(): void {
    if (this.controls && this.stats) {
      // Update the controller
      this.controls.update();
      this.render();

      // Update the performance plug-in
      this.stats.update();
      requestAnimationFrame(this.animate.bind(this));
    }
    if (this.group) {
      const axis = new THREE.Vector3(0.1.0); / / vector axis
      this.group.rotateOnAxis(axis, Math.PI / 100); // Rotate PI /100 around the axis}}Copy the code

The effect

Related articles

  • Vue3.0 + TS + Threejs implements simple demo
  • Threejs is used to solve the triangular area of three-dimensional space