Skip to content

Instantly share code, notes, and snippets.

@segmond
Created May 20, 2026 12:02
Show Gist options
  • Select an option

  • Save segmond/d55f07c22d54badc8042a7c8b3785dbb to your computer and use it in GitHub Desktop.

Select an option

Save segmond/d55f07c22d54badc8042a7c8b3785dbb to your computer and use it in GitHub Desktop.
3 little pigs kimi
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three Little Pigs - Cartoon</title>
<style>
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background: #2c3e50;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
svg {
width: 100vw;
height: 100vh;
display: block;
}
</style>
</head>
<body>
<svg viewBox="0 0 800 500" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="skyGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#87CEEB"/>
<stop offset="100%" stop-color="#E0F7FA"/>
</linearGradient>
</defs>
<!-- Sky & Sun -->
<rect width="800" height="500" fill="url(#skyGrad)"/>
<circle cx="720" cy="60" r="40" fill="#FFD700" opacity="0.9"/>
<circle cx="720" cy="60" r="50" fill="#FFD700" opacity="0.3"/>
<!-- Clouds -->
<g id="cloud1" opacity="0.9">
<ellipse cx="0" cy="0" rx="30" ry="14" fill="#fff"/>
<ellipse cx="22" cy="-6" rx="24" ry="18" fill="#fff"/>
<ellipse cx="-22" cy="-6" rx="24" ry="18" fill="#fff"/>
</g>
<g id="cloud2" opacity="0.8">
<ellipse cx="0" cy="0" rx="26" ry="12" fill="#fff"/>
<ellipse cx="18" cy="-4" rx="22" ry="16" fill="#fff"/>
<ellipse cx="-18" cy="-4" rx="22" ry="16" fill="#fff"/>
</g>
<!-- Ground -->
<rect x="0" y="350" width="800" height="150" fill="#7CFC00"/>
<path d="M0,350 Q200,340 400,350 T800,350 V500 H0 Z" fill="#32CD32"/>
<!-- ================= HOUSES ================= -->
<!-- Straw House -->
<g id="houseStraw" transform="translate(150,350) scale(0)">
<rect x="-45" y="-50" width="90" height="50" fill="#FFD700" stroke="#DAA520" stroke-width="2"/>
<path d="M-55,-50 L0,-95 L55,-50 Z" fill="#F0E68C" stroke="#DAA520" stroke-width="2"/>
<line x1="-35" y1="-40" x2="35" y2="-40" stroke="#DAA520"/>
<line x1="-35" y1="-25" x2="35" y2="-25" stroke="#DAA520"/>
<line x1="-35" y1="-10" x2="35" y2="-10" stroke="#DAA520"/>
<rect x="-12" y="-25" width="24" height="25" fill="#8B4513" rx="3"/>
</g>
<!-- Stick House -->
<g id="houseSticks" transform="translate(400,350) scale(0)">
<rect x="-45" y="-50" width="90" height="50" fill="#DEB887" stroke="#8B4513" stroke-width="2"/>
<path d="M-55,-50 L0,-95 L55,-50 Z" fill="#D2691E" stroke="#8B4513" stroke-width="2"/>
<line x1="-35" y1="-45" x2="-30" y2="-5" stroke="#8B4513" stroke-width="2"/>
<line x1="-15" y1="-45" x2="-10" y2="-5" stroke="#8B4513" stroke-width="2"/>
<line x1="5" y1="-45" x2="10" y2="-5" stroke="#8B4513" stroke-width="2"/>
<line x1="25" y1="-45" x2="30" y2="-5" stroke="#8B4513" stroke-width="2"/>
<line x1="-40" y1="-25" x2="40" y2="-20" stroke="#8B4513" stroke-width="2"/>
<rect x="-12" y="-25" width="24" height="25" fill="#5D4037" rx="3"/>
</g>
<!-- Brick House -->
<g id="houseBrick" transform="translate(650,350) scale(0)">
<rect x="-50" y="-60" width="100" height="60" fill="#B22222" stroke="#8B0000" stroke-width="2"/>
<path d="M-60,-60 L0,-110 L60,-60 Z" fill="#CD5C5C" stroke="#8B0000" stroke-width="2"/>
<line x1="-50" y1="-45" x2="50" y2="-45" stroke="#8B0000" stroke-width="1"/>
<line x1="-50" y1="-30" x2="50" y2="-30" stroke="#8B0000" stroke-width="1"/>
<line x1="-50" y1="-15" x2="50" y2="-15" stroke="#8B0000" stroke-width="1"/>
<line x1="-25" y1="-60" x2="-25" y2="-45" stroke="#8B0000" stroke-width="1"/>
<line x1="0" y1="-60" x2="0" y2="-45" stroke="#8B0000" stroke-width="1"/>
<line x1="25" y1="-60" x2="25" y2="-45" stroke="#8B0000" stroke-width="1"/>
<line x1="-40" y1="-45" x2="-40" y2="-30" stroke="#8B0000" stroke-width="1"/>
<line x1="-15" y1="-45" x2="-15" y2="-30" stroke="#8B0000" stroke-width="1"/>
<line x1="15" y1="-45" x2="15" y2="-30" stroke="#8B0000" stroke-width="1"/>
<line x1="40" y1="-45" x2="40" y2="-30" stroke="#8B0000" stroke-width="1"/>
<!-- Chimney -->
<rect x="25" y="-130" width="20" height="40" fill="#B22222" stroke="#8B0000"/>
<rect x="20" y="-135" width="30" height="8" fill="#CD5C5C" stroke="#8B0000"/>
<rect x="-12" y="-25" width="24" height="25" fill="#5D4037" rx="3"/>
</g>
<!-- ================= WOLF ================= -->
<g id="wolf" transform="translate(-120,360)">
<ellipse cx="0" cy="22" rx="18" ry="13" fill="#808080"/>
<circle cx="0" cy="0" r="13" fill="#808080"/>
<polygon points="-8,-8 -15,-18 -6,-10" fill="#808080"/>
<polygon points="8,-8 15,-18 6,-10" fill="#808080"/>
<ellipse cx="10" cy="0" rx="10" ry="7" fill="#696969"/>
<circle cx="17" cy="-1" r="1.5" fill="#111"/>
<circle cx="-4" cy="-3" r="1.8" fill="#FFD700"/>
<circle cx="-4" cy="-3" r="0.7" fill="#111"/>
<path d="M-18,22 Q-28,30 -24,40" stroke="#696969" stroke-width="2.5" fill="none"/>
<line x1="-16" y1="22" x2="-16" y2="32" stroke="#696969" stroke-width="3" stroke-linecap="round"/>
<line x1="16" y1="22" x2="16" y2="32" stroke="#696969" stroke-width="3" stroke-linecap="round"/>
</g>
<!-- ================= PIGS ================= -->
<!-- Pig 1 -->
<g id="pig1" transform="translate(150,360)">
<ellipse cx="0" cy="18" rx="14" ry="10" fill="#FFB6C1"/>
<circle cx="0" cy="0" r="11" fill="#FFB6C1"/>
<polygon points="-7,-6 -11,-14 -4,-8" fill="#FFB6C1"/>
<polygon points="7,-6 11,-14 4,-8" fill="#FFB6C1"/>
<ellipse cx="0" cy="2" rx="5" ry="3" fill="#FF69B4"/>
<circle cx="-2" cy="2" r="0.8" fill="#333"/>
<circle cx="2" cy="2" r="0.8" fill="#333"/>
<circle cx="-4" cy="-2" r="1.2" fill="#111"/>
<circle cx="4" cy="-2" r="1.2" fill="#111"/>
<line x1="-14" y1="18" x2="-14" y2="26" stroke="#FFB6C1" stroke-width="3" stroke-linecap="round"/>
<line x1="14" y1="18" x2="14" y2="26" stroke="#FFB6C1" stroke-width="3" stroke-linecap="round"/>
</g>
<!-- Pig 2 -->
<g id="pig2" transform="translate(400,360)">
<ellipse cx="0" cy="18" rx="14" ry="10" fill="#FFB6C1"/>
<circle cx="0" cy="0" r="11" fill="#FFB6C1"/>
<polygon points="-7,-6 -11,-14 -4,-8" fill="#FFB6C1"/>
<polygon points="7,-6 11,-14 4,-8" fill="#FFB6C1"/>
<ellipse cx="0" cy="2" rx="5" ry="3" fill="#FF69B4"/>
<circle cx="-2" cy="2" r="0.8" fill="#333"/>
<circle cx="2" cy="2" r="0.8" fill="#333"/>
<circle cx="-4" cy="-2" r="1.2" fill="#111"/>
<circle cx="4" cy="-2" r="1.2" fill="#111"/>
<line x1="-14" y1="18" x2="-14" y2="26" stroke="#FFB6C1" stroke-width="3" stroke-linecap="round"/>
<line x1="14" y1="18" x2="14" y2="26" stroke="#FFB6C1" stroke-width="3" stroke-linecap="round"/>
</g>
<!-- Pig 3 -->
<g id="pig3" transform="translate(650,360)">
<ellipse cx="0" cy="18" rx="14" ry="10" fill="#FFB6C1"/>
<circle cx="0" cy="0" r="11" fill="#FFB6C1"/>
<polygon points="-7,-6 -11,-14 -4,-8" fill="#FFB6C1"/>
<polygon points="7,-6 11,-14 4,-8" fill="#FFB6C1"/>
<ellipse cx="0" cy="2" rx="5" ry="3" fill="#FF69B4"/>
<circle cx="-2" cy="2" r="0.8" fill="#333"/>
<circle cx="2" cy="2" r="0.8" fill="#333"/>
<circle cx="-4" cy="-2" r="1.2" fill="#111"/>
<circle cx="4" cy="-2" r="1.2" fill="#111"/>
<line x1="-14" y1="18" x2="-14" y2="26" stroke="#FFB6C1" stroke-width="3" stroke-linecap="round"/>
<line x1="14" y1="18" x2="14" y2="26" stroke="#FFB6C1" stroke-width="3" stroke-linecap="round"/>
</g>
<!-- ================= EFFECTS ================= -->
<g id="wind" opacity="0">
<path d="M0,0 Q15,-5 30,0 M5,10 Q20,5 40,10 M2,20 Q18,15 35,20" stroke="#E0F7FA" stroke-width="4" fill="none" stroke-linecap="round"/>
<path d="M0,0 Q15,-5 30,0 M5,10 Q20,5 40,10 M2,20 Q18,15 35,20" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/>
</g>
<g id="smoke" opacity="0" transform="translate(685,215)">
<circle cx="0" cy="0" r="10" fill="#555" opacity="0.7"/>
<circle cx="10" cy="-8" r="8" fill="#777" opacity="0.6"/>
<circle cx="-6" cy="-14" r="6" fill="#999" opacity="0.5"/>
</g>
<!-- ================= TEXT ================= -->
<text id="narrator" x="400" y="45" text-anchor="middle" font-family="Comic Sans MS, cursive, sans-serif" font-size="18" fill="#2c3e50" opacity="0">Once upon a time...</text>
<text id="endText" x="400" y="260" text-anchor="middle" font-family="Comic Sans MS, cursive, sans-serif" font-size="52" fill="#D32F2F" opacity="0" font-weight="bold">The End</text>
</svg>
<script>
(() => {
// Elements
const E = {
hStraw: document.getElementById('houseStraw'),
hSticks: document.getElementById('houseSticks'),
hBrick: document.getElementById('houseBrick'),
pig1: document.getElementById('pig1'),
pig2: document.getElementById('pig2'),
pig3: document.getElementById('pig3'),
wolf: document.getElementById('wolf'),
wind: document.getElementById('wind'),
smoke: document.getElementById('smoke'),
narrator: document.getElementById('narrator'),
endText: document.getElementById('endText'),
cloud1: document.getElementById('cloud1'),
cloud2: document.getElementById('cloud2')
};
// Helpers
function setTF(el, str) { el.setAttribute('transform', str); }
function setOp(el, val) { el.setAttribute('opacity', val); }
function animate(duration, draw) {
return new Promise(resolve => {
const start = performance.now();
function frame(now) {
const t = Math.min((now - start) / duration, 1);
const e = t < 0.5 ? 2*t*t : -1 + (4 - 2*t) * t; // easeInOutQuad
draw(e, t);
if (t < 1) requestAnimationFrame(frame);
else resolve();
}
requestAnimationFrame(frame);
});
}
function wait(ms) { return new Promise(r => setTimeout(r, ms)); }
let narrateTimer = null;
function narrate(text, stay = 1800) {
E.narrator.textContent = text;
animate(300, (e,t) => setOp(E.narrator, t));
if (narrateTimer) clearTimeout(narrateTimer);
narrateTimer = setTimeout(() => {
animate(400, (e,t) => setOp(E.narrator, 1-e));
}, stay);
}
// Ambient drifting clouds
function ambientLoop() {
const now = performance.now();
setTF(E.cloud1, `translate(${120 + Math.sin(now/9000)*40}, 80)`);
setTF(E.cloud2, `translate(${520 + Math.sin(now/11000)*30}, 130)`);
requestAnimationFrame(ambientLoop);
}
ambientLoop();
// ================= SCENES =================
async function scene1_Build() {
narrate("The Three Little Pigs built three houses...", 2500);
await animate(800, (e,t) => setTF(E.hStraw, `translate(150,350) scale(${e})`));
await animate(400, (e,t) => {
const y = 360 - Math.sin(e*Math.PI)*18;
setTF(E.pig1, `translate(150,${y})`);
});
await animate(800, (e,t) => setTF(E.hSticks, `translate(400,350) scale(${e})`));
await animate(400, (e,t) => {
const y = 360 - Math.sin(e*Math.PI)*18;
setTF(E.pig2, `translate(400,${y})`);
});
await animate(1200, (e,t) => setTF(E.hBrick, `translate(650,350) scale(${e})`));
await animate(400, (e,t) => {
const y = 360 - Math.sin(e*Math.PI)*18;
setTF(E.pig3, `translate(650,${y})`);
});
await wait(600);
}
async function scene2_Straw() {
narrate("The Big Bad Wolf came to the straw house...", 2200);
// Wolf arrives
await animate(1200, (e,t) => setTF(E.wolf, `translate(${-120 + 270*e},360)`));
narrate("Little pigs, let me in! I'll huff and I'll puff!", 2000);
await wait(600);
// Blow wind + shake house
setOp(E.wind, 1);
await Promise.all([
animate(1500, (e,t) => {
setTF(E.wind, `translate(${180 + 60*e},350)`);
setOp(E.wind, 1 - e*0.3);
}),
animate(1500, (e,t) => {
const shake = Math.sin(e * 40) * 14 * (1 - e*0.6);
setTF(E.hStraw, `translate(150,350) rotate(${shake})`);
})
]);
// Collapse
await animate(600, (e,t) => {
setTF(E.hStraw, `translate(150,350) scale(${1-e}) rotate(${25*e})`);
setOp(E.hStraw, Math.max(0, 1 - e));
});
// Pig1 flees to stick house
await animate(1000, (e,t) => {
const x = 150 + 240*e;
const y = 360 - Math.abs(Math.sin(e*12))*12;
setTF(E.pig1, `translate(${x},${y})`);
});
setTF(E.pig1, `translate(390,360)`);
setOp(E.wind, 0);
}
async function scene3_Sticks() {
narrate("The wolf huffed and puffed at the stick house...", 2200);
await animate(1200, (e,t) => setTF(E.wolf, `translate(${150 + 250*e},360)`));
setOp(E.wind, 1);
await Promise.all([
animate(1500, (e,t) => {
setTF(E.wind, `translate(${430 + 60*e},350)`);
setOp(E.wind, 1 - e*0.3);
}),
animate(1500, (e,t) => {
const shake = Math.sin(e * 50) * 18 * (1 - e*0.6);
setTF(E.hSticks, `translate(400,350) rotate(${shake})`);
})
]);
// Collapse sticks
await animate(600, (e,t) => {
setTF(E.hSticks, `translate(400,350) scale(${1-e}) rotate(${-25*e})`);
setOp(E.hSticks, Math.max(0, 1 - e));
});
// Both pigs flee to brick house
await Promise.all([
animate(1000, (e,t) => {
const x = 390 + 240*e;
const y = 360 - Math.abs(Math.sin(e*12))*12;
setTF(E.pig1, `translate(${x},${y})`);
}),
animate(1000, (e,t) => {
const x = 400 + 240*e;
const y = 360 - Math.abs(Math.sin(e*12 + 1))*12;
setTF(E.pig2, `translate(${x},${y})`);
})
]);
setTF(E.pig1, `translate(630,360)`);
setTF(E.pig2, `translate(670,360)`);
setOp(E.wind, 0);
}
async function scene4_Brick() {
narrate("Then he came to the strong brick house...", 2200);
await animate(1200, (e,t) => setTF(E.wolf, `translate(${400 + 250*e},360)`));
// Blow hard
setOp(E.wind, 1);
await Promise.all([
animate(2000, (e,t) => {
setTF(E.wind, `translate(${680 + 50*e},350)`);
setOp(E.wind, 1 - e*0.3);
}),
animate(2000, (e,t) => {
const shake = Math.sin(e * 60) * 5 * (1 - e*0.8);
setTF(E.hBrick, `translate(650,350) rotate(${shake})`);
})
]);
setOp(E.wind, 0);
narrate("But the house would not fall!", 1500);
await wait(400);
// Wolf frustration jump
await animate(500, (e,t) => {
const y = 360 - Math.sin(e*Math.PI)*25;
setTF(E.wolf, `translate(650,${y})`);
});
narrate("So he climbed down the chimney...", 1500);
// Climb to chimney top
await animate(800, (e,t) => {
const x = 650 + 35*e;
const y = 360 - 100*e;
setTF(E.wolf, `translate(${x},${y})`);
});
// Drop down chimney & disappear
await animate(800, (e,t) => {
const y = 260 + 150*e;
const s = 1 - e;
setTF(E.wolf, `translate(685,${y}) scale(${s})`);
setOp(E.wolf, 1 - e);
});
// Smoke puff out of chimney
setOp(E.smoke, 1);
await animate(1000, (e,t) => {
setTF(E.smoke, `translate(685,215) scale(${1 + e*1.5})`);
setOp(E.smoke, 1 - e);
});
setOp(E.smoke, 0);
setOp(E.wolf, 0);
}
async function scene5_End() {
narrate("And the wolf was never seen again!", 2500);
// Celebration dance
await animate(2000, (e,t) => {
const y1 = 360 - Math.abs(Math.sin(e*10))*16;
const y2 = 360 - Math.abs(Math.sin(e*10 + 2))*16;
const y3 = 360 - Math.abs(Math.sin(e*10 + 4))*16;
setTF(E.pig1, `translate(630,${y1})`);
setTF(E.pig2, `translate(670,${y2})`);
setTF(E.pig3, `translate(650,${y3})`);
});
// The End
await animate(1200, (e,t) => setOp(E.endText, t));
await wait(1500);
}
// ================= RUN STORY =================
async function runStory() {
await scene1_Build();
await scene2_Straw();
await scene3_Sticks();
await scene4_Brick();
await scene5_End();
}
// Start after brief pause
setTimeout(runStory, 500);
})();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment