Colección de Códigos p5.js - Flores Interactivas (con Visualización)

Ejemplo 1: Flor con Partículas y Ruido Perlin

Este código utiliza p5.js para crear una flor cuyas partículas (pétalos) se mueven orgánicamente usando ruido Perlin y siguen sutilmente la posición del ratón. Explora conceptos de sistemas de partículas y movimiento basado en ruido.


let particles = [];
let petalColor;
let centerColor;

function setup() {
  createCanvas(400, 400);
  petalColor = color(255, 100, 0); // Orange
  centerColor = color(255, 200, 0); // Yellow

  // Create initial particles for petals
  for (let i = 0; i < 150; i++) {
    particles.push(new Particle());
  }
}

function draw() {
  background(100, 150, 100); // Greenish background

  // Draw flower center
  fill(centerColor);
  ellipse(width / 2, height / 2, 75, 75);

  // Update and display particles (petals)
  for (let particle of particles) {
    particle.update();
    particle.display();
  }
}

class Particle {
  constructor() {
    this.pos = createVector(width / 2, height / 2); // Start at center
    this.angle = random(TWO_PI);
    this.speed = random(0.5, 1.5);
    this.noiseOffset = random(1000); // Unique offset for Perlin noise
    this.size = random(5, 10);
    this.distanceFromCenter = random(30, 120); // Petal length
  }

  update() {
    // Apply Perlin noise to movement
    let noiseFactor = map(noise(this.noiseOffset), 0, 1, -0.2, 0.2); // Adjust noise range
    this.angle += noiseFactor;
    this.noiseOffset += 0.01;

    // Follow Mouse
    let angleToMouse = atan2(mouseY - height / 2, mouseX - width / 2);
    let angleDifference = angleToMouse - this.angle;
    this.angle += angleDifference * 0.01; // Smoothly adjust angle to mouse

    // Update position
    this.pos.x = width / 2 + cos(this.angle) * this.distanceFromCenter;
    this.pos.y = height / 2 + sin(this.angle) * this.distanceFromCenter;
  }

  display() {
    noStroke();
    fill(petalColor);
    ellipse(this.pos.x, this.pos.y, this.size, this.size);
  }
}

Notas Adicionales:

Ejemplo 2: Flor con Partículas y Fuerza de Atracción

Este ejemplo simula pétalos como partículas que son atraídas hacia un punto central (el centro de la flor) usando un cálculo de fuerzas simple. Demuestra cómo simular interacciones básicas de física vectorial en p5.js.


let particles = [];
let attractionPoint;

function setup() {
  createCanvas(500, 500);
  attractionPoint = createVector(width / 2, height / 2); // Center of the flower

  // Create particles for the petals
  for (let i = 0; i < 50; i++) {
    let angle = map(i, 0, 50, 0, TWO_PI);
    let petal = new Particle(attractionPoint.x + cos(angle) * 50, attractionPoint.y + sin(angle) * 50);
    particles.push(petal);
  }
}

function draw() {
  background(100,150,100); // Green background

  // Draw flower center
  fill(255, 204, 0); // Yellow
  noStroke();
  ellipse(attractionPoint.x, attractionPoint.y, 75, 75);

  // Update and display particles
  for (let particle of particles) {
    let force = attractionForce(particle.position, attractionPoint);
    particle.applyForce(force);
    particle.update();
    particle.display();
  }
}

function attractionForce(position, target) {
  let force = p5.Vector.sub(target, position);
  let distance = force.mag();
  distance = constrain(distance, 5, 200); // Limit the distance
  let strength = map(distance, 5, 200, 0.15, 0.01);  // Adjust strength for bloom effect
  force.setMag(strength);
  return force;
}

class Particle {
  constructor(x, y) {
    this.position = createVector(x, y);
    this.velocity = createVector(0, 0);
    this.acceleration = createVector(0, 0);
    this.diameter = 25;
    this.color = color(255, 100, 0); // Orange color
  }

  applyForce(force) {
    this.acceleration.add(force);
  }

  update() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0); // Reset acceleration
    this.velocity.limit(2);
  }

  display() {
    fill(this.color);
    noStroke();
    ellipse(this.position.x, this.position.y, this.diameter, this.diameter);
  }
}

Notas Adicionales:

Ejemplo 3: Flor con Pétalos Estáticos e Interactividad Simple

Una flor más simple donde los pétalos son elipses dibujadas estáticamente en cada frame. La longitud y el ángulo de los pétalos se ven afectados por la posición horizontal y vertical del ratón, respectivamente, creando una interacción directa.


function setup() {
  createCanvas(500, 500);
  angleMode(DEGREES);
}

function draw() {
  background(50, 100, 50); // Dark green background

  // Flower center properties
  let centerX = 250;
  let centerY = 250;
  let centerSize = 50;
  let petalColor = color(255, 100, 0);  // Vibrant Orange
  let centerColor = color(255, 200, 0);  // Yellow

  // Draw the flower center
  fill(centerColor);
  noStroke();
  ellipse(centerX, centerY, centerSize, centerSize);

  // Petal properties
  let numPetals = 20;
  // Petal length influenced by mouse distance from center
  let petalLength = dist(mouseX, mouseY, centerX, centerY) / 5 + 30;
  let petalWidth = 10;

  // Draw the petals
  for (let i = 0; i < numPetals; i++) {
    // Angle influenced by mouseX position
    let angle = i * (360 / numPetals) + map(mouseX, 0, width, -10, 10);

    // Calculate petal position based on angle and length
    let x = centerX + petalLength * cos(angle);
    let y = centerY + petalLength * sin(angle);

    // Draw the petal
    push(); // Isolate transformations
    translate(x, y); // Move to petal's base position
    rotate(angle + 90); // Rotate petal to point outwards from center
    fill(petalColor);
    ellipse(0, 0, petalWidth, petalLength); // Draw the petal shape
    pop(); // Restore original transformation state
  }
}

Notas Adicionales:

Ejemplo 4: Flor con Pétalos Bezier y Follaje Simple

Este código dibuja una flor con pétalos creados usando curvas Bezier para una forma más orgánica. La forma y longitud de los pétalos responden a la posición X e Y del ratón. Además, añade un fondo simple de "follaje" simulado con elipses aleatorias.


function setup() {
  createCanvas(600, 600);
  angleMode(DEGREES); // Use degrees for angle calculations
}

function draw() {
  background(100, 150, 90); // Greenish background for foliage

  // Foliage simulation (simple random ellipses)
  for (let i = 0; i < 100; i++) {
    let x = random(0, width);
    let y = random(height/2, height); // Concentrate foliage at the bottom half
    let size = random(5, 20);
    let colorOffset = map(mouseY, 0, height, -20, 20); //Shift color slightly based on mouseY
    fill(50, 150 + colorOffset, 40, 150); // Semi-transparent green
    noStroke();
    ellipse(x, y, size, size);
  }

  // Flower properties
  let centerX = width / 2;
  let centerY = height / 2 - 50; // Shift flower up a bit
  let petalColor = color(255, 120, 0); // Orange
  let centerColor = color(255, 204, 0); // Yellow

  // Flower center
  fill(centerColor);
  noStroke(); // Ensure center has no stroke
  ellipse(centerX, centerY, 80, 80);

  // Petals
  let numPetals = 12;
  for (let i = 0; i < numPetals; i++) {
    push(); // Isolate transformations
    translate(centerX, centerY); // Move origin to flower center
    rotate(i * 360 / numPetals); // Rotate for each petal

    // Petal animation controlled by mouse
    // Angle/Curve of the petal sides based on mouseX
    let petalAngle = map(mouseX, 0, width, -15, 15);
    // Length of the petal based on mouseY
    let petalLength = map(mouseY, 0, height, 50, 100);

    // Draw petal using bezier curves for a smoother shape
    fill(petalColor);
    noStroke();
    beginShape();
    vertex(0, 0); // Start at the center
    // Control points define the curve outward
    bezierVertex(petalLength / 3, -10 - petalAngle, petalLength / 3 * 2, -10 - petalAngle, petalLength, 0);
    // Control points define the curve inward, back to center
    bezierVertex(petalLength / 3 * 2, 10 + petalAngle, petalLength / 3, 10 + petalAngle, 0, 0);
    endShape(CLOSE); // Close the shape back to the start vertex
    pop(); // Restore original transformation state
  }
}

Notas Adicionales:

Ejemplo 5: Flor con Pétalos Rectangulares y Ruido Orgánico

Este ejemplo utiliza pétalos rectangulares simples, pero introduce ruido Perlin (noise()) para desplazar ligeramente la posición de cada pétalo en cada frame, dándole un aspecto más orgánico y tembloroso. La rotación general de los pétalos también está influenciada por la posición X del ratón.


function setup() {
  createCanvas(600, 600);
  angleMode(DEGREES);
  noStroke(); // Apply noStroke globally here
}

function draw() {
  background(80, 120, 80); // Dark green background for leaves

  // Flower center properties
  let centerX = width / 2;
  let centerY = height / 2;
  let centerColor = color(255, 204, 0); // Yellow-orange color
  let centerRadius = 50;

  // Draw the flower center
  fill(centerColor);
  ellipse(centerX, centerY, centerRadius * 2, centerRadius * 2);

  // Petal properties
  let petalColor = color(255, 100, 0); // Orange color
  let petalLength = 100;
  let petalWidth = 10;
  let numPetals = 20;

  // Interactive petal angle offset based on mouseX
  let petalAngleOffset = map(mouseX, 0, width, -20, 20);

  // Draw petals using a loop
  for (let i = 0; i < numPetals; i++) {
    push(); // Save current transformation state
    translate(centerX, centerY); // Move origin to flower center
    // Rotate each petal based on its index and the mouse-controlled offset
    rotate(i * (360 / numPetals) + petalAngleOffset);

    // Apply Perlin noise to petal position for an organic look
    // Use 'i' and 'frameCount' to get varying noise values over time and per petal
    let noiseX = map(noise(i, frameCount * 0.01), 0, 1, -5, 5);
    let noiseY = map(noise(i + 10, frameCount * 0.01), 0, 1, -5, 5); // Offset second noise call
    translate(noiseX, noiseY); // Apply the small noise-driven displacement

    // Draw the petal (a simple rectangle starting at the rotated origin)
    fill(petalColor);
    // rect(x, y, width, height) - here x=0, y=0 because we translated the origin
    rect(0, 0, petalLength, petalWidth);
    pop(); // Restore previous transformation state
  }
}

Notas Adicionales: