unordered-list

Add an Animated Eye Clock to Your Windows Desktop Using AutoIt

An animated eye clock is a fun desktop widget that shows the time while a stylized “eye” follows the cursor or blinks on the hour. Below is a step-by-step guide to build a simple, lightweight animated eye clock in AutoIt. It includes creating the GUI, drawing the eye graphics, updating time, and adding basic animation like pupil tracking and blinking.

What you’ll get

  • A borderless, always-on-top desktop clock showing current time.
  • A circular eye graphic with a movable pupil that follows the mouse.
  • Hourly blink animation and smooth updates.

Requirements

  • AutoIt v3 (latest stable).
  • AutoIt Window Info tool (optional, for positioning).
  • A plain text editor (SciTE recommended).

File structure

  • EyeClock.au3 main script
  • Assets (optional) any images if you prefer bitmap eyes (not required for drawing with GDI+)

Full script (EyeClock.au3)

autoit
; EyeClock.au3; Simple animated eye clock for Windows using AutoIt + GDI+; Requires AutoIt3 (v3.x)
#RequireAdmin ; optional if you need special permissions#include #include #include #include 
Global Const \(WIDTH = 220</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">Global Const \)HEIGHT = 120Global Const \(EYE_RADIUS = 30</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">Global Const \)PUPIL_RADIUS = 9Global Const \(EYE_OFFSET_X = 60</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">Global Const \)EYE_OFFSET_Y = 50
; Start GDI+_GDIPlus_Startup()
; Create transparent, borderless GUI\(hGUI = GUICreate("", \)WIDTH, \(HEIGHT, -1, -1, BitOR(\)WS_POPUP, \(WS_EX_TOPMOST))</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">GUISetBkColor(0x000000, \)hGUI); Make window layered and transparent for click-through background (keeps controls clickable)_WinAPI_SetWindowLong(\(hGUI, \)GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong(\(hGUI, \)GWL_EXSTYLE), \(WS_EX_LAYERED))</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">_WinAPI_SetLayeredWindowAttributes(\)hGUI, 0x000000, 255, \(LWA_COLORKEY)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">GUISetState(@SW_SHOW, \)hGUI)
; Create GDI+ graphics surface\(hImage = _GDIPlus_BitmapCreateFromScan0(\)WIDTH, \(HEIGHT)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">\)hGraphics = _GDIPlus_ImageGetGraphicsContext(\(hImage)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">; Font for time</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">Local \)hFont = _GDIPlus_FontCreate(“Segoe UI”, 18, \(GDIP_FONTSTYLE_BOLD)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">; Blink control</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">Global \)g_blinkTimer = TimerInit()Global \(g_blinkState = False</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">Global \)g_lastBlink = 0
; Main loopWhile 1; Clear    _GDIPlus_GraphicsClear(\(hGraphics, 0x00FFFFFF)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    ; Draw clock background</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    _GDIPlus_GraphicsFillEllipse(\)hGraphics, _MakeBrush(0xFFEFEFEF), 10, 10, 80, 80) ; left eye bg    _GDIPlus_GraphicsFillEllipse(\(hGraphics, _MakeBrush(0xFFEFEFEF), 130, 10, 80, 80) ; right eye bg</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    ; Calculate pupil positions based on mouse</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    Local \)mousePos = MouseGetPos()    Local \(winPos = WinGetPos("")</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    ; If multiple windows, we need our GUI position specifically</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    \)winPos = WinGetPos(“[HANDLE:” & GUICtrlGetHandle(\(hGUI) & "]")</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    Local \)leftEyeCenterX = \(winPos[0] + 10 + \)EYE_RADIUS    Local \(leftEyeCenterY = \)winPos[1] + 10 + \(EYE_RADIUS</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    Local \)rightEyeCenterX = \(winPos[0] + 130 + \)EYE_RADIUS    Local \(rightEyeCenterY = \)winPos[1] + 10 + \(EYE_RADIUS</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    Local \)lp = _CalcPupil(\(leftEyeCenterX, \)leftEyeCenterY, \(mousePos[0], \)mousePos[1], \(EYE_RADIUS - \)PUPIL_RADIUS - 4)    Local \(rp = _CalcPupil(\)rightEyeCenterX, \(rightEyeCenterY, \)mousePos[0], \(mousePos[1], \)EYE_RADIUS - \(PUPIL_RADIUS - 4)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    ; Blink every ~10-18 minutes randomly or on the hour</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    If Mod(@MIN, 60) = 0 And @SEC < 2 And \)g_lastBlink <> @MIN Then        \(g_blinkState = True</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">        \)g_lastBlink = @MIN        \(g_blinkTimer = TimerInit()</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    ElseIf TimerDiff(\)g_blinkTimer) > 120 And \(g_blinkState Then</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">        \)g_blinkState = False    ElseIf Not \(g_blinkState And Random(0, 1, 1) < 0.005 Then ; occasional blink</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">        \)g_blinkState = True        \(g_blinkTimer = TimerInit()</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    EndIf</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"> </span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    ; Draw eyes or blink (simple eyelid rectangle)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    If \)g_blinkState Then        ; Draw closed eyelids        _GDIPlus_GraphicsFillRectangle(\(hGraphics, _MakeBrush(0xFFDDDDDD), 10, 10 + \)EYE_RADIUS - 8, 80, 16)        _GDIPlus_GraphicsFillRectangle(\(hGraphics, _MakeBrush(0xFFDDDDDD), 130, 10 + \)EYE_RADIUS - 8, 80, 16)    Else        ; Draw irises        _GDIPlus_GraphicsFillEllipse(\(hGraphics, _MakeBrush(0xFF6AA2FF), 10 + (\)EYE_RADIUS - 18), 10 + (\(EYE_RADIUS - 18), 36, 36)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">        _GDIPlus_GraphicsFillEllipse(\)hGraphics, _MakeBrush(0xFF6AA2FF), 130 + (\(EYE_RADIUS - 18), 10 + (\)EYE_RADIUS - 18), 36, 36)
        ; Draw pupils        _GDIPlus_GraphicsFillEllipse(\(hGraphics, _MakeBrush(0xFF000000), \)lp[0] - \(PUPIL_RADIUS, \)lp[1] - \(PUPIL_RADIUS, \)PUPIL_RADIUS*2, \(PUPIL_RADIUS*2)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">        _GDIPlus_GraphicsFillEllipse(\)hGraphics, _MakeBrush(0xFF000000), \(rp[0] - \)PUPIL_RADIUS, \(rp[1] - \)PUPIL_RADIUS, \(PUPIL_RADIUS*2, \)PUPIL_RADIUS*2)
        ; Highlights        _GDIPlus_GraphicsFillEllipse(\(hGraphics, _MakeBrush(0xFFFFFFFF), \)lp[0] - 4, \(lp[1] - 6, 6, 6)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">        _GDIPlus_GraphicsFillEllipse(\)hGraphics, _MakeBrush(0xFFFFFFFF), \(rp[0] - 4, \)rp[1] - 6, 6, 6)    EndIf
    ; Draw time text    Local \(timeStr = StringFormat("%02d:%02d:%02d", @HOUR, @MIN, @SEC)</span></span><span class="block before:content-[counter(line)] before:inline-block before:[counter-increment:line] before:w-6 before:mr-4 before:text-[13px] before:text-right before:text-muted-foreground/50 before:font-mono before:select-none"><span class="text-[var(--sdm-c,inherit)] dark:text-[var(--shiki-dark,var(--sdm-c,inherit))]">    _GDIPlus_GraphicsDrawString(\)hGraphics, \(timeStr, \)hFont, 80, 70, _MakeBrush(0xFF000000))
    ; Render to GUI

Your email address will not be published. Required fields are marked *