master
js 161 lines 6.84 KB
Raw
1 // Wrap all DOM-dependent code inside a DOMContentLoaded event listener
2 document.addEventListener('DOMContentLoaded', function() {
3 // Get the canvas element and its 2D rendering context
4 const canvas = document.getElementById('pixelCanvas');
5 const ctx = canvas.getContext('2d');
6
7 // Text content and properties for the canvas-drawn text
8 const mainText = "Dynamic Pixelmap Background";
9 const subText = "Watch the colors change!";
10 const thirdText = "This text has pixel-level contrast!";
11 let fontSizeH1 = 48; // px - will be dynamically adjusted
12 let fontSizeP = 24; // px - will be dynamically adjusted
13 const fontName = "Inter, sans-serif"; // Ensure font is available or fallback
14
15 /**
16 * Generates a random hexadecimal color code, biased towards darker shades (slightly brighter than before).
17 *
18 * @returns {string} A random hexadecimal color code (e.g., '#RRGGBB').
19 */
20 function generateRandomColor() {
21 // Limit random byte generation to a darker range (0-150) - adjusted for brighter background
22 const getRandomDarkByte = () => Math.floor(Math.random() * 151); // Max value 150
23
24 const r = getRandomDarkByte();
25 const g = getRandomDarkByte();
26 const b = getRandomDarkByte();
27
28 // Helper to convert a number to a two-digit hexadecimal string
29 const toHex = (c) => {
30 const hex = c.toString(16);
31 return hex.length === 1 ? '0' + hex : hex; // Ensure two digits (e.g., 'f' becomes '0f')
32 };
33
34 // Combine RGB components into a full hexadecimal color string
35 return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
36 }
37
38 // Function to set up canvas dimensions and handle window resizing
39 function resizeCanvas() {
40 canvas.width = window.innerWidth;
41 canvas.height = window.innerHeight;
42
43 // Dynamically adjust font sizes based on screen width for responsiveness
44 if (canvas.width < 600) {
45 fontSizeH1 = 32; // Smaller font for small screens
46 fontSizeP = 18;
47 } else if (canvas.width < 900) {
48 fontSizeH1 = 40; // Medium font for medium screens
49 fontSizeP = 22;
50 } else {
51 fontSizeH1 = 48; // Original font size for large screens
52 fontSizeP = 24;
53 }
54 // No need to clear here, animate will clear and redraw
55 }
56
57 // Define parameters for drawing background pixels
58 const pixelSize = 1; // The size (width and height) of each square pixel in pixels (remains 1)
59 const pixelsPerFrame = 500; // The number of random background pixels to draw in each animation frame (increased for quicker change)
60
61 /**
62 * Draws a single randomly colored pixel on the canvas.
63 * The pixel's position is snapped to a grid defined by `pixelSize`.
64 */
65 function drawRandomBackgroundPixel() {
66 const x = Math.floor(Math.random() * (canvas.width / pixelSize)) * pixelSize;
67 const y = Math.floor(Math.random() * (canvas.height / pixelSize)) * pixelSize;
68 const color = generateRandomColor();
69 ctx.fillStyle = color;
70 ctx.fillRect(x, y, pixelSize, pixelSize);
71 }
72
73 /**
74 * Draws text on the canvas with pixel-level contrast to the background.
75 * This function uses an off-screen canvas to get the text mask.
76 */
77 function drawContrastingText() {
78 // Create an off-screen canvas for text rendering
79 const tempCanvas = document.createElement('canvas');
80 const tempCtx = tempCanvas.getContext('2d');
81 tempCanvas.width = canvas.width;
82 tempCanvas.height = canvas.height;
83
84 // Set text properties for the off-screen canvas
85 tempCtx.font = `${fontSizeH1}px ${fontName}`;
86 tempCtx.textAlign = 'center';
87 tempCtx.textBaseline = 'middle';
88 tempCtx.fillStyle = 'black'; // Draw text in black to get a clear mask
89
90 // Calculate text positions (centered)
91 const centerX = canvas.width / 2;
92 const centerY = canvas.height / 2;
93 // Adjust lineHeight based on current fontSizeH1
94 const lineHeight = fontSizeH1 * 1.2; // Approximate line height
95
96 // Draw text on the off-screen canvas
97 tempCtx.fillText(mainText, centerX, centerY - lineHeight);
98 tempCtx.font = `${fontSizeP}px ${fontName}`;
99 tempCtx.fillText(subText, centerX, centerY);
100 tempCtx.fillText(thirdText, centerX, centerY + lineHeight);
101
102 // Get pixel data from the main canvas (current background)
103 const mainImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
104 const mainPixels = mainImageData.data;
105
106 // Get pixel data from the off-screen text canvas (text mask)
107 const tempImageData = tempCtx.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
108 const tempPixels = tempImageData.data;
109
110 // Loop through all pixels
111 for (let i = 0; i < mainPixels.length; i += 4) {
112 // Check if the pixel on the temporary canvas is part of the text (opaque black)
113 if (tempPixels[i + 3] > 0) { // If this pixel is part of the text
114 // Get the background color at this pixel position from main canvas
115 const bgR = mainPixels[i];
116 const bgG = mainPixels[i + 1];
117 const bgB = mainPixels[i + 2];
118
119 // Calculate the inverse color for contrast.
120 mainPixels[i] = 255 - bgR;
121 mainPixels[i + 1] = 255 - bgG;
122 mainPixels[i + 2] = 255 - bgB;
123 }
124 }
125
126 // Put the modified pixel data back onto the main canvas
127 ctx.putImageData(mainImageData, 0, 0);
128 }
129
130 /**
131 * The main animation loop.
132 * It draws a set number of random background pixels per frame and then redraws the contrasting text.
133 */
134 function animate() {
135 // Draw multiple background pixels in each frame (accumulating effect)
136 for (let i = 0; i < pixelsPerFrame; i++) {
137 drawRandomBackgroundPixel();
138 }
139
140 // Draw the contrasting text on top of the background
141 drawContrastingText();
142
143 // Request the next animation frame, creating a smooth loop
144 requestAnimationFrame(animate);
145 }
146
147 // Initial setup and animation start
148 resizeCanvas(); // Set the initial canvas size and font sizes
149 animate(); // Start the pixel drawing animation
150
151 // Add an event listener to resize the canvas whenever the window is resized
152 window.addEventListener('resize', () => {
153 resizeCanvas(); // Recalculate canvas size and font sizes
154 // On resize, you might want to clear the canvas and immediately redraw text
155 // to avoid temporary distortions before the pixels fill in.
156 // ctx.clearRect(0, 0, canvas.width, canvas.height); // Optional: clear on resize
157 });
158
159 window.onload = () => setTimeout(wait,5000);
160 function wait(){alert("🎉 Surprise! Welcome to the digital party! 🥳")}
161 });