UNPKG

newton

Version:

A playful, particle-based physics engine designed from the ground up for JavaScript.

310 lines (286 loc) 13.3 kB
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <title>Newton - guide</title> <link href="http://fonts.googleapis.com/css?family=Poiret+One" rel="stylesheet" type="text/css"> <link href="http://fonts.googleapis.com/css?family=Roboto:400" rel="stylesheet" type="text/css"> <link rel="stylesheet" type="text/css" href="styles/base.css"> <link rel="stylesheet" type="text/css" href="styles/smart-grid.css"> <link rel="stylesheet" type="text/css" href="styles/modules.css"> </head> <body> <div class="Header"> <div class="container"> <header class="row"> <div class="columns four"><a href="http://hunterloftis.github.io/newton/"> <h1 class="Logo">Newton</h1></a></div> <div class="columns eight"> <div class="MainMenu"><a href="/dist/docs/guide.html" class="active">Guide</a><a href="#">API Reference</a><a href="https://github.com/hunterloftis/newton">Github</a><a href="https://github.com/hunterloftis/newton/issues?direction=desc&amp;sort=created&amp;state=open">Issues</a></div> </div> </header> </div> </div> <div class="container"> <div class="row"> <nav class="columns three SideBar"> <ul> <li><a href="#hello">Hello, World <ul> <li><a href="#install">Install the library</a></li> <li><a href="#simulation">Create a simulation</a></li> <li><a href="#particle">Add a particle</a></li> <li><a href="#render">Render the scene</a></li> <li><a href="#demo_hello">Demo: Hello, World</a></li> </ul></a></li> <li><a href="#basics">Movement <ul> <li><a href="#forces">Forces</a></li> <li><a href="#constraints">Constraints</a></li> <li><a href="#demo_basics">Demo: Rope</a></li> </ul></a></li> <li><a href="#bodies_group">Bodies <ul> <li><a href="#bodies">Create a Body</a></li> <li><a href="#extending_body">Extending Body</a></li> <li><a href="#demo_bodies">Demo: Rope Body</a></li> </ul></a></li> <li><a href="#interaction">Interaction <ul> <li><a href="#input">Input</a></li> <li><a href="#removal">Removal</a></li> <li><a href="#destruction">Destruction</a></li> <li><a href="#demo_behavior">Demo: Interactive Rope</a></li> </ul></a></li> </ul> </nav> <main class="columns nine"><a name="hello"></a> <h2>Hello, World</h2><a name="install"></a> <h3>Install the library</h3> <div class="Section-content"> <p> <ul> <li><a href="http://hunterloftis.github.io/newton/current/newton.js">newton.js</a></li> <li><a href="http://hunterloftis.github.io/newton/current/newton.min.js">newton.min.js</a></li> </ul> </p> <p>Or with npm: <pre class="CodeBlock">npm install --save newton</pre> <pre class="CodeBlock">var Newton = require('newton');</pre> </p> </div><a name="simulation"></a> <h3>Create a simulation</h3> <div class="Section-content"> <p> The Simulator is responsible for integrating Particles, applying Forces, and resolving Constraints. </p> <p> All the high-level and advanced functionality of Newton is based on these three simple steps. </p> <pre class="CodeBlock">var sim = Newton.Simulator(); sim.start();</pre> </div><a name="particle"></a> <h3>Add a particle</h3> <div class="Section-content"> <p> Newton has three building blocks: Particles, Forces, and Constraints. Particles are points in space that have X and Y coordinates as well as mass (size). </p> <pre class="CodeBlock">var particle = Newton.Particle(10, 20); // x, y sim.add(particle); </pre> </div><a name="render"></a> <h3>Render the scene</h3> <div class="Section-content"> <p> Newton ships with a WebGL-based renderer for development and debugging. To use it, you'll need to create a canvas element on your page. In this case, we've called our canvas `#display`. </p> <p> You can render anyway you like - canvas, webgl, DOM, SVG, etc. All renderers support a simple interface. </p> <pre class="CodeBlock">var display = document.getElementById('display'); var renderer = Newton.GLRenderer(display); renderer.render(sim); </pre> </div><a name="demo_hello"></a> <h3>Demo: Hello, World</h3> <div class="Section-content"> <p> As you can see, we're up and running - but it's a little boring with just one Particle sitting still. </p> <div class="Demo-container"> <iframe src="http://jsfiddle.net/hunterloftis/yDY6r/2/embedded/js,result,html" class="Demo"></iframe> </div> </div><a name="basics"></a> <h2>Movement</h2><a name="forces"></a> <h3>Forces</h3> <div class="Section-content"> <p> Forces are the second basic element of Newton. Each frame, the Simulator applies Forces to Particles in order to create movement. </p> <p> Newton comes with a library of Forces, and you can easily add your own. </p> <pre class="CodeBlock">var gravity = Newton.LinearForce(1, Math.PI * 1.5); // strength, direction sim.add(gravity); </pre> </div><a name="constraints"></a> <h3>Constraints</h3> <div class="Section-content"> <p>Constraints are the third basic element of Newton and are its most powerful feature.</p> <p> They create rules that are applied to Particles after integration, like "All particles should stay within this rectangle," or "These two particles should be connected." </p> <p> BoxConstraint is a location constraint that keeps a particle within a rectangular area. Newton comes with a library of Constraints. </p> <pre class="CodeBlock">var container = Newton.BoxConstraint(0, 0, 1000, 600); // x, y, width, height sim.add(container); </pre> <p> The simulator runs constraints repeatedly to converge at an approximate solution. Since constraints can conflict with each other, it's a good idea to give Newton a hint about which constraints are most important. You can do this via the Simulator's <span class='Code'>solve</span> option: </p> <pre class="CodeBlock">var sim = Newton.Simulator({ solve: [ Newton.PinConstraint, Newton.RopeConstraint ] // PinConstraint is more important than RopeConstraint }); </pre> </div><a name="demo_basics"></a> <h3>Demo: Rope</h3> <div class="Section-content"> <p> Now things are getting interesting. Our little rope has come to life! </p> <div class="Demo-container"> <iframe src="http://jsfiddle.net/hunterloftis/a4kXG/2/embedded/js,result,html" class="Demo"></iframe> </div> </div><a name="bodies_group"></a> <h2>Bodies</h2><a name="bodies"></a> <h3>Create a Body</h3> <div class="Section-content"> <p> When building a simulation, you frequently want to refer to a group of Particles, Forces, and Constraints as a single entity. Newton uses the concept of Bodies for grouping elements. </p> <p> Instead of adding Particles and Constraints directly to the Simulator, we can instead add them as a group in a Body: </p> <pre class="CodeBlock">var rope = Newton.Body(); rope.add(Newton.Particle(500 + i * 20, 180)); rope.add(Newton.RopeConstraint(prev, current)); sim.add(rope); </pre> <p> Keep in mind, Bodies are just for bookkeeping - logical groupings so your code can be readable. They have no impact on the simulation. </p> </div><a name="extending_body"></a> <h3>Extending Body</h3> <div class="Section-content"> <p> In most cases, you'll extend Newton's base Body to create reusable custom Body types. For example, let's create a Rope Body: </p> <pre class="CodeBlock">function Rope(x, y, length) { Newton.Body.call(this); // call Body's constructor // implementation here } Rope.prototype = Object.create(Newton.Body.prototype); // extend Body's prototype var rope = new Rope(225, 10, 300); </pre> </div><a name="demo_bodies"></a> <h3>Demo: Rope Body</h3> <div class="Section-content"> <p> Reuse! We now have a drop-in Rope Body that we can use as many times as we like: </p> <div class="Demo-container"> <iframe src="http://jsfiddle.net/hunterloftis/6FJtv/4/embedded/js,result,html" class="Demo"></iframe> </div> <p> We can also extend Rope with new data and behaviors. We've already given it a head property - we could also add a tail property or methods like coil() or snap() </p> </div><a name="interaction"></a> <h2>Interaction</h2><a name="input"></a> <h3>Input</h3> <div class="Section-content"> <p> Interacting with Newton is easy - just inject Forces, Particles, or Constraints into the system based on your user's behavior. </p> <pre class="CodeBlock">var mousePin = null; renderer.on('pointerdown', function(point) { var particle = sim.findNearest(point, 30); if (particle) mousePin = sim.add(Newton.PinConstraint(particle, point)); }); </pre> <p> In this case, we've added a PinConstraint to represent the user. When the user clicks on a Particle, we bind the Particle to a new constraint, which we update to follow wherever the user moves her mouse. </p> </div><a name="removal"></a> <h3>Removal</h3> <div class="Section-content"> <p> Just like add() adds Particles, Forces, and Constraints to a simulation, remove() removes them. </p> <p> In this case, we want to remove the PinConstraint whenever the user releases her mouse, so she can "let go" of the dragged Particle: </p> <pre class="CodeBlock">renderer.on('pointerup', function(point) { if (!mousePin) return; sim.remove(mousePin); mousePin = null; });</pre> </div><a name="destruction"></a> <h3>Destruction</h3> <div class="Section-content"> <p> Some Constraints can receive options that include some sort of strength value. If a Simulation reaches a point where the Constraint is acting beyond its strength, it will destroy itself to create realistic deformations and structural behavior. </p> <p> RopeConstraints can have a tensile strength. Here, we specify that once the Constraint stretches to 3x its original length, it should break: </p> <pre class="CodeBlock">this.add(Newton.RopeConstraint(prev, current, { length: segmentLength, stiffness: 0.9, // slightly springy strength: 3 // break when stretched to 3x length } ));</pre> </div><a name="demo_behavior"></a> <h3>Demo: Interactive Rope</h3> <div class="Section-content"> <p> Now we can drag our ropes around! If we stretch them too far they'll even realistically break. </p> <div class="Demo-container"> <iframe src="http://jsfiddle.net/hunterloftis/SK6SH/1/embedded/js,result,html" class="Demo"></iframe> </div> </div> </main> </div> </div> </body> </html>