| .. | ||
| Inter.ttf | ||
| main.cpp | ||
| project.cpp | ||
| README.md | ||
VulkanAnimated
A live HUD demo: three Observable<float>s drive ProgressBars, three
Observable<std::string>s drive Text labels, and an FPS readout in
the corner ticks every frame. Everything updates from a single
onUpdate listener — no Invalidate() / Redraw() calls.
What it shows
Observable<T>data flow: change a value inonUpdate, the next frame'sRebuildFramere-emits the draw list with the new value automatically. No tree rebuild.ProgressBar::bindValue(obs, lo, hi)— the bar fill normalises the observable's current value into 0..1 each frame.Text::bind(observable)— the displayed string is sourced from the observable each frame, replacing any baked-in runs.- Composition pattern: a small lambda helper builds one HP/MP-style
row (
Text+ProgressBarinside anHStack) given the observables and a colour, then the row is dropped into the parentVStacklike any other widget. - Different update rates per observable:
healthoscillates at 0.7 rad/s,manaat 1.3,chargeadvances linearly modulo 1 — visible proof that each observable updates independently.
Run
cd examples/VulkanAnimated
crafter-build -r
You should see "Animated HUD" with three coloured bars (red HP, blue MP, yellow Charge) all moving at different rates, with the FPS readout in the top-right ticking once per frame.
Click Quit to exit.
Notes
The whole tick handler is just:
EventListener<FrameTime> tick(&window.onUpdate, [&](FrameTime ft){
t += ft.delta.count();
health = 0.5f + 0.5f * std::sin(t * 0.7f);
mana = std::abs(std::sin(t * 1.3f));
charge = std::fmod(t * 0.3f, 1.0f);
healthLabel = std::format("HP {:>3.0f} / 100", health.Get() * 100);
// …
});
That's the entire animation system. There is deliberately no
Animation<T> / tween primitive in the library — drive observables
from any source you like.