Beispiel:Animation Pythagoras WAAPI.html
Aus SELFHTML-Wiki
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Pythagoras Animation mit WAAPI</title>
<style>
body {
background: #fff;
font-family: sans-serif;
}
svg {
width: min(460px, 96vw);
height:auto;
}
line, path {
fill: none;
stroke-width: 1;
stroke: rgb(0, 0, 0);
stroke-linecap: round;
stroke-linejoin: round;
transform-box: fill-box;
}
#radien path {
fill: none;
stroke: orange;
stroke-width: .5;
stroke-dasharray: 1, 2;
}
text {
fill: green;
font-family: sans-serif;
font-size: 10px;
white-space: pre;
text-anchor: middle;
}
#rechter_winkel, #zahlen, #radien {
opacity: 0;
transform-box: fill-box;
}
</style>
</head>
<body>
<p>Pythagoras WAAPI-Animation <button id="start_button" type="button">Neustart</button></p>
<svg viewBox="0 0 70 70">
<g id="radien">
<path id="radius_3" d="M 10 20 C 27 20 40 33 40 50"/>
<path id="radius_4" d="M 20 50 C 20 28 38 10 60 10"/>
</g>
<line id="linie_5" style="transform-origin: 50% 50%;" x1="10" y1="-10" x2="60" y2="-10"/>
<line id="linie_4" style="transform-origin: 100% 50%;" x1="10" y1="-20" x2="50" y2="-20"/>
<line id="linie_3" style="transform-origin: 0% 100%;" x1="10" y1="-30" x2="40" y2="-30"/>
<g id="rechter_winkel" style="transform-origin: 100% 100%;">
<path style="fill: none; stroke: green; transform-box: fill-box;" d="M 9 19 C 9 13 13 9 19 9"/>
<circle style="fill: green; stroke: none;" cx="15" cy="15" r="2"/>
</g>
<g id="zahlen">
<text x="34" y="60" style="white-space: pre;">5</text>
<text x="6" y="40" style="white-space: pre; font-size: 10px;">3</text>
<text x="64" y="40" style="white-space: pre; font-size: 10px;">4</text>
</g>
</svg>
<script>
document.addEventListener('DOMContentLoaded', function () {
const ms = s => Math.round(s * 1000);
const el = (id) => document.getElementById(id);
const T = (x,y) => `translate(${x}px, ${y}px)`;
const R = (deg) => `rotate(${deg}deg)`;
const startBtn = el("start_button");
let running = [];
const cancelAll = () => {
for (const a of running) {
a.cancel();
}
running = [];
};
const setButtonEnabled = (enabled) => {
if (!startBtn) return;
startBtn.disabled = !enabled;
startBtn.setAttribute("aria-disabled", String(!enabled));
};
const startAnimation = () => {
setButtonEnabled(false);
cancelAll();
const animations = [];
animations.push(
el("linie_5").animate(
[{ transform: T(0,0) }, { transform: T(0,60) }],
{ duration: ms(2), delay: ms(0), fill: "forwards", easing: "ease-in" }
)
);
const line4KF = [
{ t: 0.0, tx: 0, ty: 0, rotA: 0, rotB: 0 },
{ t: 2.0, tx: 5, ty: 35, rotA: 0, rotB: 0 },
{ t: 4.0, tx: 10, ty: 70, rotA: 90, rotB: 0 },
{ t: 6.5, tx: 10, ty: 70, rotA: 90, rotB: 0 },
{ t: 7.4, tx: 10, ty: 70, rotA: 90, rotB: -66 },
{ t: 8.3, tx: 10, ty: 70, rotA: 90, rotB: -39 },
{ t: 9.5, tx: 10, ty: 70, rotA: 90, rotB: -53.13 },
];
animations.push(
el("linie_4").animate(
line4KF.map(k => ({
transform: `${T(k.tx, k.ty)} ${R(k.rotA + k.rotB)}`,
offset: k.t / 9.5
})),
{ duration: ms(9.5), delay: 0, fill: "forwards", easing: "linear" }
)
);
const line3KF = [
{ t: 0.0, tx: 0, ty: 0, rotA: 0, rotB: 0 },
{ t: 2.0, tx: 0, ty: 0, rotA: 0, rotB: 0 },
{ t: 2.8, tx: 0, ty: 21, rotA: 0, rotB: 0 },
{ t: 5.0, tx: 0, ty: 80, rotA: -90, rotB: 0 },
{ t: 6.0, tx: 0, ty: 80, rotA: -90, rotB: 0 },
{ t: 7.2, tx: 0, ty: 80, rotA: -90, rotB: 50 },
{ t: 8.4, tx: 0, ty: 80, rotA: -90, rotB: 21 },
{ t: 10.0, tx: 0, ty: 80, rotA: -90, rotB: 36.87 },
];
animations.push(
el("linie_3").animate(
line3KF.map(k => ({
transform: `${T(k.tx, k.ty)} ${R(k.rotA + k.rotB)}`,
offset: k.t / 10.0
})),
{ duration: ms(10), delay: 0, fill: "forwards", easing: "linear" }
)
);
animations.push(
el("zahlen").animate(
[{ opacity: 0 }, { opacity: 1 }],
{ duration: ms(2), delay: ms(5), fill: "forwards", easing: "linear" }
)
);
const radien = el("radien");
animations.push(
radien.animate(
[{ opacity: 0 }, { opacity: 1 }],
{ duration: ms(0.95), delay: ms(5.52), fill: "forwards", easing: "linear" }
)
);
animations.push(
radien.animate(
[{ opacity: 1 }, { opacity: 0 }],
{ duration: ms(0.98), delay: ms(10.01), fill: "forwards", easing: "linear" }
)
);
const rw = el("rechter_winkel");
rw.style.transformBox = "fill-box";
rw.style.transformOrigin = "100% 100%";
animations.push(
rw.animate(
[{ opacity: 0 }, { opacity: 1 }],
{ duration: ms(2), delay: ms(10), fill: "forwards", easing: "linear" }
)
);
animations.push(
rw.animate(
[
{ transform: `${R(0)} ${T(0,0)}` },
{ transform: `${R(-142)} ${T(-12,0)}` }
],
{ duration: ms(2), delay: ms(10), fill: "forwards", easing: "linear" }
)
);
running = animations;
Promise.allSettled(animations.map(a => a.finished)).then(() => {
if (running === animations) setButtonEnabled(true);
});
};
if (startBtn) setButtonEnabled(false);
if (startBtn) {
startBtn.addEventListener("pointerup", (e) => {
e.preventDefault();
startAnimation();
});
startBtn.addEventListener("click", (e) => {
e.preventDefault();
startAnimation();
});
}
startAnimation();
});
</script>
</body>
</html>