228

Pelagic Sea Angel

Clione limacina pelagic gymnosome sea slug swimming with rhythmic wing-like parapodia flapping and a glowing orange-red visceral nucleus.

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

Full Executable Algorithm Code

// 051 - Pelagic Sea Angel (creatures)
// 1:1 Original algorithm engine source
function createSeaAngelPteropod() {
  const BODY_RIBBONS = 28;
  const WING_FILAMENTS = 24;
  return {
    setup() {
    },
    render(context, timeState, params) {
      const { ctx, width, height } = context;
      const wingSpeed = Number(params.wingSpeed || 1.4);
      const wingSpan = Number(params.wingSpan || 1.2);
      const t = timeState.time * wingSpeed;
      ctx.fillStyle = "#020306";
      ctx.fillRect(0, 0, width, height);
      const cx = width * 0.5 + Math.sin(t * 0.6) * (width * 0.05);
      const cy = height * 0.46 + Math.sin(t * 1.8) * 14;
      const angelScale = Math.min(width, height) / 480;
      ctx.save();
      ctx.translate(cx, cy);
      ctx.globalCompositeOperation = "screen";
      const baseHue = (195 + Math.sin(t * 0.8) * 20) % 360;
      for (let r = 0; r < BODY_RIBBONS; r++) {
        const normR = (r + 1) / BODY_RIBBONS;
        const curW = 28 * normR * angelScale;
        const curH = 115 * normR * angelScale;
        ctx.beginPath();
        ctx.moveTo(0, -65 * normR * angelScale);
        ctx.quadraticCurveTo(curW, -25 * normR * angelScale, curW * 0.7, 30 * normR * angelScale);
        ctx.quadraticCurveTo(curW * 0.3, 75 * normR * angelScale, 0, curH);
        ctx.quadraticCurveTo(-curW * 0.3, 75 * normR * angelScale, -curW * 0.7, 30 * normR * angelScale);
        ctx.quadraticCurveTo(-curW, -25 * normR * angelScale, 0, -65 * normR * angelScale);
        ctx.closePath();
        const bodyHue = (baseHue + normR * 25) % 360;
        ctx.strokeStyle = hsla(bodyHue, 95, 72, 0.06 + normR * 0.28);
        ctx.lineWidth = normR > 0.85 ? 1.6 : 0.8;
        ctx.stroke();
      }
      for (let visc = 1; visc <= 6; visc++) {
        const vR = (3 + visc * 3) * angelScale;
        ctx.beginPath();
        ctx.ellipse(0, 6 * angelScale, vR, vR * 1.3, 0, 0, Math.PI * 2);
        ctx.strokeStyle = hsla(15 + visc * 8, 100, 68, 0.6 - visc * 0.08);
        ctx.lineWidth = 1.6;
        ctx.stroke();
      }
      ctx.fillStyle = "#fee2e2";
      ctx.shadowColor = "#f97316";
      ctx.shadowBlur = 16;
      ctx.beginPath();
      ctx.arc(0, 6 * angelScale, 3 * angelScale, 0, Math.PI * 2);
      ctx.fill();
      ctx.shadowBlur = 0;
      const wingWave = Math.sin(t * 3.5);
      const wingCurl = Math.cos(t * 3.5);
      for (let s = -1; s <= 1; s += 2) {
        for (let wf = 0; wf < WING_FILAMENTS; wf++) {
          const normW = wf / (WING_FILAMENTS - 1);
          const rootX = s * (8 + normW * 14) * angelScale;
          const rootY = (-20 + normW * 12) * angelScale;
          const curSpan = (70 + normW * 25) * wingSpan * angelScale;
          const tipX = rootX + s * curSpan;
          const tipY = rootY - (10 + normW * 10) * angelScale + wingWave * (28 * angelScale);
          ctx.beginPath();
          ctx.moveTo(rootX, rootY);
          ctx.bezierCurveTo(
            rootX + s * (35 + normW * 15) * angelScale,
            rootY - 45 * angelScale + wingCurl * (18 * angelScale),
            tipX + s * 15 * angelScale,
            tipY - 25 * angelScale,
            tipX,
            tipY
          );
          ctx.bezierCurveTo(
            tipX - s * 25 * angelScale,
            tipY + 45 * angelScale,
            rootX + s * 25 * angelScale,
            rootY + 25 * angelScale,
            rootX,
            rootY + 12 * angelScale
          );
          ctx.closePath();
          const wingHue = (baseHue - 15 + normW * 35) % 360;
          ctx.strokeStyle = hsla(wingHue, 100, 78, 0.08 + normW * 0.35);
          ctx.lineWidth = wf % 4 === 0 ? 1.6 : 0.8;
          ctx.stroke();
        }
      }
      ctx.restore();
    }
  };
}

// Default parameters from content metadata
const defaultParams = [
  {
    "key": "wingSpeed",
    "label": "Parapodia Stroke Rate",
    "type": "range",
    "min": 0.5,
    "max": 2.5,
    "step": 0.1,
    "defaultValue": 1.4,
    "description": "Wing flap swimming frequency"
  },
  {
    "key": "wingSpan",
    "label": "Parapodia Wingspan",
    "type": "range",
    "min": 0.7,
    "max": 1.8,
    "step": 0.1,
    "defaultValue": 1.2,
    "description": "Flapping wing amplitude scaling"
  }
];

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

const instance = window.__art_instances['sea-angel-pteropod'];
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
zwing(u,t)=Awsin(ωwt)u+Bwcos(ωwt)u2,Ivisc(r)=I0exp(r22σv2)z_{\text{wing}}(u, t) = A_w \sin(\omega_w t) \cdot u + B_w \cos(\omega_w t) \cdot u^2, \quad I_{\text{visc}}(r) = I_0 \exp\left( -\frac{r^2}{2\sigma_v^2} \right)
Click to expand
Compact Formula
wing = bezierCurve(root, wingCurl*18, wingTip + wingWave*28), visc_core = radialGradient(5, 2, 22)

Mathematical Tags

#sea-angel #clione #pteropod #creatures #wings #pelagic #translucent
Author: Math Art Core Target: 60 FPS

Export & Embed: Pelagic Sea Angel

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/sea-angel-pteropod" 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! ✨