three+cannon实现三维小球搅拌重力模拟效果代码
代码语言:html
所属分类:三维
代码描述:three+cannon实现三维小球搅拌重力模拟效果代码
代码标签: three cannon 三维 小球 搅拌 重力 模拟
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> html { font-family: "Ropa Sans", Arial, sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } *, *::after, *::before { box-sizing: border-box; } body { padding: 0; margin: 0; background-color: #333333; overflow: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } a { font-size: 22px; color: #fff; text-decoration: none; padding: 10px; transition: background-color 0.3s, color 0.3s; } a:hover { color: #390fff; background-color: #fff; } section { margin: 10px; position: absolute; z-index: 1; bottom: 0; width: 100%; } #stats { position: absolute; } </style> </head> <body > <div id="stats"></div> <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="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/tweakpane.3.02.js"></script> <script type="module"> import * as CANNON from "//repo.bfw.wiki/bfwrepo/js/module/cannon-es.0.20.0.js"; 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), "#"); class App { constructor() { this.settings = { velocity: 0.015, width: window.innerWidth, height: window.innerHeight, debug: false, colors: { background: rgbToHex( window.getComputedStyle(document.body).backgroundColor), floor: rgbToHex(window.getComputedStyle(document.body).backgroundColor), box: "#390fff", spheres: { left: "#390fff", right: "#ffffff" }, ambientLight: "#ffffff", directionalLight: "#ffffff", pointLight: "#390fff" } }; } init() { this.setup(); this.createScene(); this.createCamera(); this.addCameraControls(); this.addAmbientLight(); this.addDirectionalLight(); this.addPhysicsWorld(); this.addPointLight(); this.addFloor(); this.addBox(); this.addPropeller(); this.addInnerBoudaries(); this.addWindowListeners(); this.addGuiControls(); this.addInitialSpheres(); this.addStatsMonitor(); this.animate(); } addGuiControls() { this.pane = new Tweakpane.Pane(); this.guiSettings = this.pane.addFolder({ title: "Colors", expanded: false }); this.guiSettings. addInput(this.settings.colors, "background"). on("change", evt => { this.floor.material.color = hexToRgb(evt.value); document.body.style.backgroundColor = evt.value; this.scene.background = new THREE.Color(evt.value); }); this.guiSettings. addInput(this.settings.colors.spheres, "left"). on("change", evt => { this.spheres.materials.left.color = hexToRgb(evt.value); }); this.guiSettings. addInput(this.settings.colors.spheres, "right"). on("change", evt => { this.spheres.materials.right.color = hexToRgb(evt.value); }); this.guiSettings. addInput(this.settings.colors, "box"). on("change", evt => { this.meshes.box.material.color = hexToRgb(evt.value); }); // control lights this.guiSettings = this.pane.addFolder({ title: "Directional Light", expanded: false }); this.guiSettings. addInput(this.directionalLight.position, "x", { min: -100, max: 100, step: 0.1 }). on("change", ({ value }) => { this.directionalLight.position.x = value; }); this.guiSettings. addInput(this.directionalLight.position, "y", { min: -100, max: 100, step: 0.1 }). on("change", ({ value }) => { this.directionalLight.position.y = value; }); this.guiSettings. addInput(this.directionalLight.position, "z", { min: -100, max: 100, step: 0.1 }). on("change", ({ value }) => { this.directionalLight.position.z = value; }); this.guiSettings. addInput(this.settings.colors, "directionalLight"). on("change", evt => { this.directionalLight.color = hexToRgb(evt.value); }); // control lights this.guiSettings = this.pane.addFolder({ title: "Point Light", expanded: false }); this.guiSettings. addInput(this.pointLight.position, "x", { min: -100, max: 100, step: 0.1 }). on("change", ({ value }) => { this.pointLight.position.x = value; }); this.guiSettings. addInput(this.pointLight.position, "y", { min: -100, max: 100, step: 0.1 }). on("change", ({ value }) => { this.pointLight.position.y = value; }); this.guiSettings. addInput(this.pointLight.position, "z", { min: -100, max: 100, step: 0.1 }). on("change", ({ value }) => { this.pointLight.position.z = value; }); this.guiSettings. addInput(this.settings.colors, "pointLight"). on("change", evt => { this.pointLight.color = hexToRgb(evt.value); }); } addPhysicsWorld() { this.world = new CANNON.World(); this.world.gravity.set(0, -5, 20); this.world.broadphase = new CANNON.NaiveBroadphase(); this.world.defaultContactMaterial.contactEquationStiffness = 5e7; this.world.defaultContactMaterial.contactEquationRelaxation = 3; this.world.quatNormalizeFast = true; this.world.allowSleep = true; } setup() { this.spheres = { config: { radius: 0.15, width: 32, height: 32 }, materials: { base: new THREE.MeshBasicMaterial({ color: "#ff00ff" }), left: new THREE.MeshPhysicalMaterial({ color: this.settings.colors.spheres.left, metalness: 0.1, emissive: 0x0, roughness: 0.1 }), right: new THREE.MeshPhysicalMaterial({ color: this.settings.colors.spheres.right, metalness: 0.1, emissive: 0x0, roughness: 0.1 }) } }; this.meshes = { container: new THREE.Object3D(), spheres: [], propeller: null, material: new THREE.MeshStandardMaterial({ color: "#ffffff", metalness: 0, emissive: 0x0, roughness: 1 }), sphere: { baseMaterial: new THREE.MeshBasicMaterial({ color: "#ff00ff" }), geometry: new THREE.SphereGeometry(this.spheres.config.radius, 16, 16), geometryHalf: new THREE.SphereGeometry( this.spheres.config.radius, 16, 16, 0, 3.15) } }; } createScene() { this.scene = new THREE.Scene(); this.scene.background = new THREE.Color(this.settings.colors.background); this.renderer = new THREE.WebGLRenderer({ antialias: true }); this.renderer.shadowMap.enabled = true; this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; this.renderer.setSize(this.settings.width, this.settings.height); document.body.appendChild(this.renderer.domElement); } createCamera() { this.camera = new THREE.PerspectiveCamera( 20, this.settings.width / this.settings.height, 1, 1000); this.camera.position.set(0, 30, 0); this.scene.add(this.camera); } addCameraControls() { this.orbitControl = new THREE.OrbitControls( this.camera, this.renderer.domElement); this.orbitControl.enableDamping = true; this.orbitControl.dampingFactor = 0.02; this.orbitControl.minPolarAngle = THREE.MathUtils.degToRad(0); this.orbitControl.maxPolarAngle = THREE.MathUtils.degToRad(20); this.orbitControl.minAzimuthAngle = THREE.MathUtils.degToRad(0); this.orbitControl.maxAzimuthAngle = THREE.MathUtils.degToRad(0); this.orbitControl.enablePan = false; this.orbitControl.enableRotate = true; this.orbitControl.enableZoom = false; this.orbitControl.saveState(); document.body.style.cursor = "-moz-grabg"; document.body.style.cursor = "-webkit-grab"; this.orbitControl.addEventListener("start", () => { requestAnimationFrame(() => { document.body.style.cursor = "-moz-grabbing"; document.body.style.cursor = "-webkit-grabbing"; }); }); this.orbitControl.addEventListener("end", () => { requestAnimationFrame(() => { document.body.style.cursor = "-moz-grab"; document.body.style.cursor = "-webkit-grab"; }); }); } addAmbientLight() { const light = new THREE.AmbientLight( { color: this.settings.colors.ambientLight }, 0.5); this.scene.add(light); } addDirectionalLight() { const target = new THREE.Object3D(); this.directionalLight = new THREE.DirectionalLight( this.settings.colors.directionalLight, 1); this.directionalLight.castShadow = true; this.directionalLight.target = target; this.directionalLight.shadow.mapSize.width = 2048; this.directionalLight.shadow.mapSize.height = 2048; this.directionalLight.shadow.camera.far = 1000; this.directionalLight.shadow.camera.near = -100; this.directionalLight.shadow.camera.zoom = 1; this.directionalLight.position.s.........完整代码请登录后点击上方下载按钮下载查看
网友评论0