Giant Praya Siphonophore
Deep ocean Praya dubia siphonophore colony modeled as a 3D helical coenosarc stem of swimming nectophores with trailing bioluminescent red/blue tentilla fishing lattices.
60 FPS • Canvas 2D
Click + Drag to interact with field
</>
Full Executable Algorithm Code
138 lines
5046 chars
// 045 - Giant Praya Siphonophore (creatures)
// 1:1 Original algorithm engine source
function createGiantSiphonophore() {
const STEM_FILAMENTS = 36;
const TENTILLA_COUNT = 80;
return {
setup() {
},
render(context, timeState, params) {
const { ctx, width, height } = context;
const waveSpeed = Number(params.flowSpeed || 0.9);
const chainLength = Number(params.chainSpread || 1.1);
const t = timeState.time * waveSpeed;
ctx.fillStyle = "#020306";
ctx.fillRect(0, 0, width, height);
const cx = width * 0.5;
const cy = height * 0.5;
const scale = Math.min(width, height) * 0.42 * chainLength;
ctx.save();
ctx.globalCompositeOperation = "screen";
for (let f = 0; f < STEM_FILAMENTS; f++) {
const normF = f / (STEM_FILAMENTS - 1);
const phaseOffset = normF * Math.PI * 2;
const stemRadius = scale * 0.32 * (0.8 + 0.4 * Math.sin(normF * Math.PI));
ctx.beginPath();
const steps = 65;
for (let i = 0; i <= steps; i++) {
const normI = i / steps;
const theta = normI * Math.PI * 3.8 + t * 0.8 + phaseOffset;
const waveX = Math.sin(t * 1.4 + normI * 5 + normF * 2) * 22;
const sx = cx + (normI - 0.5) * scale * 1.85 + waveX;
const sy = cy + Math.sin(theta) * stemRadius;
if (i === 0) ctx.moveTo(sx, sy);
else ctx.lineTo(sx, sy);
}
const stemHue = (180 + normF * 45 + Math.sin(t * 0.5) * 20) % 360;
ctx.strokeStyle = hsla(stemHue, 95, 70, 0.25);
ctx.lineWidth = f % 4 === 0 ? 1.6 : 0.8;
ctx.stroke();
}
const NODE_COUNT = 18;
const stemNodes = [];
for (let n = 0; n < NODE_COUNT; n++) {
const normN = n / (NODE_COUNT - 1);
const theta = normN * Math.PI * 3.8 + t * 0.8;
const nx = cx + (normN - 0.5) * scale * 1.85 + Math.sin(t * 1.4 + normN * 5) * 22;
const ny = cy + Math.sin(theta) * (scale * 0.32);
stemNodes.push({ x: nx, y: ny });
const pulse = 1 + 0.28 * Math.sin(t * 3.5 - n * 0.4);
for (let ring = 1; ring <= 3; ring++) {
ctx.beginPath();
ctx.arc(nx, ny, (4 + ring * 3.5) * pulse, 0, Math.PI * 2);
ctx.strokeStyle = hsla(185 + ring * 10, 95, 75, 0.5 - ring * 0.1);
ctx.lineWidth = 1;
ctx.stroke();
}
const isRed = n % 3 === 0;
const pColor = isRed ? "#ef4444" : "#38bdf8";
ctx.fillStyle = pColor;
ctx.shadowColor = pColor;
ctx.shadowBlur = 10;
ctx.beginPath();
ctx.arc(nx, ny, 2.5, 0, Math.PI * 2);
ctx.fill();
ctx.shadowBlur = 0;
}
for (let k = 0; k < TENTILLA_COUNT; k++) {
const normK = k / (TENTILLA_COUNT - 1);
const parentIdx = Math.floor(normK * (stemNodes.length - 1));
const root = stemNodes[parentIdx];
ctx.beginPath();
ctx.moveTo(root.x, root.y);
const tentSteps = 32;
const maxDrop = 160 * chainLength;
for (let s = 1; s <= tentSteps; s++) {
const ns = s / tentSteps;
const w1 = Math.sin(t * 2.8 - ns * 7 + k * 0.3) * (20 * ns);
const w2 = Math.cos(t * 1.8 + ns * 14 - k * 0.2) * (10 * ns);
const tx = root.x + w1 + w2;
const ty = root.y + ns * maxDrop;
ctx.lineTo(tx, ty);
if (s % 6 === 0) {
const isRedSpark = (k + s) % 4 === 0;
ctx.fillStyle = isRedSpark ? "rgba(239, 68, 68, 0.85)" : "rgba(56, 189, 248, 0.85)";
ctx.fillRect(tx - 1, ty - 1, 2, 2);
}
}
const tentHue = (180 + normK * 50 + t * 15) % 360;
ctx.strokeStyle = hsla(tentHue, 95, 75, k % 3 === 0 ? 0.55 : 0.22);
ctx.lineWidth = k % 3 === 0 ? 1.2 : 0.7;
ctx.stroke();
}
ctx.restore();
}
};
}
// Default parameters from content metadata
const defaultParams = [
{
"key": "flowSpeed",
"label": "Abyssal Drift Velocity",
"type": "range",
"min": 0.3,
"max": 2.5,
"step": 0.1,
"defaultValue": 0.9,
"description": "Colony swimming undulation speed"
},
{
"key": "chainSpread",
"label": "Colony Extension",
"type": "range",
"min": 0.6,
"max": 1.6,
"step": 0.1,
"defaultValue": 1.1,
"description": "Coenosarc stem span scaling"
}
];
if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['giant-siphonophore']) {
const inst = typeof createGiantSiphonophore === 'function' ? createGiantSiphonophore() : null;
if (inst && inst.setup) {
inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
}
window.__art_instances['giant-siphonophore'] = inst;
}
const instance = window.__art_instances['giant-siphonophore'];
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
high
Analytical Equation
rstem(s,t)=sLRssin(4πs+ω1t)Rscos(4πs+ω1t),ptentilla(s,u,t)=rstem(s)+[Awsin(ω2t−ku)uH]
Click to expand
∑
Giant Praya Siphonophore
Full Mathematical System • creatures
100%
Complete System of Equations
[Governing Law][Discrete Progression][Domain & Space][Parameter State]rstem(s,t)=sLRssin(4πs+ω1t)Rscos(4πs+ω1t),ptentilla(s,u,t)=rstem(s)+[Awsin(ω2t−ku)uH]stem=[s⋅L+sin(1.2t+4s)⋅25,sin(4πs+0.8t)⋅R],tentilla=[stem.x+sin(2.5t−6u)⋅15u,stem.y+u⋅H]x∈R2,t∈R+,ω∈[0,2π]λflowSpeed=0.9(Abyssal Drift Velocity),λchainSpread=1.1(Colony Extension)
rstem(s,t)=sLRssin(4πs+ω1t)Rscos(4πs+ω1t),ptentilla(s,u,t)=rstem(s)+[Awsin(ω2t−ku)uH]
Computational Implementation (JavaScript Engine Equivalent)
stem = [s*L + sin(1.2t + 4s)*25, sin(4πs + 0.8t)*R], tentilla = [stem.x + sin(2.5t - 6u)*15u, stem.y + u*H] Compact Formula
stem = [s*L + sin(1.2t + 4s)*25, sin(4πs + 0.8t)*R], tentilla = [stem.x + sin(2.5t - 6u)*15u, stem.y + u*H] Mathematical Tags
#siphonophore
#deep-sea
#abyss
#creatures
#colonial
#bioluminescence
#helix
Author: Math Art Core Target: 60 FPS
Press ESC or F to exit