Easy physics sandbox in JavaScript

< html >< body > < script src =' matter . min . js ' type =' text / javascript '></ script > < script > let mode = 0 ; let Engine = Matter . Engine , Body = Matter . Body , Render = Matter . Render , World = Matter . World , Bodies = Matter . Bodies , Events = Matter . Events , Vertices = Matter . Vertices , Composites = Matter . Composites ; let engine = Engine . create (); let render = Render . create ({ element : document . body , engine : engine , options : { wireframes : false } }); Engine . run ( engine ); Render . run ( render ); let world = engine . world ; let width = render . canvas . width ; let bodySelected = null , compositeSelected = null ; let menu = Bodies . rectangle ( width / 2 , 60 , width , 75 , { isStatic : true }); let selection = Bodies . rectangle ( width / 10 , 0 , width / 5 , 30 ); menu . render . sprite . texture = ' menu . png '; let Mouse = Matter . Mouse ; let MouseConstraint = Matter . MouseConstraint ; let mouse = Mouse . create ( render . canvas ); let mouseConstraint = MouseConstraint . create ( engine , { mouse : mouse }); render . mouse = mouse ; World . add ( world , [ menu , selection , mouseConstraint ]); document . addEventListener (' contextmenu ', event => event . preventDefault ()); function check ( parent ) { for ( let i = 0 ; i < parent . bodies . length ; i ++) { let body = parent . bodies [ i ]; if ( Vertices . contains ( body . vertices , mouse . position )) { if ( parent !== world ) compositeSelected = parent ; bodySelected = body ; } } } Events . on ( mouseConstraint , ' mousedown ', function ( event ) { let x = mouse . position . x ; let y = mouse . position . y ; if ( y < 100 ) { mode = Math . floor ( x / ( width / 5 )); Body . setPosition ( selection , { x : mode * width / 5 + width / 10 , y : 10 }); } else { let static = event . mouse . button == 2 ; bodySelected = null ; compositeSelected = null ; check ( world ); for ( let k = 0 ; k < world . composites . length ; k ++) { let composite = world . composites [ k ]; check ( composite ); } if ( bodySelected == null ) { let object1; switch ( mode ) { case 0 : object1 = Bodies . circle ( x , y , 30 , { isStatic : static }); break ; case 1 : object1 = Bodies . rectangle ( x , y , 60 , 30 , { isStatic : static }); break ; case 2 : object1 = Bodies . trapezoid ( x , y , 60 , 30 , . 5 , { isStatic : static }); break ; case 3 : object1 = Composites . car ( x , y , 90 , 10 , 35 ); break ; case 4 : object1 = Composites . newtonsCradle ( x , y , 5 , 10 , 80 ); break ; } World . add ( world , object1); if (object1. type == ' composite ') { compositeSelected = object1; bodySelected = compositeSelected . bodies [ 1 ]; } else { compositeSelected = null ; bodySelected = object1; } } } }); document . onkeydown = function keyPress ( e ) { switch ( e . keyCode ) { case 68 : if ( compositeSelected ) World . remove ( world , compositeSelected ); else World . remove ( world , bodySelected ); break ; case 82 : Body . rotate ( bodySelected , Math . PI / 4 ); break ; case 88 : Body . scale ( bodySelected , 1 . 1 , 1 ); break ; case 89 : Body . scale ( bodySelected , 1 , 1 . 1 ); break ; case 78 : Body . scale ( bodySelected , . 9 , 1 ); break ; case 77 : Body . scale ( bodySelected , 1 , . 9 ); break ; } }; </ script > </ body ></ html >

This simple little physics sandbox was created with just several lines of code using the great Matter.js library. The code below should be simple enough for even inexperienced JavaScripters to understand, but you can follow this link to learn more about the fundamental setup. [Lines 1-23] are just standard overhead to create the world (the environment where our physics will happen). In most cases, you won't need to modify anything here. If you're ok with wireframes instead of the colorful filled objects, you can even delete [17-20] to further simplify the code.[24-26] initialize variables:width - canvas width, which will be used to calculate the size and position of the menuWe will be using 'bodies' (simple shapes: circle, rectangle and trapezoid) as well as 'composites' (more complex objects: car and Newton's cradle, consisting of 'bodies').The user will be able to select one body (bodySelected) and one composite (compositeSelected) at a time and delete, rotate and resize them.[27] our menu at the top of the screen is a Matter.js rectangle. It is Static so that it doesn't fall down.[30] the selection bar is also a rectangle. It lies on top of the menu. You can actually drag it with your mouse for fun, but that doesn't change the selection.[31] assign the bitmap image of the menu item to the menu rectangle using the Matter.js sprite functionality[33-40] standard Matter.js mouse constraint - use these lines whenever you want to allow users to click and drag objects using the mouse[43-51] This function checks if an object has been clicked and if so, selects it. We're checking all the bodies belonging to a parent using the library method Vertices.contains.[53-106] all the real action is in this function triggered by the Matter.js mousedown event:[54-5] get the mouse coordinates[56-61] if the menu is clicked, change the mode based on the x coordinate of the mouse. The mode determines what objects are drawn on the scene.If the scene is clicked:[63] if the right button is clicked, the object will be static (can not be dragged and gravity does not pull it down). It is useful for building floors and walls.[66] check if a body was clicked which is not part of any Composite. Such bodies belong to the 'world' object. If so, select the body and the compositeSelected is null.[67-69] check whether a body that is a part of a Composite was clicked. Such bodies do not belong directly to the world object, but to Composites.[71-106] if no body was clicked, create a new object and [95] add it to the world. The type of object is determined by the current mode [72-94].[97-9] if a new composite was created, it becomes the compositeSelected. It's second body ([1]) becomes the bodySelected - for cars, it's the left wheel. For Newton's cradles, it's the second ball.[108-131] keyboard handling:[110-114] deletion[115-117] rotation[118-129] scalingScaling and rotation is only available in our sandbox for Bodies, not for Composities. You can add it using Composite.rotate and Composite.scale, but I decided to keep leave it out to keep the code shorter.Check out these programming tutorials: