(function () { const canvas = document.getElementById("main-header-background"); const context = canvas.getContext("2d"); // Get the node dimensions and enforce the canvas width and height const WIDTH = canvas.clientWidth; const HEIGHT = canvas.clientHeight; canvas.setAttribute("width", WIDTH); canvas.setAttribute("height", HEIGHT); // Define some useful constants const POSITIONS_UPDATE_DELAY = 50; // ms const NB_POINTS_PER_ROW = 4 + Math.round(WIDTH / 250); const NB_POINTS_PER_COL = 5; const INIT_ROW_SPACING = HEIGHT / (NB_POINTS_PER_COL - 1); const INIT_COL_SPACING = WIDTH / (NB_POINTS_PER_ROW - 3); const X_ORIGIN = -INIT_COL_SPACING; const Y_ORIGIN = -100; // When creating points const INIT_MAX_X_SHIFT_DISTANCE = INIT_ROW_SPACING / 3; const INIT_MAX_Y_SHIFT_ISTANCE = INIT_COL_SPACING / 4; // Set the drawing style context.lineWidth = 3; // Create a grid of points const points = []; for (let row = 0; row < NB_POINTS_PER_COL; row++) { for (let col = 0; col < NB_POINTS_PER_ROW; col++) { points.push({ x: X_ORIGIN + col * INIT_COL_SPACING + ((row % 2 === 1) ? INIT_COL_SPACING : 0), y: Y_ORIGIN + row * INIT_ROW_SPACING }); } } // Move each point a little bit for (let point of points) { point.x += (2 * Math.random() * INIT_MAX_X_SHIFT_DISTANCE) - INIT_MAX_X_SHIFT_DISTANCE; point.y += (2 * Math.random() * INIT_MAX_Y_SHIFT_ISTANCE) - INIT_MAX_Y_SHIFT_ISTANCE; } // Draw lines between points to make triangles function drawLineBetweenPoints (from, to) { context.beginPath(); context.moveTo(from.x, from.y); context.lineTo(to.x, to.y); context.stroke(); } function drawLinesBetweenAllPoints () { for (let row = 0; row < NB_POINTS_PER_COL; row++) { for (let col = 0; col < NB_POINTS_PER_ROW; col++) { // Nothing to do with the last point of each row if (col == NB_POINTS_PER_ROW - 1) { continue; } //if (Math.abs(col - NB_POINTS_PER_ROW / 2) < (NB_POINTS_PER_ROW / 7)) { // continue; //} // Get the current index and point const index = row * NB_POINTS_PER_ROW + col; const point = points[index]; // When applicable, draw lines to // - the next point on the same row // - the aligned point on the previous row // - the aligned point on the next row if (! (row % 2 === 1 && col === NB_POINTS_PER_ROW - 2)) drawLineBetweenPoints(point, points[index + 1]); if (row > 0) drawLineBetweenPoints(point, points[index - NB_POINTS_PER_ROW]); if (row < NB_POINTS_PER_COL - 1) drawLineBetweenPoints(point, points[index + NB_POINTS_PER_ROW]); // If the row number is odd, when applicable, also draw lines to // - the next point on the previous row // - the next point on the next row if (row % 2 === 1) { if (row > 0) drawLineBetweenPoints(point, points[index - NB_POINTS_PER_ROW + 1]); if (row < NB_POINTS_PER_COL - 1) drawLineBetweenPoints(point, points[index + NB_POINTS_PER_ROW + 1]); } } } } // Inverse image data alpha channel in order to // make the lines transparent and the triangles visible function invertAlphaChannel () { const currentImageData = context.getImageData(0, 0, WIDTH, HEIGHT); const currentData = currentImageData.data; const newImageData = context.createImageData(WIDTH, HEIGHT); const newData = newImageData.data; const dataLength = currentData.length; for (i = 0; i < dataLength; i += 4) { newData[i + 0] = 255; newData[i + 1] = 255; newData[i + 2] = 255; newData[i + 3] = 255 - currentData[i + 3]; } context.putImageData(newImageData, 0, 0); } // Update the point positions let positionUpdateIter = 0; const pointRotationDirections = []; const pointRotationSpeeds = []; const pointRotationRadius = []; for (let i = 0; i < points.length; i++) { pointRotationDirections[i] = { x: Math.random() > 0.5 ? 1 : - 1, y: Math.random() > 0.5 ? 1 : - 1 }; pointRotationSpeeds[i] = { x: (Math.random() * 1) + 1, y: (Math.random() * 1) + 1 }; pointRotationRadius[i] = { x: (Math.random() * 2) + 1, y: (Math.random() * 2) + 1 }; } function updatePointPositions () { /* for (let point of points) { point.x += (2 * MAX_X_SHIFT_DISTANCE * Math.random()) - MAX_X_SHIFT_DISTANCE; point.y += (2 * MAX_X_SHIFT_DISTANCE * Math.random()) - MAX_X_SHIFT_DISTANCE; } */ /* for (let iter = 0; iter < NB_POINT_POSITIONS_TO_UPDATE; iter++) { const index = Math.floor(points.length * Math.random()); const point = points[index]; point.x += (2 * MAX_X_SHIFT_DISTANCE * Math.random()) - MAX_X_SHIFT_DISTANCE; point.y += (2 * MAX_X_SHIFT_DISTANCE * Math.random()) - MAX_X_SHIFT_DISTANCE; } */ for (let i = 0; i < points.length; i++) { let point = points[i]; let direction = pointRotationDirections[i]; let speed = pointRotationSpeeds[i]; let radius = pointRotationRadius[i]; //console.log(direction, speed, xRadius, yRadius) point.x += direction.x * Math.cos(positionUpdateIter * speed.x / 10) * radius.x; //+ (Math.random() * 4) - 2; point.y += direction.y * Math.sin(positionUpdateIter * speed.y / 10) * radius.y; //+ (Math.random() * 4) - 2; } positionUpdateIter++; } setInterval(updatePointPositions, POSITIONS_UPDATE_DELAY); // Update the drawing function updateCanvas () { // Clear the canvas context.clearRect(0, 0, WIDTH, HEIGHT); // Repeat the drawing process drawLinesBetweenAllPoints(); invertAlphaChannel(); window.requestAnimationFrame(updateCanvas); } window.requestAnimationFrame(updateCanvas); })();