{"id":204,"date":"2021-09-05T23:03:23","date_gmt":"2021-09-05T23:03:23","guid":{"rendered":"http:\/\/www.shacarah.com\/main\/?p=204"},"modified":"2021-09-27T14:15:29","modified_gmt":"2021-09-27T14:15:29","slug":"html5-canvas-particle-force-animation","status":"publish","type":"post","link":"https:\/\/www.shacarah.com\/main\/script-animations\/html5-canvas-particle-force-animation\/","title":{"rendered":"HTML5 Canvas Particle Force 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\/SpriteSheetForce.js\"><\/script>\n\n    <canvas id=\"canvas2\" style=\"width:100%\">\n    <\/canvas>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Originally code was written in 2013 in AS3 (Flash ActionScript 3).<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\" style=\"text-align:center; background-color:#000;\">\n<iframe loading=\"lazy\" title=\"Flash AS3 Concept of Applying a Force\" width=\"640\" height=\"480\" src=\"https:\/\/www.youtube.com\/embed\/7wstJOlY0lM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/simple idea of a force using distance\n\nstage.frameRate = 60;\nvar particlesVector: Vector. &lt; Sprite &gt; =new Vector. &lt; Sprite &gt; ();\nvar framesVector: Vector. &lt; Number &gt; =new Vector. &lt; Number &gt; ();\nvar velocityVector: Vector. &lt; Number &gt; =new Vector. &lt; Number &gt; ();\nvar numOfParticles: Number = 500;\nvar targetX = stage.stageWidth \/ 2;\nvar targetY = stage.stageHeight \/ 2;\nvar gravity: Number = 9.8;\nvar forceStrength: Number = .05;\nvar forceSize: Number = 150;\nvar forceSpeed: Number = .2;\nvar density: Number = .1;\nvar airDensity: Number = 1.29;\nvar dragCoefficient: Number = 2.1;\nvar particleScaleMax: Number = 2;\nvar particleScaleMin: Number = .1;\nvar timeCounter: Number = 0;\n\n\/\/visit http:\/\/www.flashandmath.com\/intermediate\/ghost\/index.html\n\/\/www.flashandmath.com\/intermediate\/ghost\/GhostingEffect.fla\n\/\/credit for ghosting effect Dan Gries your kinda awesome :)\nvar bitmapData: BitmapData;\nvar bitmap: Bitmap;;\nvar displayWidth: Number;\nvar displayHeight: Number;\nvar display: Sprite;\nvar origin: Point;\nvar colorTransform: ColorTransform;\ndisplay = new Sprite();\ndisplayWidth = stage.stageWidth;\ndisplayHeight = stage.stageHeight;\nbitmapData = new BitmapData(displayWidth, displayHeight, true, 0x00000000);\nbitmap = new Bitmap(bitmapData);\nvar blur: BlurFilter = new BlurFilter();\nblur.blurX = 5;\nblur.blurY = 5;\ncolorTransform = new ColorTransform(0.999, 0.90, 0.70, 1);\norigin = new Point(0, 0);\nbitmap.x = 0;\nbitmap.y = 0;\naddChild(bitmap);\n\nfor (var i: Number = 0; i &lt; numOfParticles; i++) {\n\tvar particle: Sprite = new Sprite();\n\tparticle.graphics.beginFill(0xFF0000);\n\tparticle.graphics.drawCircle(0, 0, 1);\n\tparticle.graphics.endFill();\n\tparticle.x = Math.random() * stage.stageWidth;\n\tparticle.y = Math.random() * stage.stageHeight;\n\tparticle.scaleX = Math.random() * (particleScaleMax - particleScaleMin) + particleScaleMin;\n\tparticle.scaleY = particle.scaleX;\n\tparticlesVector.push(particle);\n\tframesVector.push(0);\n\tvelocityVector.push(0);\n}\n\naddEventListener(Event.ENTER_FRAME, animateParticles);\nvar forceField: Sprite = new Sprite();\nforceField.graphics.lineStyle(2, 0xFFFFFFF, .75);\nforceField.graphics.drawCircle(0, 0, forceSize);\nforceField.graphics.endFill();\naddChild(forceField);\nforceField.x = targetX;\nforceField.y = targetY;\nvar forceFieldArrow: Sprite = new Sprite();\nforceFieldArrow.graphics.lineStyle(2, 0xFFFFFFF, .75);\nforceFieldArrow.graphics.moveTo(0, 0);\nforceFieldArrow.graphics.lineTo(forceSize \/ 1.5 * -1, 0);\nforceFieldArrow.graphics.moveTo(forceSize \/ 1.5 * -1, 0);\nforceFieldArrow.graphics.lineTo(forceSize \/ 2 * -1, forceSize \/ 10);\nforceFieldArrow.graphics.moveTo(forceSize \/ 1.5 * -1, 0);\nforceFieldArrow.graphics.lineTo(forceSize \/ 2 * -1, forceSize \/ 10 * -1);\nforceField.addChild(forceFieldArrow);\n\nfunction animateParticles(event: Event) {\n\ttimeCounter++;\n\tfor (var n: Number = 0; n &lt; particlesVector.length; n++) {\n\t\tframesVector&#91;n] = framesVector&#91;n] + 1;\n\t\tvar time: Number = framesVector&#91;n] \/ 60;\n\t\tvar velocity: Number = .5 * (gravity * Math.pow(time, 2));\n\t\tvar volume_: Number = ((4 \/ 3) * (Math.PI * Math.pow((particlesVector&#91;n].width \/ 2), 3)));\n\t\tvar mass: Number = density * volume_;\n\t\tvar weight: Number = gravity * mass;\n\t\tvar area: Number = Math.PI * Math.pow(particlesVector&#91;n].width \/ 2, 2);\n\t\tvar drag: Number = dragCoefficient * (.5 * (airDensity * Math.pow(velocity, 2))) * area;\n\t\tvar terminalVelocity: Number = (weight - drag) \/ mass;\n\t\tvar forceDrag: Number = dragCoefficient * (.5 * (airDensity * Math.pow(forceSpeed, 2))) * area;\n\t\tvar forceVelocity: Number = forceDrag \/ mass;\n\n\t\tif (terminalVelocity &gt;= 0) {\n\t\t\tvelocityVector&#91;n] = velocity;\n\t\t}\n\t\tparticlesVector&#91;n].y += velocityVector&#91;n];\n\t\tvar distance: Number = Math.sqrt(Math.pow(particlesVector&#91;n].x - forceField.x, 2) + Math.pow(particlesVector&#91;n].y - forceField.y, 2));\n\t\tvar pullStrength: Number = (forceField.width \/ 2 - distance) * forceStrength;\n\t\tvar forceAngle: Number = forceField.rotation * Math.PI \/ 180;\n\t\tif (distance &lt; forceField.width \/ 2) {\n\t\t\tparticlesVector&#91;n].y += forceVelocity * Math.sin(forceAngle) * -1 * pullStrength;\n\t\t\tparticlesVector&#91;n].x += forceVelocity * Math.cos(forceAngle) * -1 * pullStrength;\n\t\t}\n\t\tif (particlesVector&#91;n].x &gt; stage.stageWidth || particlesVector&#91;n].x &lt; 0 || particlesVector&#91;n].y &gt; stage.stageHeight) {\n\t\t\tframesVector&#91;n] = 0;\n\t\t\tparticlesVector&#91;n].x = Math.random() * stage.stageWidth;\n\t\t\tparticlesVector&#91;n].y = particlesVector&#91;n].height * -1;\n\t\t\tparticlesVector&#91;n].scaleX = Math.random() * (particleScaleMax - particleScaleMin) + particleScaleMin;\n\t\t\tparticlesVector&#91;n].scaleY = particlesVector&#91;n].scaleX;\n\t\t}\n\t\tdisplay.addChild(particlesVector&#91;n]);\n\t}\n\tif (timeCounter % 60 == 0) {\n\t\tvar clockInterval: Number = 360 \/ 60;\n\t\tforceField.rotation += clockInterval;\n\t}\n\tbitmapData.applyFilter(bitmapData, bitmapData.rect, origin, blur);\n\tbitmapData.colorTransform(bitmapData.rect, colorTransform);\n\tbitmapData.draw(display);\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":205,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,6,10],"tags":[],"class_list":["post-204","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html5-canvas","category-script-animations","category-script-drawing"],"_links":{"self":[{"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/posts\/204"}],"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=204"}],"version-history":[{"count":10,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/posts\/204\/revisions"}],"predecessor-version":[{"id":461,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/posts\/204\/revisions\/461"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/media\/205"}],"wp:attachment":[{"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/media?parent=204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/categories?post=204"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shacarah.com\/main\/wp-json\/wp\/v2\/tags?post=204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}