makara 0.2.6

A Bevy UI simplifier that make it easy to build GUI app with bevy engine.
Documentation
#import bevy_ui::ui_vertex_output::UiVertexOutput

@group(1) @binding(0)
var<uniform> u_color: vec4<f32>;

@group(1) @binding(1)
var<uniform> u_time: vec4<f32>;

@group(1) @binding(2)
var<uniform> u_percent: f32;

@group(1) @binding(3)
var<uniform> u_type: f32; // 0 = spin, 1 = percent

@group(1) @binding(4)
var<uniform> u_background_color: vec4<f32>;

@fragment
fn fragment(in: UiVertexOutput) -> @location(0) vec4<f32> {
    let uv = in.uv;
    let center = vec2(0.5, 0.5);
    let diff = uv - center;
    let dist = length(diff);

    let outer = 0.5;
    let inner = outer * 0.7; // Inner radius is 70% of outer radius
    let smoothness = 0.03;   // Fade amount for ring edges

    let fade_outer = smoothstep(outer - smoothness, outer, dist);
    let fade_inner = smoothstep(inner, inner + smoothness, dist);
    let ring_a = fade_inner * (1.0 - fade_outer); // Combined mask opacity

    if (ring_a < 0.01) {
        discard;
    }

    let pi = 3.14159265359;

    // --- Angle Calculation ---
    // raw_angle: -pi .. pi (Starts at Positive X-axis, counter-clockwise)
    let raw_angle = atan2(diff.y, diff.x);
    // angle: 0 .. 2pi (Starts at Positive X-axis, counter-clockwise)
    var angle = raw_angle + pi;


    // PERCENT MODE (u_type > 0.5) include background track
    if (u_type > 0.5) {

        // 1. ROTATE THE ANGLE
        // Shift angle by -pi/2 (90 degrees clockwise) so that 0 radians is at the TOP.
        var rotated_angle = angle - (pi * 0.5);

        // Handle wrap-around: if angle is negative, wrap it back to the [0, 2pi] range.
        if (rotated_angle < 0.0) {
            rotated_angle += 2.0 * pi;
        }

        // 2. DEFINE ARC LIMIT
        // Assumes u_percent is 0.0 to 100.0
        let limit = (u_percent / 100.0) * 2.0 * pi;

        // 3. COMPARISON and Color Selection

        // Define the final background and foreground colors (using ring_a for the mask)
        let foreground_final_color = vec4(u_color.rgb, u_color.a * ring_a);
        let background_final_color = vec4(u_background_color.rgb, u_background_color.a * ring_a);

        // Check if the pixel falls within the filled arc limit
        if (rotated_angle <= limit) {
            // Pixel is inside the filled arc
            return foreground_final_color;
        } else {
            // Pixel is outside the filled arc, render the background track color
            return background_final_color;
        }
        // Note: We no longer need 'discard' here because we are returning a color
        // for every pixel that passes the initial ring_a mask check.
    }

    //=========================
    // SPIN MODE (u_type <= 0.5)
    // Creates a fading tail that spins around the ring.
    //=========================

    let speed = -1.5;
    // Calculate the spinning position based on time and the pixel's angle.
    let spin_angle = fract((angle / (2.0 * pi)) + u_time.x * speed);

    let c_start = vec4(u_color.rgb, 1.0);// Bright part of the spinner
    let c_end = vec4(u_color.rgb, 0.2); // Faded tail/background part

    // Blend between bright and faded based on the spin position.
    let blended = mix(c_start, c_end, spin_angle);

    // Return the blended color, multiplied by the ring mask opacity.
    return vec4(blended.rgb, blended.a * ring_a);
}