Create a fading animation using cairo.h

Viewed 31

i'm trying to make a function that can switch a window from dark mode to light mode and vice-versa. I managed to do it but now i want to add a sort of transition to the colors, where the white gets darker, and the grey gets lighter.

I've got this so far:

void paint_fade(cairo_surface_t* surface){

    cairo_t*cr=cairo_create(surface);

    if(darkmode){
        for(int i=1; i>0.2; i-=0.005){
            cairo_set_source_rgb(cr, i, i, i);
            cairo_rectangle(cr, 0, GUI_Y, getX_SizeWindow(), getY_SizeWindow()-GUI_Y);
            cairo_fill(cr);
            sleep(0.1);
        }
    }
    else{
        for(int i=0.2; i<1; i+=0.005){
            cairo_set_source_rgb(cr, i, i, i);
            cairo_rectangle(cr, 0, GUI_Y, getX_SizeWindow(), getY_SizeWindow()-GUI_Y);
            cairo_fill(cr);
            sleep(0.1);
        }
    }

    cairo_destroy(cr); 
}

But this doesn't seem like it works, does anyone know why?

1 Answers

Pango does not update the contents of the window immediately. It waits till it is in the main event loop. Your requests are put in a queue, and that queue can only by processed in the event loop.

To fix this, include GTK+, if you have not already, and put that code inside of a timout. Then you will have to use static variables so you can save you variables state from timeout call to call. Here is a possible revision:

void paint_fade(cairo_surface_t* surface){

    static cairo_t* cr = cairo_create(surface);
    static int i = 1;
    if(darkmode){
       i-=0.005;
       cairo_set_source_rgb(cr, i, i, i);
       cairo_rectangle(cr, 0, GUI_Y, getX_SizeWindow(), 
       getY_SizeWindow()-GUI_Y);
       cairo_fill(cr);
       if ( i <= 0.2) {
         cairo_destroy(cr);
         return FALSE; // Abort the timeout.
       }
    }
    else
    {
        i+=0.005
        cairo_set_source_rgb(cr, i, i, i);
        cairo_rectangle(cr, 0, GUI_Y, getX_SizeWindow(), 
        getY_SizeWindow()-GUI_Y);
        cairo_fill(cr);
        if (i => 1) {
          cairo_destroy(cr);
          return FALSE; // Abort the timeout.
        }
    }
    return TRUE;

}
Related