228

Dumbo Octopus Flight

Abyssal Grimpoteuthis octopus propulsion utilizing harmonic ear-like pectoral fin flapping kinematics and an undulating gelatinous cirrate umbrella skirt.

Playground
60 FPS Canvas 2D
Click + Drag to interact with field
</>

Full Executable Algorithm Code

// 048 - Dumbo Octopus Flight (creatures)
// 1:1 Original algorithm engine source
function createDumboOctopus() {
  const MANTLE_RIBBONS = 28;
  const EAR_FILAMENTS = 20;
  return {
    setup() {
    },
    render(context, timeState, params) {
      const { ctx, width, height } = context;
      const flapSpeed = Number(params.flapRate || 1.3);
      const earSpan = Number(params.earSpread || 1.2);
      const t = timeState.time * flapSpeed;
      ctx.fillStyle = "#020307";
      ctx.fillRect(0, 0, width, height);
      const cx = width * 0.5 + Math.sin(t * 0.5) * (width * 0.08);
      const cy = height * 0.45 + Math.sin(t * 1.6) * 12;
      const dumboScale = Math.min(width, height) / 480;
      ctx.save();
      ctx.translate(cx, cy);
      ctx.globalCompositeOperation = "screen";
      const baseHue = (330 + Math.sin(t * 0.6) * 20) % 360;
      for (let r = 0; r < MANTLE_RIBBONS; r++) {
        const normR = (r + 1) / MANTLE_RIBBONS;
        const curW = 46 * normR * dumboScale;
        const curH = 48 * normR * dumboScale;
        ctx.beginPath();
        ctx.ellipse(0, -10 * dumboScale, curW, curH, 0, 0, Math.PI * 2);
        const mHue = (baseHue + normR * 25) % 360;
        ctx.strokeStyle = hsla(mHue, 90, 70, 0.06 + normR * 0.3);
        ctx.lineWidth = normR > 0.88 ? 1.6 : 0.8;
        ctx.stroke();
      }
      const earFlap = Math.sin(t * 3.2);
      const earCurl = Math.cos(t * 3.2);
      for (let s = -1; s <= 1; s += 2) {
        for (let ef = 0; ef < EAR_FILAMENTS; ef++) {
          const normE = ef / (EAR_FILAMENTS - 1);
          const rootX = s * (22 + normE * 14) * dumboScale;
          const rootY = (-34 + normE * 12) * dumboScale;
          const curSpan = (55 + normE * 22) * earSpan * dumboScale;
          const tipX = rootX + s * curSpan;
          const tipY = rootY - (14 + normE * 8) * dumboScale + earFlap * (26 * dumboScale);
          ctx.beginPath();
          ctx.moveTo(rootX, rootY);
          ctx.bezierCurveTo(
            rootX + s * (35 + normE * 10) * dumboScale,
            rootY - 45 * dumboScale + earCurl * (16 * dumboScale),
            tipX + s * 10 * dumboScale,
            tipY - 20 * dumboScale,
            tipX,
            tipY
          );
          ctx.bezierCurveTo(
            tipX - s * 15 * dumboScale,
            tipY + 35 * dumboScale,
            rootX + s * 22 * dumboScale,
            rootY + 15 * dumboScale,
            rootX,
            rootY
          );
          ctx.closePath();
          const earHue = (baseHue - 15 + normE * 30) % 360;
          ctx.strokeStyle = hsla(earHue, 95, 78, 0.08 + normE * 0.35);
          ctx.lineWidth = ef % 4 === 0 ? 1.6 : 0.8;
          ctx.stroke();
        }
      }
      for (let s = -1; s <= 1; s += 2) {
        const eyeX = s * 24 * dumboScale;
        const eyeY = 0;
        ctx.fillStyle = "#0284c7";
        ctx.beginPath();
        ctx.arc(eyeX, eyeY, 8 * dumboScale, 0, Math.PI * 2);
        ctx.fill();
        ctx.strokeStyle = "#e0f2fe";
        ctx.lineWidth = 1.4;
        ctx.stroke();
        ctx.fillStyle = "#ffffff";
        ctx.beginPath();
        ctx.arc(eyeX - 2.5, eyeY - 2.5, 3 * dumboScale, 0, Math.PI * 2);
        ctx.fill();
      }
      const ARM_COUNT = 8;
      for (let layer = 0; layer < 6; layer++) {
        const normL = (layer + 1) / 6;
        const skirtTips = [];
        for (let a = 0; a < ARM_COUNT; a++) {
          const normA = (a / (ARM_COUNT - 1) - 0.5) * Math.PI * 0.82;
          const armWave = Math.sin(t * 2.8 + a * 0.7 + layer * 0.3) * 8 * dumboScale;
          const armLen = (65 + (4 - Math.abs(a - 3.5)) * 8) * normL * dumboScale;
          const ax = Math.sin(normA) * (45 * normL * dumboScale) + armWave;
          const ay = 22 * dumboScale + Math.cos(normA) * armLen;
          skirtTips.push({ x: ax, y: ay });
        }
        ctx.beginPath();
        ctx.moveTo(skirtTips[0].x, skirtTips[0].y);
        for (let a = 1; a < ARM_COUNT; a++) {
          const prev = skirtTips[a - 1];
          const cur = skirtTips[a];
          const midX = (prev.x + cur.x) * 0.5;
          const midY = (prev.y + cur.y) * 0.5 - 10 * normL * dumboScale;
          ctx.quadraticCurveTo(midX, midY, cur.x, cur.y);
        }
        ctx.lineTo(25 * normL * dumboScale, 20 * dumboScale);
        ctx.lineTo(-25 * normL * dumboScale, 20 * dumboScale);
        ctx.closePath();
        const sHue = (baseHue + layer * 10) % 360;
        ctx.strokeStyle = hsla(sHue, 90, 75, 0.1 + normL * 0.35);
        ctx.lineWidth = layer === 5 ? 1.8 : 0.8;
        ctx.stroke();
      }
      ctx.restore();
    }
  };
}

// Default parameters from content metadata
const defaultParams = [
  {
    "key": "flapRate",
    "label": "Ear Flap Rhythm",
    "type": "range",
    "min": 0.5,
    "max": 2.5,
    "step": 0.1,
    "defaultValue": 1.3,
    "description": "Pectoral fin flapping frequency"
  },
  {
    "key": "earSpread",
    "label": "Pectoral Fin Wingspan",
    "type": "range",
    "min": 0.7,
    "max": 1.8,
    "step": 0.1,
    "defaultValue": 1.2,
    "description": "Ear-like fin extension scaling"
  }
];

if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['dumbo-octopus']) {
  const inst = typeof createDumboOctopus === 'function' ? createDumboOctopus() : null;
  if (inst && inst.setup) {
    inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
  }
  window.__art_instances['dumbo-octopus'] = inst;
}

const instance = window.__art_instances['dumbo-octopus'];
if (instance && instance.render) {
  instance.render(
    { ctx, width, height, dpr: 1, aspectRatio: width / height },
    { time, deltaTime: dt, frameCount: Math.floor(time * 60), fps: 60 },
    defaultParams
  );
}
Edit in Interactive Playground Zero Dependencies • Standalone Canvas 2D
ƒ

Mathematical Formulation

medium
Analytical Equation
zfin(u,t)=Afsin(ωft)u+Bfcos(ωft)(1u2),parm(k,t)=p0+[sinθkRkcosθkLk+wk(t)]z_{\text{fin}}(u, t) = A_f \sin(\omega_f t) \cdot u + B_f \cos(\omega_f t) \cdot (1 - u^2), \quad \mathbf{p}_{\text{arm}}(k, t) = \mathbf{p}_0 + \begin{bmatrix} \sin\theta_k \cdot R_k \\ \cos\theta_k \cdot L_k + w_k(t) \end{bmatrix}
Click to expand
Compact Formula
ear_flap = bezierCurve(root, earCurl*15, earTip + earFlap*26), skirt = quadCurve(arm_prev, midPt - 10, arm_cur)

Mathematical Tags

#dumbo-octopus #grimpoteuthis #deep-sea #abyss #creatures #fins #octopod
Author: Math Art Core Target: 60 FPS

Export & Embed: Dumbo Octopus Flight

4K PNG Snapshot

High-resolution single frame render

WebM Video (5s Loop)

60 FPS browser-captured stream

Standalone JS Script

Complete executable Canvas 2D algorithm

HTML Iframe Embed

<iframe src="https://art.fazleyrabbi.xyz/embed/dumbo-octopus" width="500" height="500" frameborder="0" loading="lazy"></iframe>
ESC
↑↓ Navigate Select
110 Mathematical Artworks
Made by Fazley Rabbi

Support the Project

Keep mathematical creative coding alive & open source

Or via Direct Payoneer ($0 Fee)
Payoneer Customer ID: $0 Fee Direct
24076084

💡 Payoneer app: Go to Pay → Pay to recipient → Enter ID 24076084.

Thank you for supporting generative mathematical animations! ✨