javascript - Canvas Marching Squares Glitch / Scroll Integration -


i'm attempting teach myself how work canvas — , i'm in way on head — thought i'd ask if has solution issue came across.

as lesson decided try start metaball idea: http://codepen.io/ge1doot/pen/rndwqb

and rework metaballs stationary move upwards @ varying rates 1 scrolls down page.

i sort of got working here — displays better on fiddle below. https://jsfiddle.net/l7cr46px/2/

function getscrolloffsets() {      var doc = document, w = window;      var x, y, docel;            if ( typeof w.pageyoffset === 'number' ) {          x = w.pagexoffset;          y = w.pageyoffset;      } else {          docel = (doc.compatmode && doc.compatmode === 'css1compat')?                  doc.documentelement: doc.body;          x = docel.scrollleft;          y = docel.scrolltop;      }      return {x:x, y:y};  }    var lava, balldata;  balldata = new array();    (function() {  	var metablobby = metablobby || {  		screen: {  			elem:     null,  			callback: null,  			ctx:      null,  			width:    0,  			height:   0,  			left:     0,  			top:      0,  			init: function (id, callback, initres) {  				this.elem = document.getelementbyid(id);  				this.callback = callback || null;  				if (this.elem.tagname == "canvas") this.ctx = this.elem.getcontext("2d");  				window.addeventlistener('resize', function () {  					this.resize();  				}.bind(this), false);  				this.elem.onselectstart = function () { return false; }  				this.elem.ondrag        = function () { return false; }  				initres && this.resize();  				return this;  			},  			resize: function () {  				var o = this.elem;  				this.width  = o.offsetwidth;  				this.height = o.offsetheight;  				for (this.left = 0, this.top = 0; o != null; o = o.offsetparent) {  					this.left += o.offsetleft;  					this.top  += o.offsettop;  				}  				if (this.ctx) {  					this.elem.width  = this.width;  					this.elem.height = this.height;  				}  				this.callback && this.callback();  			},  			pointer: {  				screen:   null,  				elem:     null,  				callback: null,  				pos:   {x:0, y:0},  				mov:   {x:0, y:0},  				drag:  {x:0, y:0},  				start: {x:0, y:0},  				end:   {x:0, y:0},  				active: false,  				touch: false,  				move: function (e, touch) {  					//this.active = true;  					this.touch = touch;  					e.preventdefault();  					var pointer = touch ? e.touches[0] : e;  					this.mov.x = pointer.clientx - this.screen.left;  					this.mov.y = pointer.clienty - this.screen.top;  					if (this.active) {  						this.pos.x = this.mov.x;  						this.pos.y = this.mov.y;  						this.drag.x = this.end.x - (this.pos.x - this.start.x);  						this.drag.y = this.end.y - (this.pos.y - this.start.y);  						this.callback.move && this.callback.move();  					}  				},  				scroll: function(e, touch){  					run();	  				},  				init: function (callback) {  					this.screen = metablobby.screen;  					this.elem = this.screen.elem;  					this.callback = callback || {};  					if ('ontouchstart' in window) {  						// touch  						this.elem.ontouchstart  = function (e) { this.down(e, true); }.bind(this);  						this.elem.ontouchmove   = function (e) { this.move(e, true); }.bind(this);  						this.elem.ontouchend    = function (e) { this.up(e, true);   }.bind(this);  						this.elem.ontouchcancel = function (e) { this.up(e, true);   }.bind(this);  					}  					document.addeventlistener("mousemove", function (e) { this.move(e, false); }.bind(this), true);  					document.addeventlistener("scroll", function (e) { this.scroll(e, false); }.bind(this), true);  	  					return this;  				}  			},  		}  	}  	  	// ==== point constructor ====  	var point = function(x, y) {  		this.x = x;  		this.y = y;  		this.magnitude = x * x + y * y;  		this.computed = 0;  		this.force = 0;  	}  	point.prototype.add = function(p) {  		return new point(this.x + p.x, this.y + p.y);  	}  	// ==== ball constructor ====  		var ball = function(parent,i) {  			var x = math.floor(math.random() * window.innerwidth) + 1;  			var y = math.floor(math.random() * (window.innerheight)*5) + 1;  			var radius = (math.floor(math.random() * 65) + 15)  			var drift = math.random();  			  			balldata[i]=[x,y,radius, drift];  			  			this.vel = new point(0,0);  			this.pos = new point(x,y);  			this.size = radius;  			this.width = parent.width;  			this.height = parent.height;  		}  	// ==== move balls ====  		ball.prototype.move = function(i) {  			// ---- interact pointer ----  			if (pointer.active) {  					var dx = pointer.pos.x - this.pos.x;  					var dy = pointer.pos.y - this.pos.y;  					var = math.atan2(dy, dx);  					var v = -math.min(  							10,  							500 / math.sqrt(dx * dx + dy * dy)  					);  					this.pos = this.pos.add(  							new point(  									math.cos(a) * v,  									math.sin(a) * v  							)  					);  			}  			  			var drift = balldata[i-1][3];  			var pageoffset = getscrolloffsets().y;  			this.pos.y = balldata[i-1][1] - (pageoffset*drift);  			this.vel.y = 0 - (pageoffset*drift);  			this.pos = this.pos.add(this.vel);  	  		}  		  	// ==== lavalamp constructor ====  		var lavalamp = function(width, height, numballs) {  			this.step = 4;  			this.width = width;  			this.height = height;  			this.wh = math.min(width, height);  			this.sx = math.floor(this.width / this.step);  			this.sy = math.floor(this.height / this.step);  			this.paint = false;  			this.metafill = '#000000';  			this.plx = [0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0];  			this.ply = [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1];  			this.mscases = [0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 0, 2, 1, 1, 0];  			this.ix = [1, 0, -1, 0, 0, 1, 0, -1, -1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1];  			this.grid = [];  			this.balls = [];  			this.iter = 0;  			this.sign = 1;  			// ---- init grid ----  				for (var = 0; < (this.sx + 2) * (this.sy + 2); i++) {  					this.grid[i] = new point(  						(i % (this.sx + 2)) * this.step, (math.floor(i / (this.sx + 2))) * this.step  					)  				}  			// ---- create metaballs ----  				for (var = 0; < 50; i++) {  					this.balls[i] = new ball(this,i);  				}  		}  	// ==== compute cell force ====  		lavalamp.prototype.computeforce = function(x, y, idx) {  			var force;  			var id = idx || x + y * (this.sx + 2);  			if (x === 0 || y === 0 || x === this.sx || y === this.sy) {  					var force = 0.6 * this.sign;  			} else {  					var cell = this.grid[id];  					var force = 0;  					var = 0,  							ball;  					while (ball = this.balls[i++]) {  							force += ball.size * ball.size / (-2 * cell.x * ball.pos.x - 2 * cell.y * ball.pos.y + ball.pos.magnitude + cell.magnitude);  					}  					force *= this.sign  			}  			this.grid[id].force = force;  			return force;  		}  	// ---- compute cell ----  		lavalamp.prototype.marchingsquares = function(next) {  			var x = next[0];  			var y = next[1];  			var pdir = next[2];  			var id = x + y * (this.sx + 2);  			if(typeof this.grid[id] !== "undefined"){  				if (this.grid[id].computed === this.iter) return false;  				var dir, mscase = 0;  				// ---- neighbors force ----  				for (var = 0; < 4; i++) {  						var idn = (x + this.ix[i + 12]) + (y + this.ix[i + 16]) * (this.sx + 2);  						var force = this.grid[idn].force;  						if ((force > 0 && this.sign < 0) || (force < 0 && this.sign > 0) || !force) {  								// ---- compute force if not in buffer ----  								force = this.computeforce(  										x + this.ix[i + 12],  										y + this.ix[i + 16],  										idn  								);  						}  						if (math.abs(force) > 1) mscase += math.pow(2, i);  				}  				if (mscase === 15) {  					// --- inside ---  					return [x, y - 1, false];  				} else {  					// ---- ambiguous cases ----  					if (mscase === 5) dir = (pdir === 2) ? 3 : 1;  					else if (mscase === 10) dir = (pdir === 3) ? 0 : 2;  					else {  						// ---- lookup ----  						dir = this.mscases[mscase];  						this.grid[id].computed = this.iter;  					}  					// ---- draw line ----  					var ix = this.step / (  						math.abs(math.abs(this.grid[(x + this.plx[4 * dir + 2]) + (y + this.ply[4 * dir + 2]) * (this.sx + 2)].force) - 1) /  						math.abs(math.abs(this.grid[(x + this.plx[4 * dir + 3]) + (y + this.ply[4 * dir + 3]) * (this.sx + 2)].force) - 1) + 1  					);  					ctx.lineto(  							this.grid[(x + this.plx[4 * dir + 0]) + (y + this.ply[4 * dir + 0]) * (this.sx + 2)].x + this.ix[dir] * ix,  							this.grid[(x + this.plx[4 * dir + 1]) + (y + this.ply[4 * dir + 1]) * (this.sx + 2)].y + this.ix[dir + 4] * ix  					);  					this.paint = true;  					// ---- next ----  					return [  						x + this.ix[dir + 4],  						y + this.ix[dir + 8],  						dir  					];  				}  			}  		}  		lavalamp.prototype.rendermetaballs = function() {  			var = 0, ball;  			while (ball = this.balls[i++]) ball.move(i);    			// ---- reset grid ----  			this.iter++;  			this.sign = -this.sign;  			this.paint = false;  			ctx.fillstyle = '#ff0000';  			ctx.beginpath();  			// ---- compute metaballs ----  			i = 0;  			while (ball = this.balls[i++]) {  				// ---- first cell ----  				var next = [  						math.round(ball.pos.x / this.step),  						math.round(ball.pos.y / this.step), false  				];  				// ---- marching squares ----  				do {  						next = this.marchingsquares(next);  				} while (next);  				// ---- fill , close path ----  				if (this.paint) {  					ctx.fill();  					ctx.closepath();  					ctx.beginpath();  					this.paint = false;  				}  			}  		}  	  	// ==== main loop ====  		var run = function() {  			//requestanimationframe(run);  			ctx.clearrect(0, 0, screen.width, screen.height);  			lava.rendermetaballs();  		}  	// ---- canvas ----  		var screen = metablobby.screen.init("thedots", null, true),  		ctx = screen.ctx,  		pointer = screen.pointer.init();  		screen.resize();  	// ---- create lavalamps ----  		lava = new lavalamp(screen.width, screen.height, 10);  	// ---- start engine ----  		run();    })();
html,body {  	height: 100%;  	width: 100%;  	background-color: white;  }  body {  	height: 500vh;  }  #thedots {  	position: fixed;  	top: 0;  	left: 0;  	width: 100vw;  	height: 100vh;  	z-index: 100;  	pointer-events: none;  }
<canvas id="thedots" width="1203" height="363"></canvas>	

but i'm getting insane rendering bugs you'll see. or maybe they're not rendering bugs , faulty code. appreciated.

thanks!


Comments

Popular posts from this blog

facebook - android ACTION_SEND to share with specific application only -

python - Creating a new virtualenv gives a permissions error -

javascript - cocos2d-js draw circle not instantly -