three实现三维蝴蝶飞舞动画效果代码

代码语言:html

所属分类:三维

代码描述:three实现三维蝴蝶飞舞动画效果代码

代码标签: three 三维 蝴蝶 飞舞 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">

  
<style>
@import url('https://fonts.googleapis.com/css2?family=Libre+Barcode+39+Text&family=Macondo+Swash+Caps&display=swap');
html, body {
    min-height: 100%;
}
body{
  overflow: hidden;
  margin: 0;
  background: linear-gradient(#face8D 75%, aquamarine);
}
canvas{
  position: absolute;
}

#butterfly{
  position: absolute;
  font-family: 'Macondo Swash Caps', cursive;
  font-size: 10vh;
  width: 100%;
  text-align: center;
  bottom: 1vh;
  color: maroon;
}

#player{
  position: absolute;
  opacity: 0.1;
}
#player:hover{
  opacity: 1;
}

.unselectable {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
  pointer-events: none;
}
</style>



</head>

<body >
  <canvas id="cnv"></canvas>
<div id="butterfly" class="unselectable">Schmetterling</div>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/es-module-shims.1.6.2.js"></script>
<script type="importmap">
  {
    "imports": {
        "three":"//repo.bfw.wiki/bfwrepo/js/module/three/build/150/three.module.js",
   
      "three/addons/": "//repo.bfw.wiki/bfwrepo/js/module/three/examples/jsm/"
    }
  }
</script>
 
      <script type="module">
// https://discourse.threejs.org/t/schmetterling-butterfly-no-webgl-depth-sorting/48919
import {
Box2,
BufferGeometry,
BufferAttribute,
Color,
MathUtils,
Object3D,
Path,
PerspectiveCamera,
Scene,
Vector2,
Vector3,
Matrix4 } from
"three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

console.clear();

class Material {
  constructor(fill = "gray", stroke = "black", lineWidth = 2, closed = true) {
    this.fill = fill;
    this.stroke = stroke;
    this.lineWidth = lineWidth;
    this.closed = closed;
  }}


class Drawable extends Object3D {
  constructor() {
    super();
    this.isDrawable = true;
  }}


class Polygon extends Drawable {
  constructor(geometry, material) {
    super();
    this.geometry = geometry;
    this.material = material;
    this.isPolygon = true;
  }}


class Circle extends Drawable {
  constructor(radius = 1, material) {
    super();
    this.radius = radius;
    this.material = material;
    this.isCircle = true;
    this.vertices = [new Vector3(), new Vector3(0, 1, 0).setLength(radius)];
  }}


class CanvasRenderer {
  constructor(canvas) {
    this.canvas = canvas;
    this.context = this.canvas.getContext("2d");
    this.halfSize = new Vector3();
    this.renderList = [];
    this._projectScreenMatrix = new Matrix4();
    this._vector3 = new Vector3();
  }

  setSize(width, height) {
    this.canvas.width = width;
    this.canvas.height = height;
    this.halfSize.set(width, height, 0).multiplyScalar(0.5);
  }

  sort(scene) {
    this.renderList = [];
    scene.traverse(child => {
      if (child.isDrawable) {
        this._vector3.
        setFromMatrixPosition(child.matrixWorld).
        applyMatrix4(this._projectScreenMatrix);
        this.renderList.push({
          object: child,
          z: this._vector3.z });

      }
    });
    this.renderList.sort((a, b) => b.z - a.z);
  }

  render(scene, camera) {
    scene.updateMatrixWorld();
    camera.updateMatrixWorld();
    this._projectScreenMatrix.multiplyMatrices(
    camera.projectionMatrix,
    camera.matrixWorldInverse);

    this.sort(scene);

    let c = this.context;
    let v3 = this._vector3;
    let hs = this.halfSize;
    c.clearRect(0, 0, this.canvas.width, this.canvas.height);

    for (let i = 0; i < this.renderList.length; i++) {
      let listObject = this.renderList[i].object;
      let z = this.renderList[i].z;
      let g = listObject.geometry;
      let m = listObject.material;

      if (listObject.isPolygon) {
        c.beginPath();
        toScreen(listObject, 0, v3, hs);
        c.moveTo(v3.x, v3.y);
        for (let j = 1; j < g.attributes.position.count; j++) {
          toScreen(listObject, j, v3, hs);
          c.lineTo(v3.x, v3.y);
        }
        if (m.closed) {
          c.closePath();
        }
        if (m.fill) {
          c.fillStyle = m.fill;
          c.fill();
        }
        if (m.stroke) {
          c.lineWidth = m.lineWidth;
          c.strokeStyle = m.stroke;
          c.stroke();
        }
      }

      if (listObject.isCircle) {
        if (z <= 0) continue;
        listObject.lookAt(camera.position);
        listObject.updateMatrixWorld();
        vecToScreen(listObject, listObject.vertices[0], v3, hs);
        let cx = v3.x;
        let cy = v3.y;
        vecToScreen(listObject, listObject.vertices[1], v3, hs);
        let r = Math.hypot(v3.x - cx, v3.y - cy);
        c.beginPath();
        c.arc(cx, cy, r, 0, Math.PI * 2);

        if (m.fill) {
          c.fillStyle = m.fill;
          c.fill();
        }
        if (m.stroke) {
          c.lineWidth = m.lineWidth;
          c.strokeStyle = m.stroke;
          c.stroke();
        }
      }
    }

    function vecToScreen(object, v) {
      v3.copy(v);
      object.localToWorld(v3);
      commonCast(v3);
    }
    function posToScreen(object) {
      v3.setFromMatrixPosition(object.matrixWorld);
      commonCast(v3);
    }
    function toScreen(object, vertexID) {
      v3.fromBufferAttribute(object.geometry.attributes.position, vertexID);
      object.localToWorld(v3);
      commonCast(v3);
    }
    function commonCast(v3) {
      v3.project(camera);
      v3.y *= -1;
      v3.multiply(hs).add(hs);
    }
  }}


class Butterfly extends Object3D {
  constructor() {
    super();
    let holder = new Object3D();
    holder.rotation.set(Math.PI * 0.5, Math.PI, 0);
    this.add(holder);
    // head and body
    let mBody = new Material("black", "#303030", 2);
    let head = new Circle(0.25, mBody);
    head.position.y = 0.5;
    holder.add(head);

    for (let i = 0; i < 7; i++) {
      let bPart = new Circle(0.25 - i * 0.025, mBody);
      bPart.position.y = 0.125 - i * 0.25;
      holder.add(bPart);
    }

    // wings
    this.wingParts = [];
    for (let sign = 1; sign >= -1; sign -= 2) {
      let wingHolder = new Object3D();
      wingHolder.position.set(0.25 * sign, 0, 0);
      holder.add(wingHolder);
      let partTop = makePart(4, 5, 6, 1, sign, 1);
      let partBottom = makePart(3, 4, 5, 0.5, sign, -1);
      partTop.userData = {
        rotStart: Math.PI * 0.5 * -sign,
        rotAmp: Math.PI / 4 * 3,
        rotDir: sign,
        rotShift: 0 };

      partBottom.u.........完整代码请登录后点击上方下载按钮下载查看

网友评论0