Generative Art
Generative art adalah seni yang dibuat dengan bantuan algoritma dan keacakan terkontrol. Kamu menulis "aturan" dan komputer menghasilkan variasi visual yang unik setiap kali dijalankan.
Random yang Terkontrol
Math.random() memberikan angka acak antara 0-1. Tapi keacakan murni sering terlihat "kasar". Kunci generative art adalah membatasi keacakan agar hasilnya tetap estetis:
// Random dalam range tertentu
function random(min, max) {
return Math.random() * (max - min) + min;
}
// Random integer
function randomInt(min, max) {
return Math.floor(random(min, max + 1));
}
// Random dari array
function randomChoice(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
Pola Grid
Grid adalah fondasi banyak generative art:
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
const size = 40; // ukuran setiap sel
const cols = canvas.width / size;
const rows = canvas.height / size;
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
const x = i * size;
const y = j * size;
// Random pilih: garis diagonal / atau \
ctx.beginPath();
if (Math.random() > 0.5) {
ctx.moveTo(x, y);
ctx.lineTo(x + size, y + size);
} else {
ctx.moveTo(x + size, y);
ctx.lineTo(x, y + size);
}
ctx.strokeStyle = `hsl(${i * 10 + j * 10}, 70%, 60%)`;
ctx.lineWidth = 2;
ctx.stroke();
}
}
Ini menghasilkan pola yang terkenal bernama "10 PRINT" — salah satu generative art paling ikonik.
Perlin Noise — Keacakan yang Smooth
Math.random() menghasilkan nilai yang "lompat-lompat". Perlin noise menghasilkan nilai acak yang berkesinambungan — nilainya berubah secara gradual, menghasilkan pola yang lebih natural.
Implementasi simpel Perlin noise (simplex):
// Kita bisa menggunakan library seperti simplex-noise
// npm install simplex-noise
// atau gunakan implementasi sederhana berikut:
function smoothNoise(x, y) {
// Pseudo Perlin - gunakan sin untuk simulasi
return (Math.sin(x * 0.1) + Math.sin(y * 0.1) +
Math.sin((x + y) * 0.07) + Math.sin(Math.sqrt(x*x + y*y) * 0.05)) / 4;
}
// Gunakan untuk warna atau posisi
for (let x = 0; x < canvas.width; x += 4) {
for (let y = 0; y < canvas.height; y += 4) {
const n = smoothNoise(x, y);
const hue = ((n + 1) / 2) * 360;
ctx.fillStyle = `hsl(${hue}, 70%, 60%)`;
ctx.fillRect(x, y, 4, 4);
}
}
Mathematical Art — Spirograph
Matematika menghasilkan pola yang indah:
function drawSpirograph(R, r, d, color) {
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 0.5;
for (let t = 0; t < Math.PI * 20; t += 0.01) {
const x = (R - r) * Math.cos(t) + d * Math.cos((R - r) / r * t) + canvas.width/2;
const y = (R - r) * Math.sin(t) - d * Math.sin((R - r) / r * t) + canvas.height/2;
if (t === 0) ctx.moveTo(x, y);
else ctx.lineTo(x, y);
}
ctx.stroke();
}
drawSpirograph(150, 47, 80, "#e74c3c");
drawSpirograph(150, 71, 60, "#3498db");
Flow Field
Flow field adalah teknik di mana partikel mengikuti "arus" berdasarkan noise:
const particles = [];
const flowField = [];
const cellSize = 20;
const cols = Math.ceil(canvas.width / cellSize);
const rows = Math.ceil(canvas.height / cellSize);
// Generate flow field
for (let i = 0; i < cols * rows; i++) {
const x = (i % cols) * cellSize;
const y = Math.floor(i / cols) * cellSize;
const angle = smoothNoise(x * 0.01, y * 0.01) * Math.PI * 2;
flowField.push(angle);
}
// Buat partikel
for (let i = 0; i < 500; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
speed: 1,
});
}
function animate() {
// Jangan clearRect — biarkan trail menumpuk
ctx.fillStyle = "rgba(0, 0, 0, 0.02)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
particles.forEach(p => {
const col = Math.floor(p.x / cellSize);
const row = Math.floor(p.y / cellSize);
const index = col + row * cols;
const angle = flowField[index] || 0;
p.x += Math.cos(angle) * p.speed;
p.y += Math.sin(angle) * p.speed;
// Wrap around
if (p.x < 0) p.x = canvas.width;
if (p.x > canvas.width) p.x = 0;
if (p.y < 0) p.y = canvas.height;
if (p.y > canvas.height) p.y = 0;
ctx.fillStyle = `hsl(${angle * 57}, 80%, 60%)`;
ctx.fillRect(p.x, p.y, 1, 1);
});
requestAnimationFrame(animate);
}
animate();
Coding Style ala p5.js
p5.js mempopulerkan "creative coding" dengan API yang ramah:
// p5.js style — jika kamu ingin eksplorasi lebih lanjut
// Ini adalah pseudocode yang menunjukkan konsep p5.js
function setup() {
createCanvas(600, 400);
background(20);
}
function draw() {
noStroke();
fill(random(255), random(255), random(255), 50);
ellipse(mouseX, mouseY, random(10, 50));
}
Generative art mengajarkan kamu berpikir algoritmik sambil menghasilkan visual yang memukau. Setiap kali kamu menjalankan kode, hasilnya bisa berbeda!