1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
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
})()
|