Kinetic Color Fields
Generated by GridFlow AI | Tags: Kinetic Art, Generative Art, Abstract Art, Perlin Noise, Color Fields, Dynamic Systems, Animation, Organic Patterns
💡 AI 提示词
Create a complete artwork for: Kinetic Color Fields🧠 核心算法要点
- A responsive grid of circular elements is established, adapting dynamically to window size changes.
- Each circle's color (Hue, Saturation, Brightness) is determined by multiple, distinct Perlin noise functions.
- The Perlin noise inputs for color are continuously animated along the Z-axis, creating smooth, evolving color transitions across the field.
- The size of each circle is controlled by a separate Perlin noise function, providing spatial variation in scale.
- An additional global sine-wave-based pulsation is applied to all circles, introducing a rhythmic, breathing motion across the entire grid.
- HSB color mode is utilized to facilitate intuitive control over color attributes and achieve smooth, vibrant transitions.
💻 原始 p5.js 代码
var sketch = function(p) {
let cols, rows;
let cellWidth, cellHeight;
let baseNoiseScale = 0.03; // Base scale for Perlin noise coordinates
let timeSpeed = 0.002; // Speed of overall time evolution
let maxCellSizeRatio = 0.9; // Max size of circle relative to cell
let minCellSizeRatio = 0.3; // Min size of circle relative to cell
let targetCols = 30; // Desired number of columns, scales responsively
p.setup = function() {
let container = document.getElementById('p5-wrapper'); p.createCanvas(container.offsetWidth, container.offsetHeight).parent('p5-wrapper');
p.colorMode(p.HSB, 360, 100, 100); // Use HSB for intuitive color manipulation
p.noStroke(); // No borders for the circles
p.updateGridDimensions(); // Initialize grid dimensions
};
// Function to recalculate grid dimensions based on window size
p.updateGridDimensions = function() {
cellWidth = p.width / targetCols;
cols = targetCols;
rows = p.ceil(p.height / cellWidth); // Maintain cell aspect ratio, ensuring full vertical fill
cellHeight = p.height / rows; // Adjust cellHeight to perfectly fill canvas
};
p.draw = function() {
p.background(0); // Black background for striking contrast
let time = p.millis() * timeSpeed; // Global time variable for animation
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
let x = i * cellWidth + cellWidth / 2;
let y = j * cellHeight + cellHeight / 2;
// Perlin noise for color variation (Hue, Saturation, Brightness)
// Using different noise offsets and speeds for each component for rich, complex transitions
let hueVal = p.noise(i * baseNoiseScale * 0.8, j * baseNoiseScale * 0.8, time * 0.5);
let satVal = p.noise(i * baseNoiseScale * 1.2, j * baseNoiseScale * 1.2, time * 0.8 + 100); // +100 offset for different noise path
let briVal = p.noise(i * baseNoiseScale * 0.9, j * baseNoiseScale * 0.9, time * 0.7 + 200); // +200 offset for different noise path
// Map noise values to HSB ranges
let h = p.map(hueVal, 0, 1, 0, 360);
let s = p.map(satVal, 0, 1, 60, 100); // Keep saturation relatively high for vibrancy
let b = p.map(briVal, 0, 1, 70, 100); // Keep brightness relatively high
p.fill(h, s, b);
// Perlin noise for size variation, creating dynamic forms
let sizeNoiseX = i * baseNoiseScale * 1.5;
let sizeNoiseY = j * baseNoiseScale * 1.5;
let sizeNoiseZ = time * 1.2 + 300; // Faster time evolution for size changes
let sizeVal = p.noise(sizeNoiseX, sizeNoiseY, sizeNoiseZ);
// Map noise value to a base size ratio within min/max constraints
let baseSize = p.map(sizeVal, 0, 1, minCellSizeRatio, maxCellSizeRatio);
// Add a global, rhythmic pulsation effect for a kinetic feel
// Sine wave provides smooth oscillation, offset by grid position for a ripple effect
let globalPulsation = p.sin(time * 2 + (i + j) * 0.1) * 0.2 + 0.8; // Range ~0.6 to 1.0
// Calculate final size based on base size and pulsation
let finalSize = cellWidth * baseSize * globalPulsation;
p.ellipse(x, y, finalSize, finalSize);
}
}
};
// Recalibrate canvas and grid when window is resized
p.windowResized = function() {
let container = document.getElementById('p5-wrapper'); p.resizeCanvas(container.offsetWidth, container.offsetHeight);
p.updateGridDimensions();
};
};
new p5(sketch);
🎨 AI 艺术解读
Kinetic Color Fields invites contemplation into a realm where color and motion converge in an organic dance. The continuously shifting hues and pulsating forms evoke a sense of living energy, like a vast, breathing mosaic or the undulating surface of an alien ocean. This artwork explores the subtle complexities that emerge from simple algorithmic rules, creating a meditative yet dynamic visual experience that hints at the ephemeral beauty of natural phenomena and the unseen forces that shape our world.
📝 补充说明
- Using multiple Perlin noise instances with different offsets and speeds for hue, saturation, brightness, and size creates richer, less predictable variations than a single noise source.
- The `p.HSB` color mode is crucial for this type of artwork, allowing direct manipulation of color components for smooth, vibrant transitions without falling into muddy RGB values.
- Careful tuning of `baseNoiseScale` and `timeSpeed` parameters significantly impacts the artwork's character, dictating the granularity of patterns and the overall pace of evolution.
- The use of `p.ceil` for calculating `rows` and then adjusting `cellHeight` ensures the grid perfectly fills the canvas vertically, avoiding partial cells or awkward gaps at the bottom.