pane_ui 0.1.0

A RON-driven, hot-reloadable wgpu UI library with spring animations and consistent scaling
Documentation
struct Globals {
    time:           f32,
    dt:             f32,
    frame:          f32,
    cursor_x:       f32,
    cursor_y:       f32,
    cursor_pressed: f32,
    _pad0:          f32,
    _pad1:          f32,
}
@group(1) @binding(0) var<uniform> globals: Globals;

struct VertexInput {
    @location(0) pos:         vec2<f32>,
    @location(1) uv:          vec2<f32>,
    @location(2) color:       vec4<f32>,
    @location(3) cr:          vec2<f32>,
    @location(4) widget_size: vec2<f32>,
    @location(5) state:       vec4<f32>,
}
struct VertexOutput {
    @builtin(position) clip_pos:    vec4<f32>,
    @location(0)       color:       vec4<f32>,
    @location(1)       uv:          vec2<f32>,
    @location(2)       cr:          vec2<f32>,
    @location(3)       widget_size: vec2<f32>,
    @location(4)       state:       vec4<f32>,
}
@vertex fn vs(in: VertexInput) -> VertexOutput {
    var out: VertexOutput;
    out.clip_pos    = vec4(in.pos, 0.0, 1.0);
    out.color       = in.color;
    out.uv          = in.uv;
    out.cr          = in.cr;
    out.widget_size = in.widget_size;
    out.state       = in.state;
    return out;
}
@fragment fn fs(in: VertexOutput) -> @location(0) vec4<f32> {
    let uv    = in.uv;
    let px    = fwidth(uv);
    let r_px  = in.cr.x;

    // Work in pixel space so the SDF is correct for any aspect ratio,
    // including very thin rects (dividers, progress bars, etc.)
    let rw_px = 1.0 / max(px.x, 0.0001);
    let rh_px = 1.0 / max(px.y, 0.0001);
    let sx    = (uv.x - 0.5) * rw_px;
    let sy    = (uv.y - 0.5) * rh_px;
    let qx    = abs(sx) - (rw_px * 0.5 - r_px);
    let qy    = abs(sy) - (rh_px * 0.5 - r_px);
    let dist  = length(max(vec2(qx, qy), vec2(0.0))) + min(max(qx, qy), 0.0) - r_px;
    let alpha = 1.0 - smoothstep(-0.5, 0.5, dist);

    var col = in.color;
    col.a  *= alpha;
    return col;
}