Skip to content

Commit 7abcc25

Browse files
committed
dark and light preview screenshots
1 parent d2e17e1 commit 7abcc25

4 files changed

Lines changed: 47 additions & 19 deletions

File tree

docs/_static/showcase.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:f10b9b152c3ad2ef2b459675f70b9a383f2116773c05ed02fa92d3a590f06655
3-
size 311035
2+
oid sha256:4670cf7ee376ee7d5514a6f0b61862975febb5c83a9ff76aa8f076758900afa3
3+
size 345586

docs/create_showcase.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
}}
6363
</style>
6464
<div id="showcase_root" style="width:min(800px,100%); max-width:100%; margin:0 auto 1em auto; position:relative;">
65-
<canvas id="{canvas_id}" width="800" height="400" style="background-color:var(--webgpu-canvas-bg,#ffffff); width:100%; max-width:100%; height:auto; aspect-ratio:800 / 400; border-radius:8px; display:block;"></canvas>
65+
<canvas id="{canvas_id}" width="800" height="400" style="background-color:var(--webgpu-canvas-bg,#ffffff); width:100%; max-width:100%; height:auto; aspect-ratio:800 / 400; touch-action:none; border-radius:8px; display:block;"></canvas>
6666
<script>
6767
{engine_js}
6868
RenderEngine.create("{canvas_id}", "{blob_b64}");

webgpu/export/screenshot.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
screenshot requests over stdin/stdout.
55
66
Protocol (line-based):
7-
Request: <width> <height> <blob_b64>\n
7+
Request: <width> <height> <color_scheme> <blob_b64>\n
8+
where <color_scheme> is "light" or "dark".
9+
810
Response: <png_b64>\n
911
Shutdown: (close stdin)
1012
@@ -90,18 +92,22 @@ def log_message(self, *a):
9092
sys.stdout.flush()
9193

9294
# Process requests from stdin
95+
request_id = 0
9396
for line in sys.stdin:
9497
line = line.strip()
9598
if not line:
9699
continue
97100

98-
parts = line.split(' ', 2)
99-
if len(parts) != 3:
101+
parts = line.split(' ', 3)
102+
if len(parts) != 4:
100103
sys.stdout.write("\n")
101104
sys.stdout.flush()
102105
continue
103106

104-
width, height, blob_b64 = int(parts[0]), int(parts[1]), parts[2]
107+
width, height = int(parts[0]), int(parts[1])
108+
color_scheme, blob_b64 = parts[2], parts[3]
109+
if color_scheme not in ("light", "dark"):
110+
color_scheme = "light"
105111

106112
html = f"""<!DOCTYPE html><html><body style="margin:0;padding:0;overflow:hidden;">
107113
<canvas id="c" width="{width}" height="{height}" style="display:block;"></canvas>
@@ -118,7 +124,9 @@ def log_message(self, *a):
118124
</script></body></html>"""
119125

120126
(tmpdir / "index.html").write_text(html)
121-
page.goto(f"http://127.0.0.1:{port}/index.html")
127+
page.emulate_media(color_scheme=color_scheme)
128+
request_id += 1
129+
page.goto(f"http://127.0.0.1:{port}/index.html?rid={request_id}")
122130

123131
try:
124132
page.wait_for_function(

webgpu/jupyter.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -204,35 +204,55 @@ def _DrawHTMLLazy(scene, width=640, height=600):
204204
_engine_emitted = True
205205
engine_url = f"{rel_prefix}_static/webgpu_scenes/engine.js"
206206

207-
# Capture screenshot in a separate subprocess
208-
screenshot_b64 = _capture_screenshot_subprocess(blob_b64, width, height)
209-
screenshot_filename = f"screenshot_{blob_hash}.png"
210-
if screenshot_b64:
211-
(static_dir / screenshot_filename).write_bytes(base64.b64decode(screenshot_b64))
212-
screenshot_url = f"{rel_prefix}_static/webgpu_scenes/{screenshot_filename}"
207+
# Capture screenshots (light + dark) in a separate subprocess.
208+
screenshot_light_b64 = _capture_screenshot_subprocess(blob_b64, width, height, color_scheme="light")
209+
screenshot_dark_b64 = _capture_screenshot_subprocess(blob_b64, width, height, color_scheme="dark")
210+
211+
screenshot_light_filename = f"screenshot_{blob_hash}_light.png"
212+
screenshot_dark_filename = f"screenshot_{blob_hash}_dark.png"
213+
214+
if screenshot_light_b64:
215+
(static_dir / screenshot_light_filename).write_bytes(base64.b64decode(screenshot_light_b64))
216+
if screenshot_dark_b64:
217+
(static_dir / screenshot_dark_filename).write_bytes(base64.b64decode(screenshot_dark_b64))
218+
219+
screenshot_light_url = f"{rel_prefix}_static/webgpu_scenes/{screenshot_light_filename}"
220+
# Fallback to light if dark capture failed
221+
screenshot_dark_url = (
222+
f"{rel_prefix}_static/webgpu_scenes/{screenshot_dark_filename}"
223+
if screenshot_dark_b64 else screenshot_light_url
224+
)
213225

214226
# Emit the lazy-load HTML: only screenshot + overlay, everything else loaded on click
215227
lazy_html = f"""
216228
<style>
217229
#{id_}root {{ --webgpu-canvas-bg: #ffffff; }}
230+
#{id_}img_light {{ display: block; }}
231+
#{id_}img_dark {{ display: none; }}
218232
@media (prefers-color-scheme: dark) {{
219233
#{id_}root {{ --webgpu-canvas-bg: #adadad; }}
234+
#{id_}img_light {{ display: none; }}
235+
#{id_}img_dark {{ display: block; }}
220236
}}
221237
</style>
222238
<div id='{id_}root'
223239
style="position: relative; width: min({width}px, 100%); max-width: 100%; overflow: hidden;"
224240
>
225-
<img id='{id_}img'
226-
src='{screenshot_url}'
241+
<img id='{id_}img_light'
242+
src='{screenshot_light_url}'
227243
style='width: 100%; max-width: 100%; height: auto; aspect-ratio: {width} / {height}; display: block;'
228244
/>
245+
<img id='{id_}img_dark'
246+
src='{screenshot_dark_url}'
247+
style='width: 100%; max-width: 100%; height: auto; aspect-ratio: {width} / {height}; display: none;'
248+
/>
229249
<div id='{id_}overlay'
230250
style='position: absolute; top: 0; left: 0; width: 100%; height: 100%;
231251
display: flex; align-items: center; justify-content: center;
232252
background: rgba(0,0,0,0); cursor: pointer; transition: background 0.2s;'
233253
onmouseover="this.style.background='rgba(0,0,0,0.18)'; this.querySelector('span').style.opacity='1'"
234254
onmouseout="this.style.background='rgba(0,0,0,0)'; this.querySelector('span').style.opacity='0'"
235-
onclick="(function() {{ var r = document.getElementById('{id_}root'); if (r.__activated) return; r.__activated = true; function activate() {{ document.getElementById('{id_}img').style.display = 'none'; document.getElementById('{id_}overlay').style.display = 'none'; document.getElementById('{canvas_id}').style.display = 'block'; RenderEngine.create('{canvas_id}', window.{scene_var}); }} function loadBlob() {{ var s = document.createElement('script'); s.src = '{scene_url}'; s.onload = activate; document.head.appendChild(s); }} if (typeof RenderEngine === 'undefined') {{ var s = document.createElement('script'); s.src = '{engine_url}'; s.onload = loadBlob; document.head.appendChild(s); }} else {{ loadBlob(); }} }})()"
255+
onclick="(function() {{ var r = document.getElementById('{id_}root'); if (r.__activated) return; r.__activated = true; function activate() {{ var il = document.getElementById('{id_}img_light'); if (il) il.style.display = 'none'; var id = document.getElementById('{id_}img_dark'); if (id) id.style.display = 'none'; document.getElementById('{id_}overlay').style.display = 'none'; document.getElementById('{canvas_id}').style.display = 'block'; RenderEngine.create('{canvas_id}', window.{scene_var}); }} function loadBlob() {{ var s = document.createElement('script'); s.src = '{scene_url}'; s.onload = activate; document.head.appendChild(s); }} if (typeof RenderEngine === 'undefined') {{ var s = document.createElement('script'); s.src = '{engine_url}'; s.onload = loadBlob; document.head.appendChild(s); }} else {{ loadBlob(); }} }})()"
236256
>
237257
<span style='color: white; font-size: 1.3em; font-weight: bold;
238258
text-shadow: 0 1px 4px rgba(0,0,0,0.7); pointer-events: none;
@@ -282,7 +302,7 @@ def _get_static_dir():
282302
_screenshot_worker = None
283303

284304

285-
def _capture_screenshot_subprocess(blob_b64, width, height):
305+
def _capture_screenshot_subprocess(blob_b64, width, height, color_scheme):
286306
"""Send a screenshot request to the persistent worker process."""
287307
import subprocess
288308
import sys
@@ -304,7 +324,7 @@ def _capture_screenshot_subprocess(blob_b64, width, height):
304324
return ""
305325

306326
try:
307-
_screenshot_worker.stdin.write(f"{width} {height} {blob_b64}\n")
327+
_screenshot_worker.stdin.write(f"{width} {height} {color_scheme} {blob_b64}\n")
308328
_screenshot_worker.stdin.flush()
309329
result = _screenshot_worker.stdout.readline().strip()
310330
return result

0 commit comments

Comments
 (0)