48h.arts.ens.fr/js/triangles-mask.js

203 lines
6.5 KiB
JavaScript
Raw Normal View History

(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);
})();