• aqualibrium
  • We were much closer than you thought -- not drowning but waving.
  • Sources

  • Main html file: dhtml/water-particles-canvas.html
    ge1doot mini library: /library/ge1doot.js
  • CSS

  • 
    html {
    	overflow: hidden;
    	-ms-touch-action: none;
    	-ms-content-zooming: none;
    }
    body {
    	position: absolute;
    	margin: 0;
    	padding: 0;
    	background: #222;
    	width: 100%;
    	height: 100%;
    }
    #screen {
    	position: absolute;
    	width: 100%;
    	height: 100%;
    	background: #000;
    	cursor: pointer;
    }
    .search {
    	background:#0065CB !important;
    }
    
  • HTML

  • 
    <canvas id="screen"></canvas>
    
  • JS

  • 
    /* 
     * ==================================================================
     * SVG experiment
     * http://www.dhteumeuleu.com/water
     * Author Gerard Ferrandez - September 2009
     * ---------------------------------------------------
     * Released under the MIT license
     * http://www.dhteumeuleu.com/LICENSE.html
     * adapted from Grant Kot's work at http://kotsoft.googlepages.com/
     * ==================================================================
     */
    
    "use strict";
    
    (function () {
    	var scr, ctx, pointer, grid, npart, ipart, pdiam, gw, gh, ax = 0, ay = 0;
    	var obj = [];
    	/* ==== particle constructor ==== */
    	var Particle = function () {
    		this.x = Math.random() * scr.width;
    		this.y = Math.random() * scr.height;
    		this.vx = 0;
    		this.vy = 0;
    		this.dx = 0;
    		this.dy = 0;
    		this.w = pdiam * .5;
    	}
    	/* ==== move particle ==== */
    	Particle.prototype.move = function () {
    		this.x  += this.dx;
    		this.y  += this.dy;
    		this.vx += this.dx;
    		this.vy += this.dy;
    		this.dx  = 0;
    		this.dy  = 0;
    		/* ---- draw particle ---- */
    		ctx.drawImage(ipart, this.x - this.w, this.y - this.w, this.w * 2, this.w * 2);
    	}
    	/* ==== fluid simulation ==== */
    	Particle.prototype.physics = function () {
    		/* ---- mouse ---- */
    		if (pointer.isDown) {
    			var dx = this.x - pointer.X;
    			var dy = this.y - pointer.Y;
    			var d = Math.sqrt(dx * dx + dy * dy);
    			if (d < Math.min(scr.width, scr.height) / 2) {
    				this.dx += dx / d * 0.5;
    				this.dy += dy / d * 0.5;
    			}
    		}
    		/* ---- gravity and acceleration ---- */
    		this.vx += ax;
    		this.vy += ay;
    		//this.vy += .1;
    		this.x += this.vx;
    		this.y += this.vy;
    		/* ---- screens limits ---- */
    		if (this.x < pdiam * .5) this.dx += (pdiam * .5 - this.x);
    		else if (this.x > scr.width - pdiam * .5) this.dx -= (this.x - scr.width + pdiam * .5);
    		if (this.y < pdiam * .5) this.dy += (pdiam * .5 - this.y);
    		else if (this.y > scr.height - pdiam * .5) this.dy -= (this.y - scr.height + pdiam * .5);
    		/* ---- grid coordinates ---- */
    		var gx = Math.round(this.x / (pdiam * 4));
    		var gy = Math.round(this.y / (pdiam * 4));
    		/* ---- neightbors constraints ---- */
    		for (var ix = gx - 1; ix <= gx + 1; ix++) {  
    			for (var iy = gy - 1; iy <= gy + 1; iy++) {
    				var g = grid[iy * gw + ix] || [];
    				for (var j = 0, l = g.length; j < l; j++) {
    					var that = g[j];
    					var dx = that.x - this.x;
    					var dy = that.y - this.y;
    					var d = Math.sqrt(dx * dx + dy * dy);
    					if (d < pdiam) {
    						dx = (dx / d) * (pdiam - d) * .25;
    						dy = (dy / d) * (pdiam - d) * .25;
    						this.dx -= dx;
    						this.dy -= dy;
    						that.dx += dx;
    						that.dy += dy;
    					}
    				}
    			}
    		}
    		/* ---- update neighbors list ---- */
    		if (!grid[gy * gw + gx]) grid[gy * gw + gx] = [this];
    		else grid[gy * gw + gx].push(this);
    	}
    	/* ==== main loop ==== */
    	var run = function () {
    		// ---- clear screen ----
    		ctx.clearRect(0, 0, scr.width, scr.height);
    		grid = new Array(gw * gh);
    		for(var i = 0; i < npart; i++) obj[i].physics();
    		for(var i = 0; i < npart; i++) obj[i].move();
    		// ---- next frame ----
    		requestAnimFrame(run);
    	}
    	/* ==== init script ==== */
    	var init = function (p) {
    		pdiam = p.particleSize;
    		// ---- canvas ----
    		scr = new ge1doot.Screen({
    			container: "screen",
    			resize: function () {
    				gw = Math.round(scr.width  / (pdiam * 4));
    				gh = Math.round(scr.height / (pdiam * 4));
    			}
    		});
    		ctx = scr.ctx;
    		scr.resize();
    		// ---- pointer ----
    		pointer = new ge1doot.Pointer({});
    		// ---- particle image ----
    		ipart = new Image();
    		ipart.src = p.particleImg;
    		// ---- create particles ----
    		npart = Math.round(((scr.width * scr.height) / (pdiam * pdiam)) * 0.6);
    		for (var i = 0; i < npart; i++) {
    			obj[i] = new Particle();
    		}
    		// ---- more fun on iPad :-) ----
    		if (window.DeviceMotionEvent != undefined) {
    			window.ondevicemotion = function(e) {
    				ax = e.accelerationIncludingGravity.x * 0.1;
    				ay = -e.accelerationIncludingGravity.y * 0.1;
    				if (ax > 0.1) ax = 0.1; else if (ax < -0.1) ax = -0.1;
    				if (ay > 0.1) ay = 0.1; else if (ay < -0.1) ay = -0.1;
    				if (window.innerWidth / window.innerHeight > 1) {
    					var t = ay;
    					ay = ax;
    					ax = -t;
    				}
    			}
    		} else ay = 0.1;
    		run();
    	}
    	return {
    		// ---- launch script -----
    		load : function (p) {
    			window.addEventListener('load', function () {
    				init(p);
    			}, false);
    		}  
    	}
    })().load({
    	particleImg: "../images/sp32r.gif",
    	particleSize: 32
    });
    
    © www.dhteumeuleu.com 2004-2015