1const canvas = document.getElementById("livestream_of_a_mountain_rebuilding_itself_canvas");
2const ctx = canvas.getContext("2d", { willReadFrequently: true });
3const initial_time = new Date();
4
5ctx.canvas.width = window.innerWidth * 0.28;
6ctx.canvas.height = window.innerHeight * 0.28;
7
8var offset_magnitude = -0.4;
9var framesSinceTap = 0;
10var framesTapLasts = 4;
11var x_tap_position = Math.floor(ctx.canvas.width / 2.0);
12var y_tap_position = Math.floor(ctx.canvas.height / 2.0);
13
14function getCursorPosition(canvas, e) {
15    const rect = canvas.getBoundingClientRect();
16    const x = event.clientX - rect.left;
17    const y = event.clientY - rect.top;
18    x_tap_position = Math.floor((x / rect.right) * ctx.canvas.width);
19    y_tap_position = Math.floor((y / rect.bottom) * ctx.canvas.height);
20}
21
22canvas.addEventListener('mousemove', function(e) {
23    framesSinceTap = 0;
24    getCursorPosition(canvas, e);
25})
26
27function startDrawing() {
28
29    var date = Date.now();
30    date = date / 2000.0;
31    
32    var frame = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
33    var frame_original = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
34    var edge_fade_distance = (6 * (Math.sin((Date.now() / 6400)) + 1)) + 8;
35
36    function setPixel(x, y, red, green, blue, alpha) {
37        var index_position = (x + (y * ctx.canvas.width)) * 4;
38        frame.data[index_position] = red;
39        frame.data[index_position + 1] = green;
40        frame.data[index_position + 2] = blue;
41        frame.data[index_position + 3] = alpha;
42    }
43
44    var center_x = Math.floor(ctx.canvas.width * 0.5);
45    var center_y = Math.floor(ctx.canvas.height * 0.5);
46    center_y = Math.floor(center_y + (offset_magnitude * 0.2));
47
48    /* Feedback loop on noise */
49    for (let i = 0; i < ctx.canvas.width; i++) {
50        for (let j = 0; j < ctx.canvas.height; j++) {
51        
52            var x_position = i;
53
54            if (center_x < i) {
55                x_position = Math.max(i - 2, 0);
56            } else if (center_x > i) {
57                x_position = Math.min(i + 2, ctx.canvas.width)
58            }
59            
60            var y_position = j;
61            
62            if (center_y < j) {
63                y_position = Math.max(j - 2 - (offset_magnitude * 0.00004), 0);
64            } else if (center_y > j) {
65                y_position = Math.min(j + 2 + (offset_magnitude * 0.00004), ctx.canvas.height);
66            }
67
68            var index_position = Math.floor((x_position + (y_position * ctx.canvas.width)) * 4);
69
70            var getRed = frame_original.data[index_position];
71            var getGreen = frame_original.data[index_position + 1];
72            var getBlue = frame_original.data[index_position + 2];
73            var getAlpha = frame_original.data[index_position + 3];
74
75            setPixel(i, j, getRed, getGreen, getBlue, getAlpha);
76        }
77    }
78
79    /* Add pixel wherever user touched */
80    if (framesSinceTap < framesTapLasts) {
81        var getRed = Math.ceil((Math.sin(Date.now() * 0.0021) + 1.0) * 32.0) * 8;
82        var getGreen = Math.ceil((Math.sin(Date.now() * 0.0004) + 1.0) * 32.0) * 8;
83        var getBlue = 256;
84        
85        setPixel(x_tap_position, y_tap_position, 0, 0, 0, 256);
86        setPixel(x_tap_position + 1, y_tap_position, 0, 0, 0, 256);
87        setPixel(x_tap_position + 1, y_tap_position - 1, getRed, getGreen, getBlue, 256);
88        setPixel(x_tap_position - 1, y_tap_position, getRed, getGreen, getBlue, 256);
89        setPixel(x_tap_position - 1, y_tap_position + 1, getRed, getGreen, getBlue, 256);
90        setPixel(x_tap_position - 2, y_tap_position, getRed, getGreen, getBlue, 256);
91        setPixel(x_tap_position - 2, y_tap_position + 2, getRed, getGreen, getBlue, 256);
92        setPixel(x_tap_position - 3, y_tap_position + 3, getRed, getGreen, getBlue, 256);
93        
94        setPixel((ctx.canvas.width - x_tap_position), y_tap_position, 0, 0, 0, 256);
95        setPixel((ctx.canvas.width - x_tap_position - 1), y_tap_position, 0, 0, 0, 256);
96        setPixel((ctx.canvas.width - x_tap_position - 3), y_tap_position + 2, 256, 256, 256, 256);
97        setPixel((ctx.canvas.width - x_tap_position + 1), y_tap_position, getRed, getGreen, getBlue, 256);
98        setPixel((ctx.canvas.width - x_tap_position + 2), y_tap_position + 2, getRed, getGreen, getBlue, 256);
99    }
100
101    /* Generate noise in center */
102    var x_width = Math.floor((1 + Math.sin(Date.now() * 0.00008)) * 4)
103    var y_width = Math.floor(((1 + Math.sin(Date.now() * 0.00028)) * 25) + Math.abs(offset_magnitude * 0.04))
104    var y_noise_offset = Math.floor(((1 + Math.sin(Date.now() * 0.00005)) * 29) + Math.abs(offset_magnitude * 0.09))
105
106    // Fix: If it's the first few seconds, make sure there is something on the screen
107    var current_time = new Date();
108
109    if (current_time - initial_time < 1600) {
110        x_width = Math.max(x_width, 1)
111        y_width = Math.max(y_width, 1);
112        y_noise_offset = Math.floor(y_noise_offset * 0.25)
113    }
114
115    for (let i = center_x - x_width; i < center_x + x_width; i++) {
116        for (let j = center_y - y_width; j < center_y + y_width; j++) {
117            var thisdate = Date.now();
118            var splitseconds = thisdate * 0.0004;
119            var getRed = Math.ceil((Math.sin(splitseconds + i + j + i + j) + 1.0) * 32.0) * 8;
120            var getGreen = Math.ceil((Math.sin(splitseconds + 1.1 - i - j - j) + 1.0) * 32.0) * 8;
121            var getBlue = 256;
122
123            // If it's the first 4800 milliseconds, do black/white
124            if (current_time - initial_time < 4800) {
125                var getRG = (getRed + getGreen);
126                if (getRG > 256) {
127                    getRG = 256;
128                } else {
129                    getRG = 0;
130                }
131                getRed = getRG;
132                getGreen = getRG;
133                getBlue = getRG;
134            }
135            setPixel(i, Math.min(j + y_noise_offset, ctx.canvas.height), getRed, getGreen, getBlue, 256);
136        }
137    }
138    framesSinceTap = framesSinceTap + 1;
139    ctx.putImageData(frame, 0, 0)
140}
141
142let startAnim = setInterval(startDrawing, 80);

Livestream of a Mountain Rebuilding Itself (Pattern 240928), 2024. Javascript. 10:28 min. loop. 142 lines, 6 KB.