Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
michael@0 | 1 | <!DOCTYPE html> |
michael@0 | 2 | <html> |
michael@0 | 3 | <head> |
michael@0 | 4 | <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
michael@0 | 5 | <script type="text/javascript"> |
michael@0 | 6 | |
michael@0 | 7 | var ripples = { |
michael@0 | 8 | frame: 0, |
michael@0 | 9 | |
michael@0 | 10 | get frames() { |
michael@0 | 11 | return this.frame; |
michael@0 | 12 | }, |
michael@0 | 13 | |
michael@0 | 14 | // Size of buffer. |
michael@0 | 15 | width: 80, |
michael@0 | 16 | height: 80, |
michael@0 | 17 | |
michael@0 | 18 | // Render size. |
michael@0 | 19 | renderWidth: 1200, |
michael@0 | 20 | renderHeight: 700, |
michael@0 | 21 | |
michael@0 | 22 | // Canvas size. |
michael@0 | 23 | canvasWidth: 1200, |
michael@0 | 24 | canvasHeight: 700, |
michael@0 | 25 | |
michael@0 | 26 | // Ripple start points. |
michael@0 | 27 | ripplePoints: [ |
michael@0 | 28 | {x:0.5,y:0.5,start:0}, |
michael@0 | 29 | {x:0.2,y:0.3,start:0}, |
michael@0 | 30 | {x:0.7,y:0.6,start:0}, |
michael@0 | 31 | {x:0.2,y:0.2,start:4000}, |
michael@0 | 32 | {x:0.7,y:0.2,start:6000}, |
michael@0 | 33 | {x:0.2,y:0.8,start:8000}, |
michael@0 | 34 | {x:0.5,y:0.3,start:12000}, |
michael@0 | 35 | {x:0.2,y:0.6,start:16000}, |
michael@0 | 36 | {x:0.8,y:0.2,start:20000}, |
michael@0 | 37 | {x:0.3,y:0.8,start:24000}, |
michael@0 | 38 | {x:0.6,y:0.2,start:28000} |
michael@0 | 39 | ], |
michael@0 | 40 | |
michael@0 | 41 | a: false, // previous frame |
michael@0 | 42 | b: false, // frame before previous frame |
michael@0 | 43 | |
michael@0 | 44 | pixelWidth: 0, |
michael@0 | 45 | pixelHeight: 0, |
michael@0 | 46 | |
michael@0 | 47 | init: function() { |
michael@0 | 48 | // Get start time. |
michael@0 | 49 | var d = new Date(); |
michael@0 | 50 | this.startTime = d.getTime(); |
michael@0 | 51 | |
michael@0 | 52 | // Pixel sizes. |
michael@0 | 53 | this.pixelWidth = Math.floor(this.renderWidth / this.width); |
michael@0 | 54 | this.pixelHeight = Math.floor(this.renderHeight / this.height); |
michael@0 | 55 | |
michael@0 | 56 | // Top left corner position of the rendered effect. |
michael@0 | 57 | this.xPosition = this.canvasWidth / 2 - (this.pixelWidth * this.width) / 2; |
michael@0 | 58 | this.yPosition = this.canvasHeight / 2 - (this.pixelHeight * this.height) / 2; |
michael@0 | 59 | |
michael@0 | 60 | |
michael@0 | 61 | // Init canvas. |
michael@0 | 62 | var canvas = document.getElementById('ripples'); |
michael@0 | 63 | this.ctx = canvas.getContext('2d'); |
michael@0 | 64 | |
michael@0 | 65 | // Create buffers. |
michael@0 | 66 | this.a = new Buffer(this.width, this.height); |
michael@0 | 67 | this.b = new Buffer(this.width, this.height); |
michael@0 | 68 | |
michael@0 | 69 | }, |
michael@0 | 70 | |
michael@0 | 71 | processBuffers: function() { |
michael@0 | 72 | var damping = 0.02; |
michael@0 | 73 | for (var x = 2; x < this.width - 2; x++) { |
michael@0 | 74 | for (var y = 2; y < this.height - 2; y++) { |
michael@0 | 75 | this.b.set(x, y, |
michael@0 | 76 | ( |
michael@0 | 77 | this.a.get(x - 2, y) |
michael@0 | 78 | + this.a.get(x + 2, y) |
michael@0 | 79 | + this.a.get(x, y - 2) |
michael@0 | 80 | + this.a.get(x, y + 2) |
michael@0 | 81 | + this.a.get(x - 1, y) |
michael@0 | 82 | + this.a.get(x + 1, y) |
michael@0 | 83 | + this.a.get(x, y - 1) |
michael@0 | 84 | + this.a.get(x, y + 1) |
michael@0 | 85 | + this.a.get(x - 1, y - 1) |
michael@0 | 86 | + this.a.get(x + 1, y + 1) |
michael@0 | 87 | + this.a.get(x + 1, y - 1) |
michael@0 | 88 | + this.a.get(x - 1, y + 1) |
michael@0 | 89 | ) / 12 * 2 - this.b.get(x, y)); |
michael@0 | 90 | this.b.set(x, y, this.b.get(x, y) - this.b.get(x, y) * damping); |
michael@0 | 91 | } |
michael@0 | 92 | } |
michael@0 | 93 | }, |
michael@0 | 94 | |
michael@0 | 95 | render: function() { |
michael@0 | 96 | |
michael@0 | 97 | for (var x = 2; x < this.width - 2; x++) { |
michael@0 | 98 | for (var y = 2; y < this.height - 2; y++) { |
michael@0 | 99 | |
michael@0 | 100 | var color = this.b.get(x, y); |
michael@0 | 101 | |
michael@0 | 102 | var progress = color / 256; |
michael@0 | 103 | var rMin = 0, rMax = 255, |
michael@0 | 104 | gMin = 0, gMax = 255, |
michael@0 | 105 | bMin = 0, bMax = 255; |
michael@0 | 106 | |
michael@0 | 107 | var rDelta = (rMax - rMin) / 2; |
michael@0 | 108 | var rValue = Math.round(rMin + rDelta + rDelta * progress); |
michael@0 | 109 | var gDelta = (gMax - gMin) / 2; |
michael@0 | 110 | var gValue = Math.round(gMin + gDelta + gDelta * progress); |
michael@0 | 111 | var bDelta = (bMax - bMin) / 2; |
michael@0 | 112 | var bValue = Math.round(bMin + bDelta + bDelta * progress); |
michael@0 | 113 | this.ctx.fillStyle = "rgb("+rValue+", "+gValue+", "+bValue+")"; |
michael@0 | 114 | this.ctx.fillRect(this.xPosition + x * this.pixelWidth, |
michael@0 | 115 | this.yPosition + y * this.pixelHeight, |
michael@0 | 116 | this.pixelWidth, |
michael@0 | 117 | this.pixelHeight); |
michael@0 | 118 | } |
michael@0 | 119 | } |
michael@0 | 120 | }, |
michael@0 | 121 | |
michael@0 | 122 | swapBuffers: function() { |
michael@0 | 123 | var c = this.b; |
michael@0 | 124 | this.b = this.a; |
michael@0 | 125 | this.a = c; |
michael@0 | 126 | }, |
michael@0 | 127 | |
michael@0 | 128 | clear: function() { |
michael@0 | 129 | this.ctx.clearRect(0, 0, this.width, this.height); |
michael@0 | 130 | }, |
michael@0 | 131 | |
michael@0 | 132 | addRipple: function(time) { |
michael@0 | 133 | |
michael@0 | 134 | var ripplePoints = new Array(); |
michael@0 | 135 | for (var i = 0; i < this.ripplePoints.length; i++) { |
michael@0 | 136 | if (this.ripplePoints[i].start < time) { |
michael@0 | 137 | this.a.sphere( |
michael@0 | 138 | Math.floor(this.width * this.ripplePoints[i].x), |
michael@0 | 139 | Math.floor(this.height * this.ripplePoints[i].y), |
michael@0 | 140 | Math.floor(this.width * 0.1), 256); |
michael@0 | 141 | } else { |
michael@0 | 142 | ripplePoints.push(this.ripplePoints[i]); |
michael@0 | 143 | } |
michael@0 | 144 | } |
michael@0 | 145 | this.ripplePoints = ripplePoints; |
michael@0 | 146 | |
michael@0 | 147 | }, |
michael@0 | 148 | |
michael@0 | 149 | run: function(time) { |
michael@0 | 150 | this.clear(); |
michael@0 | 151 | this.addRipple(time); |
michael@0 | 152 | this.processBuffers(); |
michael@0 | 153 | this.render(); |
michael@0 | 154 | this.swapBuffers(); |
michael@0 | 155 | this.frame++; |
michael@0 | 156 | } |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | function Buffer(newWidth, newHeight) { |
michael@0 | 160 | this.width = newWidth; |
michael@0 | 161 | this.height = newHeight; |
michael@0 | 162 | this.data = new Array(); |
michael@0 | 163 | |
michael@0 | 164 | for (var x = 0; x < this.width; x++) { |
michael@0 | 165 | this.data[x] = new Array(); |
michael@0 | 166 | for (var y = 0; y < this.height; y++) { |
michael@0 | 167 | this.data[x][y] = 0; |
michael@0 | 168 | } |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | this.sphere = function(sphereX, sphereY, radius, depth) { |
michael@0 | 172 | for (var x = 0; x < this.width; x++) { |
michael@0 | 173 | for (var y = 0; y < this.height; y++) { |
michael@0 | 174 | var d = this.distance(sphereX, sphereY, x, y); |
michael@0 | 175 | if (d < radius) { |
michael@0 | 176 | this.data[x][y] = this.data[x][y] + depth * ((radius - Math.sqrt(d)) / radius); |
michael@0 | 177 | //this.data[x][y] = this.data[x][y] + Math.round((1 - d / radius) * 256); |
michael@0 | 178 | if (this.data[x][y] > 256) this.data[x][y] = 256; |
michael@0 | 179 | } |
michael@0 | 180 | } |
michael@0 | 181 | } |
michael@0 | 182 | } |
michael@0 | 183 | |
michael@0 | 184 | this.ripple = function(sphereX, sphereY, radius) { |
michael@0 | 185 | for (var x = 0; x < this.width; x++) { |
michael@0 | 186 | for (var y = 0; y < this.height; y++) { |
michael@0 | 187 | var d = this.distance(sphereX, sphereY, x, y); |
michael@0 | 188 | if (d < radius) { |
michael@0 | 189 | this.set(x, y, Math.sin((d / radius) * Math.PI) * 70);//Math.round((1 - d / radius) * 256); |
michael@0 | 190 | } |
michael@0 | 191 | } |
michael@0 | 192 | } |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | this.hardRipple = function(sphereX, sphereY, radius) { |
michael@0 | 196 | for (var x = 0; x < this.width; x++) { |
michael@0 | 197 | for (var y = 0; y < this.height; y++) { |
michael@0 | 198 | var d = this.distance(sphereX, sphereY, x, y); |
michael@0 | 199 | if (d < radius && d > radius * 0.8) { |
michael@0 | 200 | this.set(x, y, 256);//Math.round((1 - d / radius) * 256); |
michael@0 | 201 | } |
michael@0 | 202 | } |
michael@0 | 203 | } |
michael@0 | 204 | } |
michael@0 | 205 | |
michael@0 | 206 | this.distance = function(x1, y1, x2, y2) { |
michael@0 | 207 | return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); |
michael@0 | 208 | } |
michael@0 | 209 | |
michael@0 | 210 | this.get = function(x, y) { |
michael@0 | 211 | if (typeof(this.data[x]) != "undefined" && typeof(this.data[x][y]) != "undefined") { |
michael@0 | 212 | return this.data[x][y]; |
michael@0 | 213 | } else { |
michael@0 | 214 | return 0; |
michael@0 | 215 | } |
michael@0 | 216 | } |
michael@0 | 217 | |
michael@0 | 218 | this.set = function(x, y, value) { |
michael@0 | 219 | if (typeof(this.data[x]) != "undefined" && typeof(this.data[x][y]) != "undefined") { |
michael@0 | 220 | this.data[x][y] = Math.round(value); |
michael@0 | 221 | } |
michael@0 | 222 | } |
michael@0 | 223 | } |
michael@0 | 224 | |
michael@0 | 225 | function run() { |
michael@0 | 226 | ripples.init(); |
michael@0 | 227 | var now = new Date(); |
michael@0 | 228 | var start = window.mozAnimationStartTime; |
michael@0 | 229 | function step(timestamp) { |
michael@0 | 230 | progress = timestamp - start; |
michael@0 | 231 | ripples.run(progress); |
michael@0 | 232 | var time = new Date(); |
michael@0 | 233 | var diff = time.getTime() - now.getTime(); |
michael@0 | 234 | if (diff < 5000) { // five seconds |
michael@0 | 235 | window.mozRequestAnimationFrame(step); |
michael@0 | 236 | } else { |
michael@0 | 237 | var evt = document.createEvent("CustomEvent"); |
michael@0 | 238 | evt.initCustomEvent("test", true, false, { testName: "ripples", frames: ripples.frames, msec: diff }); |
michael@0 | 239 | window.dispatchEvent(evt); |
michael@0 | 240 | } |
michael@0 | 241 | } |
michael@0 | 242 | window.mozRequestAnimationFrame(step); |
michael@0 | 243 | } |
michael@0 | 244 | |
michael@0 | 245 | </script> |
michael@0 | 246 | <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
michael@0 | 247 | <style> |
michael@0 | 248 | </style> |
michael@0 | 249 | <meta charset="utf-8"> |
michael@0 | 250 | </head> |
michael@0 | 251 | <body onload="setTimeout(run, 1000);"> |
michael@0 | 252 | <div id="anchor"><canvas id="ripples" width="1200" height="700"></canvas></div> |
michael@0 | 253 | </body> |
michael@0 | 254 | </html> |