The Ring Class

Back to Energy Rings Animation

Purpose: The Ring class represents a single expanding ring with dynamic properties including size, thickness, color, and transparency. This class encapsulates all the data and behavior needed to create and animate a single energy ring.

Visual Example

Ring Instance Example
Ring objects rendered on the canvas, showing the expanding circle with varying thickness and fading transparency

Key Object-Oriented Programming Concepts

Complete Ring Class Source Code

// ============================================
// RING CLASS (Base Class)
// ============================================
// This class defines a single ring and what it can do
// The EnergyRing class will use this as the building block for creating
// sequential pulses
class Ring {
    // Constructor - called when creating a new Ring object
    // Parameters:
    //   x, y: position of ring center
    //   settings: object containing hue, saturation, brightness, thickness, maxDiameter, speed
    constructor(x, y, settings) {
        this.x = x;                                 // X position of the ring center
        this.y = y;                                 // Y position of the ring center
        this.diameter = 0;                          // Starting diameter (will grow)
        this.maxDiameter = settings.maxDiameter;    // Maximum size before disappearing
        
        // Handle thickness settings
        // If finalThickness < initialThickness, we need to swap them
        // or ensure the mapping still works correctly
        this.initialThickness = settings.initialThickness;
        this.finalThickness = settings.finalThickness;
        
        // Determine if thickness is growing or shrinking
        // This allows the ring to either expand or contract in thickness
        this.thicknessGrowing = this.finalThickness >= this.initialThickness;
        
        this.currentThickness = settings.initialThickness;  // Current thickness (will change over time)
        this.speed = settings.speed;                        // How fast the ring expands (pixels per frame)
        
        // Color for the ring using HSB color mode
        this.hue = settings.hue;                // Hue from control panel
        this.saturation = settings.saturation;  // Saturation from control panel
        this.brightness = settings.brightness;  // Brightness from control panel
        this.alpha = 255;                       // Transparency (255 = fully opaque)
    }
    
    // Update method - called each frame to grow the ring
    update() {
        // Increase the diameter by the speed value
        this.diameter += this.speed;
        
        // Fade out as the ring gets larger
        // map() converts diameter range to alpha range (255 to 0)
        this.alpha = map(this.diameter, 0, this.maxDiameter, 255, 0);
        
        // Calculate current thickness based on diameter
        // As the ring expands from 0 to maxDiameter,
        // thickness changes from initialThickness to finalThickness
        // This works correctly whether finalThickness is larger or smaller than initialThickness
        // If finalThickness > initialThickness: ring gets thicker (energy pulse effect)
        // If finalThickness < initialThickness: ring gets thinner (reverse effect)
        this.currentThickness = map(this.diameter, 0, this.maxDiameter, 
                                   this.initialThickness, this.finalThickness);
    }
    
    // Display method - draws the ring on the canvas
    display() {
        // Set stroke (outline) color with transparency using HSB values
        stroke(this.hue, this.saturation, this.brightness, this.alpha);
        
        // Set the thickness of the ring outline using the current thickness
        // This value changes dynamically as the ring expands
        strokeWeight(this.currentThickness);
        
        // Don't fill the circle (just draw the outline)
        noFill();
        
        // Draw the circle (ring) at position x, y with current diameter
        circle(this.x, this.y, this.diameter);
    }
    
    // Check if the ring has finished expanding
    isFinished() {
        return this.diameter > this.maxDiameter;
    }
    
    // Get the progress of this ring as a value between 0 and 1
    // 0 = just started, 1 = reached max diameter
    // Used by EnergyRing to determine when to spawn the next ring
    getProgress() {
        return this.diameter / this.maxDiameter;
    }
}

Instance Variables (Properties)

Property Type Description
x Number X coordinate of the ring's center
y Number Y coordinate of the ring's center
diameter Number Current diameter of the ring (starts at 0, grows over time)
maxDiameter Number Maximum diameter before the ring is considered finished
initialThickness Number Starting stroke thickness in pixels
finalThickness Number Ending stroke thickness in pixels
currentThickness Number Current stroke thickness (changes dynamically)
speed Number Growth rate in pixels per frame
hue Number Color hue value (0-360)
saturation Number Color saturation value (0-100)
brightness Number Color brightness value (0-100)
alpha Number Transparency value (0-255, fades as ring expands)

Methods (Behaviors)

Method Returns Description
constructor(x, y, settings) - Initializes a new Ring with position and configuration settings
update() void Updates the ring's state each frame (grows diameter, adjusts thickness and transparency)
display() void Renders the ring on the canvas using p5.js drawing functions
isFinished() Boolean Returns true if the ring has exceeded its maximum diameter
getProgress() Number Returns a value between 0 and 1 representing expansion progress

Example Usage

// Create settings object with ring configuration
let ringSettings = {
    hue: 51,                // Gold color
    saturation: 100,
    brightness: 100,
    initialThickness: 2,
    finalThickness: 50,
    maxDiameter: 400,
    speed: 2
};

// Create a new Ring instance at position (400, 300)
let myRing = new Ring(400, 300, ringSettings);

// In the animation loop:
function draw() {
    background(0, 0, 94);
    
    myRing.update();      // Update ring state
    myRing.display();     // Draw the ring
    
    // Check if ring is finished
    if (myRing.isFinished()) {
        console.log("Ring has completed its expansion!");
    }
}