Skip to content

Center play triangle in click-to-play button - #289

Open
wilcoxjay wants to merge 1 commit into
simonw:mainfrom
wilcoxjay:fix-play-button-triangle-centering
Open

Center play triangle in click-to-play button#289
wilcoxjay wants to merge 1 commit into
simonw:mainfrom
wilcoxjay:fix-play-button-triangle-centering

Conversation

@wilcoxjay

Copy link
Copy Markdown

The margin-left:7% on the play icon's triangle SVG pushes it right of the disc center.

Before / after with crosshairs

EngineBeforeAfter
Blink / Chromeblink-chrome-before-crosshairblink-chrome-after-crosshair
Gecko / Firefoxgecko-firefox-before-crosshairgecko-firefox-after-crosshair
WebKit / Safariwebkit-safari-before-crosshairwebkit-safari-after-crosshair

Before / after no crosshairs

EngineBeforeAfter
Blink / Chromeblink-chrome-before-cleanblink-chrome-after-clean
Gecko / Firefoxgecko-firefox-before-cleangecko-firefox-after-clean
WebKit / Safariwebkit-safari-before-cleanwebkit-safari-after-clean

Reproducing the screenshots

To reproduce these screenshots using playwright, save harness.html and capture.py, and then:

python3 -m venv venv
venv/bin/pip install playwright
venv/bin/playwright install chromium firefox webkit # one-time engine download (~250 MB)
venv/bin/python capture.py # 12 images -> ./out/

harness.html

Renders the button with the disc + icon CSS copied verbatim from click-to-play-component.html. Query params toggle the margin-left under test (?m=7%25 vs ?m=0), the red centre crosshair (?g=1), and an engine badge (?badge=1) written by in-page feature detection so each screenshot self-identifies its engine.

<!doctype html><metacharset="utf-8"><title>ctp harness</title><style>html,body{margin:0;font-family:-apple-system,system-ui,sans-serif}
.wrap{position:relative;width:300px;height:300px;display:grid;place-items:center;background:#2b1a4a}
/* ===== verbatim from click-to-play-component.html (injectStyles) ===== */
.ctp-btn{width:200px;height:200px;aspect-ratio:1;display:grid;place-items:center;
border-radius:50%;background:rgba(12,14,22,.34);
-webkit-backdrop-filter:blur(3px) saturate(1.15);backdrop-filter:blur(3px) saturate(1.15);
box-shadow:06px22pxrgba(0,0,0,.34),inset 0001.6pxrgba(255,255,255,.9);
opacity:.92}
.ctp-btnsvg{grid-area:1/1;width:40%;height:40%;fill:#fff;filter:drop-shadow(01px2pxrgba(0,0,0,.45))}
/* margin-left on .ctp-i-play is applied from ?m=... below (the property under test) *//* ===================================================================== */
.guide-v{position:absolute;left:50%;top:0;bottom:0;width:1px;background:red;transform:translateX(-.5px)}
.guide-h{position:absolute;top:50%;left:0;right:0;height:1px;background:red;transform:translateY(-.5px)}
.hidden{display:none}
.badge{position:absolute;left:0;right:0;top:0;padding:6px8px;font:70013px/1.3 ui-monospace,Menlo,monospace;
color:#fff;background:rgba(0,0,0,.55);text-align:center;letter-spacing:.02em}
</style><divclass="wrap"><divclass="badge hidden" id="badge"></div><divclass="ctp-btn"><!-- verbatim PLAY_ICON path from click-to-play-component.html --><svgclass="ctp-i-play" viewBox="0 0 24 24" aria-hidden="true"><pathd="M8 5.5v13a1 1 0 0 0 1.53.85l10-6.5a1 1 0 0 0 0-1.7l-10-6.5A1 1 0 0 0 8 5.5z"/></svg></div><divclass="guide-v" id="gv"></div><divclass="guide-h" id="gh"></div></div><script>functionhas(o,k){try{returnkino;}catch(e){returnfalse;}}functionsupports(p,v){try{returnCSS.supports(p,v);}catch(e){returnfalse;}}vargecko=navigator.productSub==="20100101"||supports("-moz-appearance","none")||navigator.oscpu!==undefined;varwebkit=has(window,"GestureEvent")&&navigator.vendor==="Apple Computer, Inc.";varblink=has(navigator,"userAgentData")||has(Intl,"v8BreakIterator");varverdict=gecko ? "GECKO · Firefox" : webkit ? "WEBKIT · Safari" : blink ? "BLINK · Chrome" : "UNKNOWN";varq=newURLSearchParams(location.search);document.querySelector(".ctp-i-play").style.marginLeft=q.get("m")||"0";if(q.get("g")!=="1"){document.getElementById("gv").classList.add("hidden");document.getElementById("gh").classList.add("hidden");}if(q.get("badge")==="1"){vardisc=document.querySelector('.ctp-btn').getBoundingClientRect();vartri=document.querySelector('.ctp-i-play path').getBoundingClientRect();varoff=(tri.x+tri.width/2)-(disc.x+disc.width/2);varb=document.getElementById("badge");b.classList.remove("hidden");b.textContent=verdict+" · offset "+off.toFixed(3)+"px";}</script>

capture.py

Loads the harness in each engine at 2× scale and screenshots the 300×300 button for every
combination of engine × {before, after} × {crosshair, clean} — the 12 images — and prints
the measured offset per engine.

importjsonfrompathlibimportPathfromplaywright.sync_apiimportsync_playwrightHARNESS= (Path(__file__).resolve().parent/"harness.html").as_uri()
OUT=Path(__file__).resolve().parent/"out"OUT.mkdir(exist_ok=True)
ENGINES= [("blink-chrome", "chromium"), ("gecko-firefox", "firefox"), ("webkit-safari", "webkit")]
STATES= [("before", "7%"), ("after", "0")] # before = buggy margin-left:7%, after = fixedGUIDES= [("crosshair", "1"), ("clean", "0")]
MEASURE="""() => { const disc = document.querySelector('.ctp-btn').getBoundingClientRect(); const tri = document.querySelector('.ctp-i-play path').getBoundingClientRect(); return Math.round(((tri.x + tri.width/2) - (disc.x + disc.width/2)) * 1000) / 1000;}"""measured= {}
withsync_playwright() asp:
launchers= {"chromium": p.chromium, "firefox": p.firefox, "webkit": p.webkit}
foreng_slug, eng_keyinENGINES:
browser=launchers[eng_key].launch()
forstate_slug, margininSTATES:
forguide_slug, ginGUIDES:
page=browser.new_page(viewport={"width": 300, "height": 300}, device_scale_factor=2)
page.goto(f"{HARNESS}?m={margin}&g={g}&badge=1", wait_until="networkidle")
ifguide_slug=="crosshair":
measured[f"{eng_slug}/{state_slug}"] =page.evaluate(MEASURE)
page.locator(".wrap").screenshot(path=str(OUT/f"{eng_slug}-{state_slug}-{guide_slug}.png"))
page.close()
browser.close()
print("wrote screenshots to", OUT)
print(json.dumps(measured, indent=2))

The play icon's SVG path is already balanced, so the margin-left:7% nudge
over-corrected and pushed the triangle right of the disc center. Remove it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@wilcoxjay