three+cannon模拟三维小球搅拌物理反应动画效果代码
代码语言:html
所属分类:三维
代码描述:three+cannon模拟三维小球搅拌物理反应动画效果代码,按住空格键,鼠标点击增加小球。
代码标签: three cannon 模拟 三维 小球 搅拌 物理 反应 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://fonts.googleapis.com/css?family=Ropa+Sans&display=swap" rel="stylesheet"> <!-- PRELOAD IMAGES --> <link rel="preload" as="image" href="//repo.bfw.wiki/bfwrepo/images/threecaizhi/ambientOcclusion.avif" crossorigin> <link rel="preload" as="image" href="//repo.bfw.wiki/bfwrepo/images/threecaizhi/height.avif" crossorigin> <link rel="preload" as="image" href="//repo.bfw.wiki/bfwrepo/images/threecaizhi/roughness.avif" crossorigin> <link rel="preload" as="image" href="//repo.bfw.wiki/bfwrepo/images/threecaizhi/normal.avif" crossorigin> <link rel="preload" as="image" href="//repo.bfw.wiki/bfwrepo/images/threecaizhi/basecolor.avif" crossorigin> <style> html { font-family: "Ropa Sans", Arial, sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; font-size: 16px; } *, *::after, *::before { box-sizing: border-box; } h1 { margin: 0; padding: 0; } body { padding: 0; margin: 0; background-color: #341472; overflow: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } a { font-size: 16px; color: #fff; text-decoration: none; padding: 10px; transition: background-color 0.3s, color 0.3s; } a:hover { color: #341472; background-color: #fff; } #credits { margin: 0; position: absolute; z-index: 1; bottom: 10px; width: 100%; left: 20px; } #instructions { position: absolute; color: #fff; z-index: 1; top: 0; left: 100px; } .stats { position: absolute; top: 0; z-index: 0; pointer-events: none; } </style> </head> <body> <div class="stats"> </div> <p id="instructions"> 按住空格键,鼠标点击增加小球</p> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/Stats-16.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.144.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.144.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/TransformControls.js"></script> <script type="module"> import { Pane } from "//repo.bfw.wiki/bfwrepo/js/module/tweakpane.3.0.2.js"; import * as CANNON from "//repo.bfw.wiki/bfwrepo/js/module/cannon-es.0.20.0.js"; const radians = degrees => { return degrees * Math.PI / 180; }; const hexToRgb = hex => { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16) / 255, g: parseInt(result[2], 16) / 255, b: parseInt(result[3], 16) / 255 } : null; }; const rgbToHex = (s) => s.match(/[0-9]+/g).reduce((a, b) => a + (b | 256).toString(16).slice(1), "#"); const rInterval = function (callback, delay) { const dateNow = Date.now; const requestAnimation = window.requestAnimationFrame; let start = dateNow(); let stop; const intervalFunc = function () { dateNow() - start < delay || (start += delay, callback()); stop || requestAnimation(intervalFunc); }; requestAnimation(intervalFunc); return { clear: function () { stop = 1; } }; }; class App { init() { this.setup(); this.createScene(); this.createCamera(); this.addCameraControls(); this.addAmbientLight(); this.addDirectionalLight(); this.addPhysicsWorld(); this.addPointLight(); this.addPointerDebugger(); this.addFloor(); this.addFloorGrid(); this.addPropeller(); this.addInnerBoudaries(); this.addAxisHelper(); this.addStatsMonitor(); this.addWindowListeners(); this.addGuiControls(); this.addInitialSpheres(); this.animate(); } addGuiControls() { this.pane = new Pane(); this.guiSettings = this.pane.addFolder({ title: "Settings", expanded: false }); this.guiSettings.addInput(this.colors, "background").on("change", evt => { this.floor.material.color = hexToRgb(evt.value); document.body.style.backgroundColor = evt.value; this.scene.background = new Color(evt.value); }); this.guiSettings.addInput(this.colors, "ring").on("change", evt => { this.ringMesh.material.color = hexToRgb(evt.value); }); this.guiSettings.addInput(this.colors, "propeller").on("change", evt => { this.meshes.propeller.material.color = hexToRgb(evt.value); }); this.guiSettings. addInput(this.colors, "leftSideSphere"). on("change", evt => { this.meshes.sphereLeftSideMaterial.color = hexToRgb(evt.value); }); this.guiSettings. addInput(this.colors, "rightSideSphere"). on("change", evt => { this.meshes.sphereRightSideMaterial.color = hexToRgb(evt.value); }); this.guiSettings. addInput(this.colors, "displayGrid"). on("change", evt => { if (evt.value) { this.scene.add(this.grid); } else { this.scene.remove(this.grid); } }); } addPointerDebugger() { const material = new THREE.MeshStandardMaterial({ color: 0xff0000 }); const geometry = new THREE.SphereGeometry(0.01, 16, 16); this.pointerDebugger = new THREE.Mesh(geometry, material); this.scene.add(this.pointerDebugger); } addPhysicsWorld() { this.world = new CANNON.World(); this.world.gravity.set(0, -40, 0.5); this.world.broadphase = new CANNON.NaiveBroadphase(); this.world.solver.iterations = 20; this.world.defaultContactMaterial.contactEquationStiffness = 1e6; this.world.defaultContactMaterial.contactEquationRelaxation = 10; this.world.allowSleep = true; } setup() { this.velocity = 0.015; this.raycaster = new THREE.Raycaster(); this.mouse3D = new THREE.Vector2(); this.width = window.innerWidth; this.height = window.innerHeight; this.debug = false; this.colors = { background: rgbToHex( window.getComputedStyle(document.body).backgroundColor), floor: rgbToHex(window.getComputedStyle(document.body).backgroundColor), box: "#ffffff", leftSideSphere: "#ff0f40", rightSideSphere: "#ffffff", ambientLight: "#ffffff", directionalLight: "#ffffff", ring: "#ffaf00", propeller: "#faecec", displayGrid: true }; this.sphereConfig = { radius: 0.18, width: 32, height: 32 }; this.meshes = { container: new THREE.Object3D(), spheres: [], propeller: null, material: new THREE.MeshStandardMaterial({ color: this.colors.propeller, metalness: 0.1, roughness: 0.1 }), .........完整代码请登录后点击上方下载按钮下载查看
网友评论0