three+gsap实现三维粒子烟花绽放动画效果代码

代码语言:html

所属分类:三维

代码描述:three+gsap实现三维粒子烟花绽放动画效果代码

代码标签: three gsap 三维 粒子 烟花 绽放 动画

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

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

<head>
  <meta charset="UTF-8">
  

  
  
<style>
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: #EF9595;
}
</style>

  
  
  
</head>

<body translate="no">
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/es-module-shims.1.6.3.js"></script>
<script type="importmap">
  {
    "imports": {      
      "three": "//repo.bfw.wiki/bfwrepo/js/module/three/build/160/three.module.js",
        "three/addons/": "//repo.bfw.wiki/bfwrepo/js/module/three/examples/160/jsm/"
    }
  }
</script>

<canvas id="canvas"></canvas>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.12.2.js"></script>
      <script  type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const canvas = document.querySelector("#canvas");
let D = { w: window.innerWidth, h: window.innerHeight };
let renderer, camera, controls, scene, group, envMap;

const MAX_ROCKETS = 2;
const ROCKET_GAP = 0.5; // seconds
const COLORS = ['#E76161'];
const P_COUNTS = [85, 100, 102, 113, 120, 129, 140];
let rockets = [],fireworks = [];
/** Renderer */
renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
renderer.setClearColor('#EF9595');
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
/** Camera */
camera = new THREE.PerspectiveCamera(20, D.w / D.h, 0.1, 100);
camera.position.set(0, 9, 41);
/** Orbit Controls */
controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 5.5, 0);
controls.enableDamping = true;
controls.enablePan = false;
controls.dampingFactor = 0.02;
controls.maxPolarAngle = 85 * Math.PI / 180;
controls.minPolarAngle = 55 * Math.PI / 180;
controls.minDistance = 25;
controls.maxDistance = 41;
// addEventListener('mousemove', () => {
//   console.log(camera.position, controls.target);
// })
/** Scene */
scene = new THREE.Scene();
/** Light */
const light1 = new THREE.DirectionalLight('#ffffff', 1);
light1.position.set(0, 10, 0);
light1.castShadow = true;
light1.shadow.camera.left = -15;
light1.shadow.camera.right = 15;
light1.shadow.camera.top = 15;
light1.shadow.camera.bottom = -15;
scene.add(light1);
/** Fog */
scene.fog = new THREE.Fog('#EF9595', 45, 70);
/** Ground */
const ground = new THREE.Mesh(
new THREE.PlaneGeometry(1000, 1000),
new THREE.MeshStandardMaterial({
  color: '#FFC5C5',
  emissive: '#FFC5C5',
  emissiveIntensity: 0.8 }));


ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
scene.add(ground);
/** Group */
group = new THREE.Group();
group.position.y = 0.5;
scene.add(group);
/** Load envMap */
new THREE.TextureLoader().load('//repo.bfw.wiki/bfwrepo/icon/63ed7c0922a66.gif?x-oss-process=image/auto-orient,1/resize,m_fill,w_100,h_100,/quality,q_90', _envMap => {
  _envMap.mapping = THREE.EquirectangularReflectionMapping;
  _envMap.encoding = THREE.sRGBEncoding;
  envMap = _envMap;
});

function Rocket({ color, position, particleCount }) {
  this.color = color;
  this.targetPos = new THREE.Vector3(position.x, position.y, position.z);
  let currentPos = new THREE.Vector3(0, 0, 0);
  this.particleCount = particleCount;
  const self = this;
  init();

  function init() {
    const geometry = new THREE.SphereGeometry(0.1, 32, 32);
    const material = new THREE.MeshStandardMaterial({
      color: self.color,
      metalness: 1,
      roughness: 0.1,
      envMap,
      envMapIntensity: 1 });

    self.mesh = new THREE.Mesh(geometry, material);
    self.mesh.frustumCulled = false;
    self.mesh.castShadow = true;
    scene.add(self.mesh);
  }
  this.isCompleted = function () {
    return currentPos.distanceTo(this.targetPos) < 0.25;
  };
  this.update = function (delta) {
    currentPos.lerp(this.targetPos, delta * 0.0027);
    self.mesh.position.copy(currentPos);
  };
  this.remove = function () {
    scene.remove(this.mesh);
  };
}

function Firework({ color, targetPos, particleCount }) {
  this.color = color;
  this.targetPos = targetPos;
  this.particleCount = particleCount;
  const self = this;
  let startTime;
  init();

  function init() {
    const particleGeo = new THREE.SphereGeometry(0.2, 32);
    const geometry = new THREE.InstancedBufferGeometry().copy(particleGeo);
    geometry.index = particleGeo.index;
    geometry.instanceCount = self.particleCount;

    const pos = [];
    const rot = [];
    const scl = [];
    const delay = [];
    let dummy = new THREE.Object3D();

    for (let i = 0; i < self.particleCount; i++) {
      const angle1 = i / self.particleCount * Math.PI;
      const angle2 = i / self.particleCount * 90;
      const x = Math.sin(angle1) * Math.cos(angle2);
      const y = Math.sin(angle1) * Math.sin(angle2);
      const z = Math.cos(angle1);
      pos.push(x, y, z);

      dummy.rotation.set(
      randomNum(0, Math.PI * 2),
      randomNum(0, Math.PI * 2),
      randomNum(0, Math.PI * 2));

      dummy.updateMatrix();

      rot.push(dummy.quaternion.x, dummy.quaternion.y, dummy.quaternion.z, dummy.quaternion.w);
      scl.push(1, 1, 1);

      delay.push(randomNum(0, 1));
    }

    geometry.setAttribute('instT', new THREE.InstancedBufferAttribute(new Float32Array(pos), 3, false));
    geometry.setAttribute('instR', new THREE.InstancedBufferAttribute(new Float32Array(rot), 4, false));
    geometry.setAttribute('instS', new THREE.InstancedBufferAttribute(new Float32Array(scl), 3, false));
    geometry.setAttribute('instDelay', new THREE.InstancedBufferAttribute(new Float32Array(delay), 1, false));

    const insertVertexAttributes = shader => {
      shader.vertexShader = `
        uniform float uTime;
        uniform float uProgress;
        varying vec2 vUv;
        varying float vInstDelay;
  
        attribute vec3 instT;
        attribute vec4 instR;
        attribute vec3 instS;
        attribute float instDelay;
        
        // http://barradeau.com/blog/?p=1109
        vec3 trs( inout vec3 position, vec3 T, vec4 R, vec3 S ) {
            position *= S;
            position += 2.0 * cross( R.xyz, cross( R.xyz, position ) + R.w * position );
            position += T;
            return position;
        }
        vec3 transformedNormal(vec3 normal, vec4 R) {
            return normalize(normal + 2.0 * cross(R.xyz, cross(R.xyz, normal) + R.w * normal));
        }
        ${shader.vertexShader}
      `;
    };
    const overideVertexShader = shader => {
      shader.vertexShader = shader.vertexShader.replace(
      `#include <begin_vertex>`,
      `#include <begin_vertex>
          float time = uTime;
          vInstDelay = instDe.........完整代码请登录后点击上方下载按钮下载查看

网友评论0