diff --git a/src/vte.cc b/src/vte.cc
index 8d97e1c..80981d4 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8598,17 +8598,20 @@ VteTerminalPrivate::draw_cells(struct _vte_draw_text_request *items,
         if (blink) {
                 unsigned int blink_time = 1000;
                 guint64 now;
+                double ratio;
 
                 g_object_get(gtk_widget_get_settings(m_widget),
                         "gtk-cursor-blink-time", &blink_time,
                         nullptr);
                 now = g_get_monotonic_time() / 1000;
 
-                if (now % blink_time >= blink_time / 2)
-                        fg = bg;
+                ratio = fabs(((double)(now % blink_time) / blink_time) * 2 - 1);
+                fg.red   = ratio * fg.red   + (1.0 - ratio) * bg.red;
+                fg.green = ratio * fg.green + (1.0 - ratio) * bg.green;
+                fg.blue  = ratio * fg.blue  + (1.0 - ratio) * bg.blue;
                 if (m_contents_blink_tag == 0)
                         m_contents_blink_tag = g_timeout_add_full(G_PRIORITY_LOW,
-                                                                  blink_time / 2 - now % (blink_time / 2),
+                                                                  50, /* arbitrary for the demo: 20 FPS */
                                                                   (GSourceFunc)invalidate_all_cb,
                                                                   this,
                                                                   NULL);
