Circle Sync ⭕
A precision-timing game where holding the perfect interval grows a glowing circle to match a target
Circle Sync is a single HTML file that turns "tap and hold for the right amount of time" into a complete game. A glowing circle starts small. Press and hold to grow it. Release exactly when it matches the dashed target outline. The closer to perfect — 1.00 — the more points you earn. A perfect 1.00 clears the level and awards a level bonus; higher levels have tighter timing windows and faster growth rates.
The game runs indefinitely. Best score per level and overall total points persist via localStorage so the player can chase improvements across sessions.
Delivery
1 HTML file
Dependencies
0 installed
Levels
Endless
Score precision
2 decimals
Perfect score
1.00
Storage
localStorage
The game loop is a single press-hold-release gesture per attempt:
Press to grow
A small glowing inner circle and a larger dashed target outline appear. Touching down begins growing the inner circle outward.
Continuous expansion
The circle expands at a level-defined rate while held. A live percentage shows how close the current diameter is to the target.
Release at match
Lift your finger when the inner circle visually matches the dashed outline. The closer to 100% match at release, the higher the timing score.
Perfect = level up
A timing score of exactly 1.00 (after 2-decimal rounding) clears the current level, awards a bonus, and advances to a harder level.
Each release yields a timing score calculated as 1.00 − |current/target − 1|, then rounded to 2 decimals and floored at 0. A release at exactly the target gives 1.00; releases at 50% of target or 150% of target give 0.50; far misses give 0.00.
The timing score is multiplied by the level's point value — higher levels reward each attempt with more points. Points accumulate to an overall total across the whole session. A perfect 1.00 release additionally awards the level's completion bonus and unlocks the next level.
The inner circle is a single div with a radial gradient — white center, yellow accent, blue mid, and dark blue edge. The illusion of glow comes from a large box-shadow with the accent color at 78% opacity, brightened slightly when active. The outer target uses a CSS dashed border that contrasts visually with the solid inner circle.
A live number shows current diameter as a percentage of target. This is updated every animation frame during a press — players can use it for visual calibration, especially early on. Skilled players ignore it and rely on visual matching for faster release reflex.
On release, the score is displayed prominently. A perfect 1.00 triggers a brief celebration animation and the level-up overlay. Non-perfect scores show in a softer color along with a hint about whether you released too early or too late.
Per-level statistics are tracked and viewable from a stats overlay: number of attempts, best score per level, total tries before clearing, and current best overall total points. The data is stored under multiple localStorage keys (legacy migration: circleSyncBestPoints, circleSyncBest, bestScore) — the game reads any of them on load to handle older save formats from earlier versions gracefully.
HTML + CSS + Vanilla JS
Entire game, single file
No framework
Pointer Events
Unified press/release across input types
Native browser
requestAnimationFrame
Growth loop — diameter updated per frame
Native browser
CSS gradients
Glow circle, radial backgrounds
No image assets
localStorage
Best scores + level stats persistence
Native browser
State lives in a small object: level, currentDiameter, isHolding, totalPoints, plus per-level stats arrays. There are no classes — only functions that read and mutate state.
The growth loop is started on pointerdown and stopped on pointerup. While running, it uses requestAnimationFrame to add the level's growth rate to currentDiameter each frame, then updates the circle's CSS width and height. The live percentage is computed in the same loop.
The version string (Circle Sync v5.0) is shown in the footer; storage keys carry version-tolerant fallbacks so updates can be released without wiping player progress. There are no analytics, no error reporting, and no network calls — the game's entire surface area is the HTML, CSS, and JS in the one file.