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 |
Sibling Selector Style Change on Hover | 3,087 Kb |
P - Polaroid | 3,532 Kb |
Hsl text shadow generator | 4,200 Kb |
SASS Placeholder Style Mixin | 2,130 Kb |
Header Layout | 3,123 Kb |
A Pen by Alex Bergin | 3,347 Kb |
E - Espresso | 4,229 Kb |
Spinning Liquid In Box Loader Doodle | 2,992 Kb |
Ghost | 5,310 Kb |
Motion blur loader | 2,505 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 |
Sexy Social Buttons | Ipiyale | 2,226 Kb |
TweenMax transformOrigin Bubble | Nicolund | 2,209 Kb |
Halo 5 REQ Guide Bookmarklet | Cwacht | 3,993 Kb |
Flexbox Grid - equal height | DaveOrDead | 2,855 Kb |
CSS Infinite 360 | APinix | 5,564 Kb |
Underlined form fields | Mitchdot | 2,323 Kb |
Simple Accordion | Wearebold | 3,683 Kb |
LeMandinque | Aadesida | 9,046 Kb |
Nested flexbox layout for library catalog | Boycetrus | 3,271 Kb |
Slide out Menu | Rbiggs | 4,936 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!