跳动的爱心代码–李峋爱心代码(完整源码)

本文章分为两部分:

第一部分为实现效果展示,第二部分是实现跳动爱心源码。

关注微信公众号: ClassmateJie

跳动的爱心效果展示

在这里插入图片描述

关注微信公众号【ClassmateJie】获取完整源码,回复爱心代码。

实现步骤

1.建一个html文件,代码如下:




  
  爱心跳动,3D拖拽搬
  





  
  <!--  -->
  
  
  
  
  


  


    (function () {
      const _face = new THREE.Triangle();

      const _color = new THREE.Vector3();

      class MeshSurfaceSampler {

        constructor(mesh) {

          let geometry = mesh.geometry;

          if (!geometry.isBufferGeometry || geometry.attributes.position.itemSize !== 3) {

            throw new Error('THREE.MeshSurfaceSampler: Requires BufferGeometry triangle mesh.');

          }

          if (geometry.index) {

            console.warn('THREE.MeshSurfaceSampler: Converting geometry to non-indexed BufferGeometry.');
            geometry = geometry.toNonIndexed();

          }

          this.geometry = geometry;
          this.randomFunction = Math.random;
          this.positionAttribute = this.geometry.getAttribute('position');
          this.colorAttribute = this.geometry.getAttribute('color');
          this.weightAttribute = null;
          this.distribution = null;

        }

        setWeightAttribute(name) {

          this.weightAttribute = name ? this.geometry.getAttribute(name) : null;
          return this;

        }

        build() {

          const positionAttribute = this.positionAttribute;
          const weightAttribute = this.weightAttribute;
          const faceWeights = new Float32Array(positionAttribute.count / 3); // Accumulate weights for each mesh face.

          for (let i = 0; i < positionAttribute.count; i += 3) {

            let faceWeight = 1;

            if (weightAttribute) {

              faceWeight = weightAttribute.getX(i) + weightAttribute.getX(i + 1) + weightAttribute.getX(i + 2);

            }

            _face.a.fromBufferAttribute(positionAttribute, i);

            _face.b.fromBufferAttribute(positionAttribute, i + 1);

            _face.c.fromBufferAttribute(positionAttribute, i + 2);

            faceWeight *= _face.getArea();
            faceWeights[i / 3] = faceWeight;

          } // Store cumulative total face weights in an array, where weight index
          // corresponds to face index.


          this.distribution = new Float32Array(positionAttribute.count / 3);
          let cumulativeTotal = 0;

          for (let i = 0; i < faceWeights.length; i++) {

            cumulativeTotal += faceWeights[i];
            this.distribution[i] = cumulativeTotal;

          }

          return this;

        }

        setRandomGenerator(randomFunction) {

          this.randomFunction = randomFunction;
          return this;

        }

        sample(targetPosition, targetNormal, targetColor) {

          const cumulativeTotal = this.distribution[this.distribution.length - 1];
          const faceIndex = this.binarySearch(this.randomFunction() * cumulativeTotal);
          return this.sampleFace(faceIndex, targetPosition, targetNormal, targetColor);

        }

        binarySearch(x) {

          const dist = this.distribution;
          let start = 0;
          let end = dist.length - 1;
          let index = - 1;

          while (start <= end) {

            const mid = Math.ceil((start + end) / 2);

            if (mid === 0 || dist[mid - 1]  x) {

              index = mid;
              break;

            } else if (x  1) {

            u = 1 - u;
            v = 1 - v;

          }

          _face.a.fromBufferAttribute(this.positionAttribute, faceIndex * 3);

          _face.b.fromBufferAttribute(this.positionAttribute, faceIndex * 3 + 1);

          _face.c.fromBufferAttribute(this.positionAttribute, faceIndex * 3 + 2);

          targetPosition.set(0, 0, 0).addScaledVector(_face.a, u).addScaledVector(_face.b, v).addScaledVector(_face.c, 1 - (u + v));

          if (targetNormal !== undefined) {

            _face.getNormal(targetNormal);

          }

          if (targetColor !== undefined && this.colorAttribute !== undefined) {

            _face.a.fromBufferAttribute(this.colorAttribute, faceIndex * 3);

            _face.b.fromBufferAttribute(this.colorAttribute, faceIndex * 3 + 1);

            _face.c.fromBufferAttribute(this.colorAttribute, faceIndex * 3 + 2);

            _color.set(0, 0, 0).addScaledVector(_face.a, u).addScaledVector(_face.b, v).addScaledVector(_face.c, 1 - (u + v));

            targetColor.r = _color.x;
            targetColor.g = _color.y;
            targetColor.b = _color.z;
          }
          return this;

        }

      }

      THREE.MeshSurfaceSampler = MeshSurfaceSampler;

    })();

  
  
    (function () {

      const _object_pattern = /^[og]\s*(.+)?/; // mtllib file_reference

      const _material_library_pattern = /^mtllib /; // usemtl material_name

      const _material_use_pattern = /^usemtl /; // usemap map_name

      const _map_use_pattern = /^usemap /;

      const _vA = new THREE.Vector3();

      const _vB = new THREE.Vector3();

      const _vC = new THREE.Vector3();

      const _ab = new THREE.Vector3();

      const _cb = new THREE.Vector3();

      function ParserState() {

        const state = {
          objects: [],
          object: {},
          vertices: [],
          normals: [],
          colors: [],
          uvs: [],
          materials: {},
          materialLibraries: [],
          startObject: function (name, fromDeclaration) {

            // If the current object (initial from reset) is not from a g/o declaration in the parsed
            // file. We need to use it for the first parsed g/o to keep things in sync.
            if (this.object && this.object.fromDeclaration === false) {

              this.object.name = name;
              this.object.fromDeclaration = fromDeclaration !== false;
              return;

            }

            const previousMaterial = this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined;

            if (this.object && typeof this.object._finalize === 'function') {

              this.object._finalize(true);

            }

            this.object = {
              name: name || '',
              fromDeclaration: fromDeclaration !== false,
              geometry: {
                vertices: [],
                normals: [],
                colors: [],
                uvs: [],
                hasUVIndices: false
              },
              materials: [],
              smooth: true,
              startMaterial: function (name, libraries) {

                const previous = this._finalize(false); // New usemtl declaration overwrites an inherited material, except if faces were declared
                // after the material, then it must be preserved for proper MultiMaterial continuation.


                if (previous && (previous.inherited || previous.groupCount  0 ? libraries[libraries.length - 1] : '',
                  smooth: previous !== undefined ? previous.smooth : this.smooth,
                  groupStart: previous !== undefined ? previous.groupEnd : 0,
                  groupEnd: - 1,
                  groupCount: - 1,
                  inherited: false,
                  clone: function (index) {

                    const cloned = {
                      index: typeof index === 'number' ? index : this.index,
                      name: this.name,
                      mtllib: this.mtllib,
                      smooth: this.smooth,
                      groupStart: 0,
                      groupEnd: - 1,
                      groupCount: - 1,
                      inherited: false
                    };
                    cloned.clone = this.clone.bind(cloned);
                    return cloned;

                  }
                };
                this.materials.push(material);
                return material;

              },
              currentMaterial: function () {

                if (this.materials.length > 0) {

                  return this.materials[this.materials.length - 1];

                }

                return undefined;

              },
              _finalize: function (end) {

                const lastMultiMaterial = this.currentMaterial();

                if (lastMultiMaterial && lastMultiMaterial.groupEnd === - 1) {

                  lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
                  lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
                  lastMultiMaterial.inherited = false;

                } // Ignore objects tail materials if no face declarations followed them before a new o/g started.


                if (end && this.materials.length > 1) {

                  for (let mi = this.materials.length - 1; mi >= 0; mi--) {

                    if (this.materials[mi].groupCount <= 0) {

                      this.materials.splice(mi, 1);

                    }

                  }

                } // Guarantee at least one empty material, this makes the creation later more straight forward.


                if (end && this.materials.length === 0) {

                  this.materials.push({
                    name: '',
                    smooth: this.smooth
                  });

                }
.....





  1. 建立一个css文件
body {
  background: rgb(0, 0, 0);
  overflow: hidden;
  margin: 0;
  /* background-color: #000 !important; */
}

  1. 运行html文件

    在这里插入图片描述

获取源码直接运行

在这里插入图片描述

关注微信公众号「
ClassmateJie」

更多惊喜等待你的发掘

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/9ea7d2eb9c.html