Riplz.html(檔案已創建)
| @@ -0,0 +1,70 @@ | |||
| 1 | + | <!doctype html> | |
| 2 | + | <html> | |
| 3 | + | <head> | |
| 4 | + | <meta charset="UTF-8" /> | |
| 5 | + | <style> | |
| 6 | + | body, html { | |
| 7 | + | height: 100%; | |
| 8 | + | } | |
| 9 | + | ||
| 10 | + | body { | |
| 11 | + | display: flex; | |
| 12 | + | justify-content: center; | |
| 13 | + | align-items: center; | |
| 14 | + | background-color: black; | |
| 15 | + | } | |
| 16 | + | </style> | |
| 17 | + | <title>Riplz</title> | |
| 18 | + | </head> | |
| 19 | + | <body> | |
| 20 | + | <canvas id="canvas" width="1024" height="1024"></canvas> | |
| 21 | + | ||
| 22 | + | <script> | |
| 23 | + | const canvas = document.getElementById('canvas'); | |
| 24 | + | const ctx = canvas.getContext('2d'); | |
| 25 | + | const startTime = performance.now(); | |
| 26 | + | ||
| 27 | + | (function drawRipple(timestamp) { | |
| 28 | + | const elapsedTimeUnits = (timestamp - startTime) / 50; | |
| 29 | + | const pixelData = ctx.createImageData(canvas.width, canvas.height); | |
| 30 | + | ||
| 31 | + | // Step through the array one pixel at a time | |
| 32 | + | for (let i = 0; i < pixelData.data.length; i += 4) { | |
| 33 | + | ||
| 34 | + | // We can find our (x, y) position on the canvas by comparing | |
| 35 | + | // our position in the array with the width of the canvas. | |
| 36 | + | let x = Math.floor(i / 4) % canvas.width; | |
| 37 | + | let y = Math.floor(i / (4 * canvas.width)); | |
| 38 | + | ||
| 39 | + | // We need our origin to be in the center, so lets convert the (x, y) | |
| 40 | + | // from above (the "canvas coordinates") to their "reindexed" values | |
| 41 | + | // (what they would become if the origin were in the center). | |
| 42 | + | let reIndexedX = -((canvas.width - x) - (canvas.width / 2)); | |
| 43 | + | let reIndexedY = (canvas.height - y) - (canvas.height / 2); | |
| 44 | + | ||
| 45 | + | // Instead of writing our own code for Pythagorean's theorem, we can | |
| 46 | + | // use JavaScript's built-in method to calculate the hypotenuse. | |
| 47 | + | let radialX = Math.hypot(reIndexedX, reIndexedY); | |
| 48 | + | ||
| 49 | + | // For reference, see https://www.desmos.com/calculator/bp9t79pfa0 | |
| 50 | + | let waveHeight = Math.sin((radialX - elapsedTimeUnits) / 8); | |
| 51 | + | ||
| 52 | + | // Normally, a sin wave fluctuates between -1 and 1, but we want ours | |
| 53 | + | // to fluctuate between 0 and 255 instead (the range for RGB values). | |
| 54 | + | let adjustedHeight = (waveHeight * 60 + (255/2)); | |
| 55 | + | ||
| 56 | + | // Assign the adjustedHeight to R, G, and B equally, to make gray. | |
| 57 | + | pixelData.data[i] = adjustedHeight; // red | |
| 58 | + | pixelData.data[i + 1] = adjustedHeight; // green | |
| 59 | + | pixelData.data[i + 2] = adjustedHeight; // blue | |
| 60 | + | pixelData.data[i + 3] = 255; // opacity | |
| 61 | + | } | |
| 62 | + | ||
| 63 | + | ctx.putImageData(pixelData, 0, 0); | |
| 64 | + | ||
| 65 | + | requestAnimationFrame(drawRipple); | |
| 66 | + | })(startTime); | |
| 67 | + | </script | |
| 68 | + | </body> | |
| 69 | + | </html> | |
| 70 | + | ||
上一頁
下一頁