Canvas Pulse Animation

by Ben Gillbanks

HTML

<canvas id="blobCanvas" width="600" height="400"></canvas>

CSS

body {
    background: lightblue;
}
canvas {
    display: block;
    margin: 0 auto;
    width: 100%;
    max-width: 600px;
    outline: 1px white solid;
}

JavaScript

class AnimatedCharacter {
    constructor(canvasId, options) {
    this.active = false;
        this.canvas = document.getElementById(canvasId);
        this.ctx = this.canvas.getContext('2d');
        this.centerX = this.canvas.width * 0.5;
        this.centerY = this.canvas.height * 0.65;
        this.options = options || {};
        this.scale = 1.25;
        this.defaultOptions = {
            baseRadius: 100, // Default base radius of the character
            numPoints: 16, // Number of control points for character shape
            transitionDuration: 5000, // Duration of each morphing transition in milliseconds
            pauseDuration: 200, // Pause duration between morphing transitions in milliseconds
            color: 'gold' // Default color of the character
        };
        this.options = { ...this.defaultOptions, ...this.options }; // Merge default and custom options
        this.points1 = this.generatePoints(this.options.baseRadius); // Initial control points for morphing
        this.points2 = this.generatePoints(this.options.baseRadius * this.scale); // Secondary control points for morphing
        this.morphCount = 1; // Counter for morphing cycles
        this.startTime = null; // Start time of each morphing transition
    }

    // Method to generate random control points for character shape
    generatePoints(baseRadius) {
        const radiusOffset = baseRadius * 0.05;
        const points = [];
        for (let i = 0; i < this.options.numPoints; i++) {
            let angle = (Math.PI * 2 / this.options.numPoints) * i;
            let radius = baseRadius + Math.random() * radiusOffset * 2 - radiusOffset;
            let x = this.centerX + Math.cos(angle) * radius;
            let y = this.centerY + Math.sin(angle) * radius;
            if (y > (this.centerY + (this.centerY * 0.3))) {
                y = (this.centerY + (this.centerY * 0.3)) + (Math.random() * 4);
            }
            points.push({ x, y });
        }
       ...