spinner
Parameters
- src:std.builtin.SourceLocation
- std.builtin.SourceLocation
- opts:Options
- Options
Source
Implementation
pub fn spinner(src: std.builtin.SourceLocation, opts: Options) void {
var defaults: Options = .{
.name = "Spinner",
.min_size_content = .{ .w = 50, .h = 50 },
};
const options = defaults.override(opts);
var wd = WidgetData.init(src, .{}, options);
wd.register();
wd.minSizeSetAndRefresh();
wd.minSizeReportToParent();
if (wd.rect.empty()) {
return;
}
const rs = wd.contentRectScale();
const r = rs.r;
var t: f32 = 0;
const anim = Animation{ .end_time = 3_000_000 };
if (animationGet(wd.id, "_t")) |a| {
// existing animation
var aa = a;
if (aa.done()) {
// this animation is expired, seamlessly transition to next animation
aa = anim;
aa.start_time = a.end_time;
aa.end_time += a.end_time;
animation(wd.id, "_t", aa);
}
t = aa.value();
} else {
// first frame we are seeing the spinner
animation(wd.id, "_t", anim);
}
var path: Path.Builder = .init(dvui.currentWindow().lifo());
defer path.deinit();
const full_circle = 2 * std.math.pi;
// start begins fast, speeding away from end
const start = full_circle * easing.outSine(t);
// end begins slow, catching up to start
const end = full_circle * easing.inSine(t);
path.addArc(r.center(), @min(r.w, r.h) / 3, start, end, false);
path.build().stroke(.{ .thickness = 3.0 * rs.s, .color = options.color(.text) });
}