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='//repo.bfw.wiki/bfwrepo/js/cannon.min.js'></script> <script type="text/javascript" src="//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 '//repo.bfw.wiki/bfwrepo/js/module/three/build/120/three.module.js'; import useThree from '//repo.bfw.wiki/bfwrepo/js/useThree.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(); world.gra.........完整代码请登录后点击上方下载按钮下载查看
网友评论0