Water simulation with javascript. Today we continue JavaScript lessons, and our article will about using js in modeling of water effects. Sometimes we can create very interesting solutions using ordinary Javascript.
Here are sample and downloadable package:
Step 1. HTML
As usual, we start with the HTML.
This is our main page code with all samples.
index.html
1 | < link rel = "stylesheet" href = "css/main.css" type = "text/css" media = "all" /> |
2 | < script src = "js/main.js" type = "text/javascript" ></ script > |
4 | < img id = "unit" src = "unit.png" style = "visibility:hidden" > |
Step 2. CSS
Here are used CSS styles.
css/main.css
1 | body{ background : #eee ; font-family : Verdana , Helvetica , Arial , sans-serif ; margin : 0 ; padding : 0 } |
2 | .example{ position : relative ; background : #FFF ; width : 600px ; height : 600px ; border : 1px #000 solid ; margin : 20px auto ; padding : 20px ;-moz-border-radius: 3px ;-webkit-border-radius: 3px } |
3 | #main{ position : absolute ; width : 520px ; height : 520px ; background : #000 ; outline : #f0f solid 3px ; overflow : hidden ; cursor : pointer } |
4 | #fps{ position : absolute ; right : 20px ; top : 20px } |
Step 3. JS
Here are our main control JS file.
js/main.js
001 | var wp = function () { |
003 | var scr, grid, npart, diam, nx, ny, nw, nh, gw, gh; |
006 | var obj = new Array(npart); |
010 | var addEvent = function (o, e, f) { |
011 | if (window.addEventListener) o.addEventListener(e, f, false ); |
012 | else if (window.attachEvent) r = o.attachEvent( 'on' + e, f); |
015 | var resize = function () { |
016 | nw = scr.offsetWidth; |
017 | nh = scr.offsetHeight; |
019 | for (nx = 0, ny = 0; o != null ; o = o.offsetParent) { |
023 | gw = Math.round(nw / pdiam); |
024 | gh = Math.round(nh / pdiam); |
027 | var Particle = function (img) { |
028 | this .x = Math.random() * nw; |
029 | this .y = Math.random() * nh; |
034 | this .wi = img.width * .5; |
035 | this .hi = img.height * .5; |
037 | var d = document.createElement( 'img' ); |
038 | d.style.position = "absolute" ; |
039 | d.style.left = "-1000px" ; |
045 | Particle.prototype.move = function () { |
053 | this .plo.left = Math.round( this .x - this .wi) + 'px' ; |
054 | this .plo.top = Math.round( this .y - this .hi) + 'px' ; |
057 | Particle.prototype.physics = function () { |
060 | var dx = this .x - xm; |
061 | var dy = this .y - ym; |
062 | var d = Math.sqrt(dx * dx + dy * dy); |
073 | if ( this .x < pdiam * .5) this .dx += (pdiam * .5 - this .x); |
074 | else if ( this .x > nw - pdiam * .5) this .dx -= ( this .x - nw + pdiam * .5); |
075 | if ( this .y < pdiam * .5) this .dy += (pdiam * .5 - this .y); |
076 | else if ( this .y > nh - pdiam * .5) this .dy -= ( this .y - nh + pdiam * .5); |
078 | var gx = Math.round( this .x / pdiam); |
079 | var gy = Math.round( this .y / pdiam); |
081 | for ( var ix = gx - 1; ix <= gx + 1; ix++) { |
082 | for ( var iy = gy - 1; iy <= gy + 1; iy++) { |
083 | var g = grid[iy * gw + ix] || []; |
084 | for (j = 0, l = g.length; j < l; j++) { |
086 | var dx = that.x - this .x; |
087 | var dy = that.y - this .y; |
088 | var d = Math.sqrt(dx * dx + dy * dy); |
089 | if (d < pdiam && d > 0) { |
090 | dx = (dx / d) * (pdiam - d) * .25; |
091 | dy = (dy / d) * (pdiam - d) * .25; |
101 | if (!grid[gy * gw + gx]) grid[gy * gw + gx] = [ this ]; |
102 | else grid[gy * gw + gx].push( this ); |
105 | var run = function () { |
107 | grid = new Array(gw * gh); |
108 | for ( var i = 0; i < npart; i++) obj[i].physics(); |
109 | for ( var i = 0; i < npart; i++) obj[i].move(); |
114 | init : function (n, d) { |
115 | scr = document.getElementById( 'main' ); |
119 | addEvent(document, 'mousemove' , function (e) { |
120 | if (window.event) e = window.event; |
124 | addEvent(window, 'resize' , resize); |
125 | addEvent(document, 'mousedown' , function (e) { if (e.preventDefault) e.preventDefault(); down = true ; return false ;}); |
126 | addEvent(document, 'mouseup' , function () { down = false ; return false ;}); |
127 | document.onselectstart = function () { return false ; } |
128 | scr.ondrag = function () { return false ; } |
130 | setInterval( function () { |
131 | document.getElementById( 'fps' ).innerHTML = fps + ' FPS' ; |
136 | for ( var i = 0; i < npart; i++) obj[i] = new Particle(document.getElementById( 'unit' )); |
141 | window.onload = function () { |
This is most interesting and important part of our article. Here we creating our main object – scene, and adding particle to it. Also added several events (mainly for mouse). All this looks like low level coding, but don`t worry – this is mainly mathematics.
[sociallocker]
[/sociallocker]
Conclusion
Hope that you was happy to play with thas robo-water 🙂 If is you were wondering – do not forget to thank. I would be grateful for your interesting comments. Good luck!