var WaveGrid = (function(){ function WaveGrid (opt){ this.opt = defaults(opt, { stroke_width: 2, stroke: "#ffffff", fill: "#000000", wave_spacing: 20, wave_height: 6, wave_height_scale: 4, speed: 15, wave_stagger: 8, smooth_stagger: true, face: null, waves: true, }) if (! this.opt.face) { console.error("WaveGrid: please supply a SnapMX face object") } this.loaded = false } WaveGrid.prototype.load = function(data, w, h){ this.waves = [] this.data = data var dx = this.opt.wave_spacing var dy = this.opt.wave_height var top_padding = dy * this.opt.wave_height_scale + this.opt.stroke_width var wave var x, y this.w = w this.h = h this.opt.face.resize(w + dx*2, h + top_padding + dy*2) this.group = this.opt.face.snap.g() this.group.attr({ transform: "T" + (2.5*dx) + ","+ -top_padding/2 }) for (y = 0; y < h; y += dy) { wave = this.group.path().attr({ strokeWidth: this.opt.stroke_width, stroke: this.opt.stroke, fill: this.opt.fill, }) this.waves.push(wave) } this.loaded = true this.update(0) } WaveGrid.prototype.update = function(t){ if (! this.loaded) return t *= this.opt.speed / 1000 var wave_height_scale = this.opt.wave_height_scale var dx = this.opt.wave_spacing var dy = this.opt.wave_height var dt = t % dx var dtr = dt/dx var pixels = this.data.data var pw = this.data.width var ph = this.data.height var w = this.w var xmin = (dx-dt) - dx var xmax = w + (dx*2) var wave, path, x, xx, y, yy var at, bt, ay, by, zt, zy var pi, i, j = this.waves.length-1 var xstart = 0 var smooth_stagger = this.opt.smooth_stagger var stagger = this.opt.wave_stagger var stagger_dtr var use_waves = this.opt.waves for (y = 0; y < this.h; y += dy, j--) { pi = ((y/this.h) * ph)|0 wave = this.waves[j] path = "M" + (-dx) + "," + y if (smooth_stagger) { dt = (t/stagger + ((j % stagger)/stagger * dx)) % dx dtr = dt/dx xmin = (dx-dt) - dx } else { xstart = stagger == 1 ? 0 : ((j % stagger)/stagger) * dx } for (x = xstart; x <= xmax; x += dx) { xx = x + xmin jj = clamp( x / w, 0, 1 ) * (pw) jjj = clamp( (x+dx) / w, 0, 1 ) * (pw) if (jjj >= pw) { at = ((pi * pw) + pw-2)|0 } else { at = ((pi * pw) + jj)|0 } if (jjj >= pw) { bt = ((pi * pw) + pw - 1)|0 } else { bt = ((pi * pw) + jjj)|0 } ay = (pixels[at]/255 * dy) * (dtr) * wave_height_scale by = (pixels[bt]/255 * dy) * (1-dtr) * wave_height_scale yy = y + (ay + by) if (use_waves) { path += "C" path += (xx).toFixed(3) + "," + (y).toFixed(3) + " " path += (xx).toFixed(3) + "," + (yy + (ay+by)).toFixed(3) + " " path += (xx).toFixed(3) + "," + (yy).toFixed(3) + " " } else { path += "M" + (xx - 0.01).toFixed(3) + "," + (y).toFixed(3) path += "L" + (xx).toFixed(3) + "," + (yy).toFixed(3) path += "L" + (xx + 0.01).toFixed(3) + "," + (y).toFixed(3) } } wave.attr({ d: path }) } } return WaveGrid })()