cannon实现三维气球跟随鼠飘动动画交互效果

代码语言:html

所属分类:三维

代码描述:cannon实现三维气球跟随鼠飘动动画交互效果

代码标签: 气球 跟随 飘动 动画 交互 效果

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

<style>
body {
  margin: 0;
  width: 100%;
  height: 100%;
}

canvas {
  display: block;
}
</style>

</head>
<body translate="no">
<canvas id="canvas"></canvas>
<p class="collection">

</p>

<script src='http://repo.bfw.wiki/bfwrepo/js/cannon.min.js'></script>
<script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/chroma.min.js"></script>
<script type="module">
import {
AmbientLight,
Color,
DynamicDrawUsage,
InstancedBufferAttribute,
InstancedMesh,
MathUtils,
Mesh,
MeshPhongMaterial,
Object3D,
Scene,
SphereBufferGeometry,
SpotLight,
Vector3 } from
'https://unpkg.com/three@0.120/build/three.module.js';

import useThree from 'https://codepen.io/soju22/pen/cb31020fed766eb66bc8ad1879bc3325.js';

const { randFloat: rnd, randFloatSpread: rndFS } = MathUtils;

App();

function App() {
  let three, scene;
  let cannon, iMesh;

  const target = new Vector3();
  let sphere, light1, light2;

  init();


  function init() {
    three = useThree().init({
      canvas: document.getElementById('canvas'),
      camera_fov: 50,
      camera_pos: new Vector3(0, 0, 25),
      camera_ctrl: {
        enableDamping: true,
        dampingFactor: 0.05 },

      mouse_move: true,
      mouse_raycast: true });

    three.renderer.shadowMap.enabled = true;

    cannon = useCannon();

    initScene();
    animate();
  }

  function initScene() {
    scene = new Scene();

    scene.background = new Color(0xffffff);
    scene.add(new AmbientLight(0x808080));

    light1 = new SpotLight(0xffffff, 0.5, 0, Math.PI / 8, 0.1);
    light1.position.set(0, 20, 50);
    light1.castShadow = true;
    light1.shadow.mapSize.width = 2048;
    light1.shadow.mapSize.height = 2048;
    scene.add(light1);
    scene.add(light1.target);

    light2 = new SpotLight(0xff0000, 0.5, 0, Math.PI / 8, 0.1);
    light2.position.set(0, -20, 50);
    light2.castShadow = true;
    light2.shadow.mapSize.width = 2048;
    light2.shadow.mapSize.height = 2048;
    scene.add(light2);
    scene.add(light2.target);

    sphere = new Mesh(
    new SphereBufferGeometry(5, 24, 24),
    new MeshPhongMaterial({ color: 0xffffff }));

    sphere.receiveShadow = true;
    scene.add(sphere);
    cannon.addMesh(sphere);

    initInstancedMesh();
  }

  function initInstancedMesh() {
    const geometry = new SphereBufferGeometry(1, 16, 16);
    // const geometry = new BoxBufferGeometry(1, 1, 1);
    const material = new MeshPhongMaterial({ color: 0xffffff, vertexColors: true });
    iMesh = new InstancedMesh(geometry, material, 200);
    iMesh.instanceMatrix.setUsage(DynamicDrawUsage);
    iMesh.mass = 0.1;

    iMesh.castShadow = true;
    iMesh.receiveShadow = true;

    // instance matrix
    const dummy = new Object3D();
    iMesh.scales = new Float32Array(iMesh.count);
    for (let i = 0; i < iMesh.count; i++) {
      dummy.position.set(rndFS(40), rndFS(40), rndFS(40));
      dummy.updateMatrix();
      iMesh.setMatrixAt(i, dummy.matrix);
      iMesh.scales[i] = rnd(0.25, 1);
    }

    // colors
    const cscale = chroma.scale([0xffffff, 0xc5777c, 0x437b7f]);
    iMesh.cscale = cscale;
    const colors = [];
    for (let i = 0; i < iMesh.count; i++) {
      const color = new Color(cscale(rnd(0, 1)).hex());
      colors.push(color.r, color.g, color.b);
    }
    iMesh.geometry.setAttribute('color', new InstancedBufferAttribute(new Float32Array(colors), 3));

    scene.add(iMesh);
    cannon.addMesh(iMesh);

    // custom gravity
    const v = new Vector3();
    iMesh.bodies.forEach(body => {
      body.preStep = () => {
        v.copy(target).sub(body.position).normalize().multiplyScalar(0.5);
        v.clampScalar(-0.5, 0.5);
        body.force.copy(v);
      };
    });
  }

  function animate() {
    requestAnimationFrame(animate);
    target.copy(three.mouseV3);
    cannon.step();
    render();
  }

  function render() {
    const { renderer, camera, cameraCtrl } = three;
    if (cameraCtrl) cameraCtrl.update();
    renderer.render(scene, camera);
  }
}

/**
   * From https://github.com/mrdoob/three.js/blob/master/examples/jsm/physics/CannonPhysics.js
   */
function useCannon() {
  const world = new CANNON.World();
  .........完整代码请登录后点击上方下载按钮下载查看

网友评论0