3D Accelerometer Ball Pit
How do I make an 3d accelerometer ball pit?
Open this pen in full page view on a device with an accelerometer and give it a gentle shake to move the balls around. Please don't break your phones! . What is a 3d accelerometer ball pit? How do you make a 3d accelerometer ball pit? This script and codes were developed by Alex Bergin on 23 September 2022, Friday.
3D Accelerometer Ball Pit - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>3D Accelerometer Ball Pit</title> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="debug"></div> <script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/85/three.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
3D Accelerometer Ball Pit - Script Codes CSS Codes
html, body, canvas { margin: 0; padding: 0; overflow: hidden; position: absolute; -webkit-transform-origin: top left; transform-origin: top left; width: 100%; height: 100%; left: 0; top: 0;
}
.debug { position: fixed; color: black; background: white; top: 0; left: 0; padding: 5px; font: 10px sans-serif; z-index: 10; display: none;
}
3D Accelerometer Ball Pit - Script Codes JS Codes
(function() { var App, Ball, Camera, Colors, Container, Environment, Physics, Stage, SubClass, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; SubClass = (function() { function SubClass(parent, data) { this.parent = parent; if (this.parent.root != null) { this.root = this.parent.root; } else { this.root = this.parent; } if (typeof this.init === "function") { this.init(data); } } return SubClass; })(); Colors = (function(superClass) { extend(Colors, superClass); function Colors() { return Colors.__super__.constructor.apply(this, arguments); } Colors.prototype.init = function() { this.background = 0x8eb4c2; this.container = 0xfffdf8; return this.balls = [0xfa0f1e, 0x28ebb8, 0xffe740, 0x27aff2]; }; return Colors; })(SubClass); Stage = (function(superClass) { extend(Stage, superClass); function Stage() { this.loop = bind(this.loop, this); this.remove = bind(this.remove, this); this.add = bind(this.add, this); this.onResize = bind(this.onResize, this); return Stage.__super__.constructor.apply(this, arguments); } Stage.prototype.init = function() { this.addListeners(); this.build(); return this.onResize(); }; Stage.prototype.addListeners = function() { window.addEventListener("resize", this.onResize); return this.dpi = window.devicePixelRatio; }; Stage.prototype.build = function() { this.scene = new THREE.Scene(); this.renderer = new THREE.WebGLRenderer(); this.scene.fog = new THREE.Fog(this.root.colors.background, 0, 25); this.renderer.setClearColor(this.root.colors.background); this.renderer.shadowMap.enabled = true; this.renderer.shadowMap.type = THREE.PCFShadowMap; return document.body.appendChild(this.renderer.domElement); }; Stage.prototype.onResize = function() { this.root.width = window.innerWidth * this.dpi; this.root.height = window.innerHeight * this.dpi; this.renderer.domElement.style.transform = "scale(" + (1 / this.dpi) + ")"; return this.renderer.setSize(this.root.width, this.root.height); }; Stage.prototype.add = function(obj) { return this.scene.add(obj); }; Stage.prototype.remove = function(obj) { obj.geometry.dispose(); obj.material.dispose(); return this.scene.remove(obj); }; Stage.prototype.loop = function() { return this.renderer.render(this.scene, this.parent.camera.main); }; return Stage; })(SubClass); Camera = (function(superClass) { extend(Camera, superClass); function Camera() { this.onResize = bind(this.onResize, this); return Camera.__super__.constructor.apply(this, arguments); } Camera.prototype.init = function() { this.build(); this.addListeners(); return this.onResize(); }; Camera.prototype.build = function() { var color, ratio; ratio = this.root.width / this.root.height; color = 0xFFFFFF; this.main = new THREE.PerspectiveCamera(35, ratio, 1, 1000); this.ambient = new THREE.HemisphereLight(color, color, 1.1); this.spot = new THREE.DirectionalLight(color, 0.15); this.spot.castShadow = true; this.spot.shadow.darkness = 1; this.spot.shadow.cameraNear = 0; this.spot.shadow.cameraFar = 1500; this.spot.shadow.cameraLeft = -900; this.spot.shadow.cameraRight = 900; this.spot.shadow.cameraTop = 900; this.spot.shadow.cameraBottom = -900; this.spot.shadow.mapWidth = 1024; this.spot.shadow.mapHeight = 1024; this.spot.position.x = 9; this.spot.position.y = 9; this.spot.position.z = -15; this.parent.stage.scene.add(this.spot); return this.root.stage.scene.add(this.ambient); }; Camera.prototype.addListeners = function() { return window.addEventListener("resize", this.onResize); }; Camera.prototype.onResize = function() { this.main.aspect = this.root.width / this.root.height; this.main.updateProjectionMatrix(); this.main.position.x = this.main.position.y = 0; this.main.position.z = -3.6; return this.main.lookAt({ x: 0, y: 0, z: 1 }); }; return Camera; })(SubClass); Container = (function(superClass) { extend(Container, superClass); function Container() { this.onResize = bind(this.onResize, this); this.loop = bind(this.loop, this); return Container.__super__.constructor.apply(this, arguments); } Container.prototype.pieces = ["floor", "top", "right", "bottom", "left"]; Container.prototype.init = function() { this.build(); this.addListeners(); return this.onResize(); }; Container.prototype.build = function() { var geometry, i, len, material, piece, ref; geometry = new THREE.PlaneGeometry(2, 2, 1, 1); material = new THREE.MeshLambertMaterial({ color: this.root.colors.container, side: THREE.DoubleSide }); ref = this.pieces; for (i = 0, len = ref.length; i < len; i++) { piece = ref[i]; this[piece] = new THREE.Mesh(geometry, material); this[piece].castShadow = true; this[piece].recieveShadow = true; this[piece].collision = new CANNON.Body({ mass: 0, position: new CANNON.Vec3(0, 0, 10), shape: new CANNON.Plane() }); ({ material: this.root.physics.groundMaterial }); this.root.stage.add(this[piece]); this.root.physics.world.addBody(this[piece].collision); } this.cover = new CANNON.Body({ mass: 0, position: new CANNON.Vec3(0, 0, 3), shape: new CANNON.Plane(), material: this.root.physics.material }); return this.root.physics.world.addBody(this.cover); }; Container.prototype.addListeners = function() { return window.addEventListener("resize", this.onResize); }; Container.prototype.loop = function() { var i, len, piece, ref, results, vertex, vertices; vertices = ["x", "y", "z"]; ref = this.pieces; results = []; for (i = 0, len = ref.length; i < len; i++) { piece = ref[i]; results.push((function() { var j, len1, ref1, results1; results1 = []; for (j = 0, len1 = vertices.length; j < len1; j++) { vertex = vertices[j]; results1.push((ref1 = this[piece].collision) != null ? ref1.position[vertex] = this[piece].position[vertex] : void 0); } return results1; }).call(this)); } return results; }; Container.prototype.onResize = function() { var angle, aspect, fov, height, i, len, piece, ref, results, vector, width; ref = this.pieces; results = []; for (i = 0, len = ref.length; i < len; i++) { piece = ref[i]; this[piece].position.x = this[piece].position.y = 0; this[piece].position.z = 10; fov = 35 * Math.PI / 180; height = 2 * Math.tan(fov / 2) * 10; aspect = this.root.width / this.root.height; width = height * aspect; if (piece === "floor") { this[piece].position.z = 7.5; this[piece].scale.y = height * 0.666; this[piece].scale.x = width * 0.666; vector = new CANNON.Vec3(1, 0, 0); angle = 180 * (Math.PI / 180); this[piece].collision.quaternion.setFromAxisAngle(vector, angle); } if (piece === "left" || piece === "right") { this[piece].rotation.y = 90 * (Math.PI / 180); this[piece].position.y = 0; this[piece].scale.y = height * 0.666 * 2; this[piece].scale.x = 10; vector = new CANNON.Vec3(0, 1, 0); angle = -90 * (Math.PI / 180); if (piece === "left") { this[piece].position.x = width * 0.666 * 0.5; } else { angle = -angle; this[piece].position.x = width * -0.666 * 0.5; } this[piece].collision.quaternion.setFromAxisAngle(vector, angle); } if (piece === "top" || piece === "bottom") { this[piece].rotation.x = 90 * (Math.PI / 180); this[piece].position.x = 0; this[piece].scale.x = width * 0.666 * 2; this[piece].scale.y = 10; vector = new CANNON.Vec3(1, 0, 0); angle = -90 * (Math.PI / 180); if (piece === "top") { this[piece].position.y = height * 0.666 * 0.5; angle = -angle; } else { this[piece].position.y = height * -0.666 * 0.5; } results.push(this[piece].collision.quaternion.setFromAxisAngle(vector, angle)); } else { results.push(void 0); } } return results; }; return Container; })(SubClass); Ball = (function(superClass) { extend(Ball, superClass); function Ball() { this.loop = bind(this.loop, this); return Ball.__super__.constructor.apply(this, arguments); } Ball.prototype.init = function() { return this.build(); }; Ball.prototype.build = function() { var geometry, material, position, scale; scale = 0.15 + Math.random() * 0.3; geometry = new THREE.SphereGeometry(scale, 12, 12); material = new THREE.MeshLambertMaterial({ vertexColors: THREE.FaceColors, color: this.root.colors.balls[Math.floor(Math.random() * this.root.colors.balls.length)] }); this.piece = new THREE.Mesh(geometry, material); this.piece.castShadow = true; this.piece.recieveShadow = false; position = { x: Math.random() * 8 - 4, y: Math.random() * 8 - 4, z: 4 + Math.random() * 5 }; this.piece.collision = new CANNON.Body({ mass: scale * 20, shape: new CANNON.Sphere(scale), position: new CANNON.Vec3(position.x, position.y, position.z), material: this.root.physics.material }); this.root.stage.add(this.piece); return this.root.physics.world.addBody(this.piece.collision); }; Ball.prototype.loop = function() { var i, len, results, vertex, vertices; vertices = ["x", "y", "z"]; results = []; for (i = 0, len = vertices.length; i < len; i++) { vertex = vertices[i]; results.push(this.piece.position[vertex] = this.piece.collision.position[vertex]); } return results; }; return Ball; })(SubClass); Environment = (function(superClass) { extend(Environment, superClass); function Environment() { this.loop = bind(this.loop, this); return Environment.__super__.constructor.apply(this, arguments); } Environment.prototype.init = function() { var results, total; this.container = new Container(this); this.balls = []; total = 25; results = []; while (total > 0) { this.balls.push(new Ball(this)); results.push(total--); } return results; }; Environment.prototype.loop = function() { var ball, i, len, ref, results; this.container.loop(); ref = this.balls; results = []; for (i = 0, len = ref.length; i < len; i++) { ball = ref[i]; results.push(ball.loop()); } return results; }; return Environment; })(SubClass); Physics = (function(superClass) { extend(Physics, superClass); function Physics() { this.loop = bind(this.loop, this); this.onMouseMove = bind(this.onMouseMove, this); this.onDeviceMotion = bind(this.onDeviceMotion, this); return Physics.__super__.constructor.apply(this, arguments); } Physics.prototype.init = function() { this.build(); return this.addListeners(); }; Physics.prototype.build = function() { var material; this.ios = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; this.world = new CANNON.World(); this.world.broadphase = new CANNON.NaiveBroadphase(); this.world.gravity.set(0, 0, 0); this.world.solver.iterations = 20; this.world.solver.tolerance = 0; this.material = new CANNON.Material(); material = new CANNON.ContactMaterial(this.material, this.material); material.restitution = 0.7; material.friction = 0.1; material.contactEquationStiffness = 100000000; material.contactEquationRegularizationTime = 3; this.world.addContactMaterial(material); this.world.defaultContactMaterial = material; this.past = new Date().getTime(); return this.debug = document.querySelector(".debug"); }; Physics.prototype.addListeners = function() { window.addEventListener("devicemotion", this.onDeviceMotion); return window.addEventListener("mousemove", this.onMouseMove); }; Physics.prototype.onDeviceMotion = function(e) { var acceleration, mult, ox, oy, oz, x, y, z; x = 0; y = -9.86; z = 0; ox = 0; oy = 0; oz = -3.5; mult = 1; if (this.ios) { mult = -1; } acceleration = e.accelerationIncludingGravity; if (acceleration.x !== null) { x = acceleration.x * mult; } if (acceleration.y !== null) { y = -acceleration.y * mult; } if (acceleration.z !== null) { z = acceleration.z * mult; } this.world.gravity.set(x, y, z); this.root.camera.main.position.x = ox; this.root.camera.main.position.y = oy; return this.root.camera.main.position.z = oz; }; Physics.prototype.onMouseMove = function(e) { var x, y; x = (e.clientX / window.innerWidth) - 0.5; y = (e.clientY / window.innerHeight) - 0.5; this.world.gravity.set(-x * 9, -y * 9, 0); this.root.camera.spot.position.x = x * 5; this.root.camera.spot.position.y = y * 5; this.root.camera.main.position.x = x * 0.1; return this.root.camera.main.position.y = y * 0.1; }; Physics.prototype.loop = function() { var delta, present; present = new Date().getTime(); delta = present - this.past; this.past = present; return this.world.step(1 / 60, delta, 3); }; return Physics; })(SubClass); App = (function() { function App() { this.loop = bind(this.loop, this); this.colors = new Colors(this); this.stage = new Stage(this); this.camera = new Camera(this); this.physics = new Physics(this); this.environment = new Environment(this); this.loop(); } App.prototype.loop = function() { var base, i, len, results, task, tasks; requestAnimationFrame(this.loop); tasks = ["physics", "environment", "stage"]; results = []; for (i = 0, len = tasks.length; i < len; i++) { task = tasks[i]; results.push(typeof (base = this[task]).loop === "function" ? base.loop() : void 0); } return results; }; return App; })(); new App();
}).call(this);
Developer | Alex Bergin |
Username | abergin |
Uploaded | September 23, 2022 |
Rating | 4.5 |
Size | 8,397 Kb |
Views | 32,384 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
B - Bicycle | 3,983 Kb |
Background animation | 5,314 Kb |
Bauble | 5,287 Kb |
Motion blur loader | 2,505 Kb |
Ghost | 5,310 Kb |
Singing Text To Speech | 9,647 Kb |
Show Nav On Scroll | 4,898 Kb |
Using Pseudo Elements for Input Styling | 3,999 Kb |
Hsl text shadow generator | 4,200 Kb |
Fancy Text Inputs | 3,934 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
CSS-Flexbox-Demo | Sstiglets | 1,709 Kb |
NeeilTimer | Neeilan | 2,836 Kb |
Konami Code Easter Egg | Teolitto | 3,051 Kb |
Wikipedia Viewer | Thomasvaeth | 2,549 Kb |
Cars going | Netoguimaraes | 1,699 Kb |
Nice responsive team page | Infomiho | 3,139 Kb |
A Pen by Patrick Cox | Pcridesagain | 2,899 Kb |
Sencha Touch 2.3.1 Basic Grid Example | Trozdol | 2,770 Kb |
Custom Checkbox and radio inputs SCSS | Rgfx | 3,367 Kb |
Wrap_Test | Mscfourn | 7,503 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!