{"id":201,"date":"2021-09-05T22:58:30","date_gmt":"2021-09-05T22:58:30","guid":{"rendered":"http:\/\/www.shacarah.com\/main\/?p=201"},"modified":"2021-09-27T15:15:20","modified_gmt":"2021-09-27T15:15:20","slug":"html5-canvas-gravity-falling-objects-animation","status":"publish","type":"post","link":"https:\/\/www.shacarah.com\/main\/script-animations\/html5-canvas-gravity-falling-objects-animation\/","title":{"rendered":"HTML5 Canvas Gravity Falling Objects Animation"},"content":{"rendered":"\n<p>Pure JavaScript animation.<\/p>\n\n\n\n<p>The basic concept for these particle animations started with some basic physics after being curious what the terminal velocity of rain is. <\/p>\n\n\n\n<div class=\"content\">\n<script src=\"https:\/\/www.shacarah.com\/Scripts\/modernizr-2.0.6.js\"><\/script>\n<script src=\"https:\/\/www.shacarah.com\/Scripts\/rainTrails.js\"><\/script>\n    <canvas id=\"canvas1\" style=\"width:100%\">\n    <\/canvas>\n<\/div>\n\n\n\n<p> Originally code was written in 2013 in AS3 (Flash ActionScript 3). <\/p>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/look up any objects density (water has a density of 1) and drag coefficient (http:\/\/en.wikipedia.org\/wiki\/Drag_coefficient)\r\n\/\/changing the stage dimensions will not affect the code\r\n\/\/ time is derived from 60 frames per second in the calculations\r\nstage.frameRate = 60;\r\n\/\/ holds the falling objects\r\nvar dropsVector: Vector. &lt; Sprite > =new Vector. &lt; Sprite > ();\r\n\/\/ holds the time for each object - the calculations on enter frame below are all functions of time\r\nvar framesVector: Vector. &lt; Number > =new Vector. &lt; Number > ();\r\n\/\/ holds what the velocity is for each object\r\nvar velocityVector: Vector. &lt; Number > =new Vector. &lt; Number > ();\r\nvar numOfDrops: Number = 300;\r\n\/\/gravity here is 9.8 pixels\r\nvar gravity: Number = 9.8;\r\n\/\/ how close together the stuff this object is made of is\r\nvar density: Number = 1;\r\n\/\/ how thick is the air\r\nvar airDensity: Number = 1.29;\r\n\/\/how much air does the object \"catch\" increase to slow down an decrease to speed up\r\nvar dragCoefficient: Number = .47;\r\n\/\/minimum and maximum scale of the water droplets\r\nvar maxScale: Number = 1.3;\r\nvar minScale: Number = .3;\r\n\/\/ create all the droplets doesn't have to be a Sprite could be sprite or you could create a clip give it a class name and add it in place of the circle\r\nfor (var i: Number = 0; i &lt; numOfDrops; i++) {\r\n\tvar rainDrop: Sprite = new Sprite();\r\n\trainDrop.graphics.beginFill(0x82CDFF, 1);\r\n\trainDrop.graphics.drawCircle(0, 0, 1);\r\n\trainDrop.graphics.endFill();\r\n\t\/\/set a random location on the stage so it isn't blank with a sudden shower of water - neat experiment though just get rid of the Math.Random()* before rainDrop.y\r\n\trainDrop.x = Math.random() * stage.stageWidth;\r\n\trainDrop.y = Math.random() * stage.stageHeight * -2;\r\n\trainDrop.scaleX = Math.random() * (maxScale - minScale) + minScale;\r\n\trainDrop.scaleY = rainDrop.scaleX;\r\n\t\/\/put a value for each droplet into the holders (object, time, velocity)\r\n\tdropsVector.push(rainDrop);\r\n\tframesVector.push(0);\r\n\tvelocityVector.push(0);\r\n}\r\n\/\/ super cool guy Dan Geis wrote this stuff (http:\/\/www.flashandmath.com\/intermediate\/ghost\/)\r\n\/\/ its pretty simple and very cool - basically create a bitmap (image) redraw all those droplets every frame and blur the previous one makes pretty trails\r\nvar bitmapData: BitmapData;\r\nvar bitmap: Bitmap;\r\nvar displayWidth: Number;\r\nvar displayHeight: Number;\r\nvar display: Sprite;\r\nvar origin: Point;\r\nvar colorTransform1: ColorTransform;\r\ndisplay = new Sprite();\r\ndisplayWidth = stage.stageWidth;\r\ndisplayHeight = stage.stageHeight;\r\nbitmapData = new BitmapData(displayWidth, displayHeight, true, 0x00000000);\r\nbitmap = new Bitmap(bitmapData);\r\nvar blur: BlurFilter = new BlurFilter();\r\nblur.blurX = 2;\r\nblur.blurY = 2;\r\ncolorTransform1 = new ColorTransform(0.999, 0.999, 0.999, .8);\r\norigin = new Point(0, 0);\r\nbitmap.x = 0;\r\nbitmap.y = 0;\r\naddChild(bitmap);\r\n\/\/end Dan's code\r\naddEventListener(Event.ENTER_FRAME, rainDown);\r\nfunction rainDown(event: Event) {\r\n\tfor (var n: Number = 0; n &lt; dropsVector.length; n++) {\r\n\t\t\/\/ keeps track of time falling for each droplet\r\n\t\tframesVector&#91;n] = framesVector&#91;n] + 1;\r\n\t\tvar time: Number = framesVector&#91;n] \/ 60;\r\n\t\t\/\/ all this stuff is what really calculates the terminal velocity... these are not perfect measurements\r\n\t\tvar velocity: Number = .5 * (gravity * Math.pow(time, 2));\r\n\t\tvar volume_: Number = ((4 \/ 3) * (Math.PI * Math.pow((dropsVector&#91;n].width \/ 2), 3)));\r\n\t\t\/\/ spherical object volume if you want a none a spherical object look up the volume formula for said object and apply it here\r\n\t\tvar mass: Number = density * volume_;\r\n\t\t\/\/ mass \"how much stuff there is\"\r\n\t\tvar weight: Number = gravity * mass;\r\n\t\t\/\/ not really weight of the object this is a reference to something more like force of the object due to gravity\r\n\t\tvar area: Number = Math.PI * Math.pow(dropsVector&#91;n].width \/ 2, 2);\r\n\t\t\/\/ cross sectional area, if you chop and object exactly down the middle at its widest point and take the area of that, that is the cross sectional area again I'm taking a circular area\r\n\t\tvar drag: Number = dragCoefficient * (.5 * (airDensity * Math.pow(velocity, 2))) * area;\r\n\t\t\/\/calculates the drag based on the air density the cross sectional area and drag coefficient\r\n\t\tvar terminalVelocity: Number = (weight - drag) \/ mass;\r\n\t\t\/\/when the weight force and drag equal each-other that is terminal velocity, test this out for yourself change the drag coefficient to 0 move all the object to the same location on the y axis and run the program, they all fall at exactly the same speed\r\n\t\tif (terminalVelocity >= 0) {\r\n\t\t\t\/\/test that terminal velocity is equal to 0 (weight-drag)\/mass = 0... terminal velocity\r\n\t\t\tvelocityVector&#91;n] = velocity;\r\n\t\t}\r\n\t\t\/\/ move the droplets down\r\n\t\tdropsVector&#91;n].y += velocityVector&#91;n];\r\n\t\t\/\/ if the droplets go off the stage move them back to the top... no real need for the x test here unless you decide to make wind :)\r\n\t\tif (dropsVector&#91;n].x > stage.stageWidth || dropsVector&#91;n].x &lt; 0 || dropsVector&#91;n].y > stage.stageHeight) {\r\n\t\t\t\/\/reset the time, scale, location to some random settings\r\n\t\t\tframesVector&#91;n] = 0;\r\n\t\t\tdropsVector&#91;n].x = Math.random() * stage.stageWidth;\r\n\t\t\tdropsVector&#91;n].y = dropsVector&#91;n].height * -1;\r\n\t\t\t\/\/if you want to stop the dripping look change -1 to a larger negative number\r\n\t\t\tdropsVector&#91;n].scaleX = Math.random() * (maxScale - minScale) + minScale;\r\n\t\t\tdropsVector&#91;n].scaleY = dropsVector&#91;n].scaleX;\r\n\t\t}\r\n\t\t\/\/ adds the droplets to the display where the bitmap is draw that adds the trails\r\n\t\tdisplay.addChild(dropsVector&#91;n]);\r\n\t}\r\n\t\/\/ draws the bitmap\r\n\tbitmapData.applyFilter(bitmapData, bitmapData.rect, origin, blur);\r\n\tbitmapData.colorTransform(bitmapData.rect, colorTransform1);\r\n\tbitmapData.draw(display);\r\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Pure JavaScript animation. The basic concept for these particle animations started with some basic physics after being curious what the terminal velocity of rain is. Originally code was written in 2013 in AS3 (Flash ActionScript 3).<\/p>\n","protected":false},"author":1,"featured_media":202,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,6],"tags":[],"class_list":["post-201","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html5-canvas","category-script-animations"],"_links":{"self":[{"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/posts\/201"}],"collection":[{"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/comments?post=201"}],"version-history":[{"count":4,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/posts\/201\/revisions"}],"predecessor-version":[{"id":463,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/posts\/201\/revisions\/463"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/media\/202"}],"wp:attachment":[{"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/media?parent=201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/categories?post=201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/tags?post=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}