feat(theme): --settle capture delay for reveal transitions and canvas heroes

Scroll-reveal themes (gotham .reveal, scifi-clean data-sc-reveal) start
content at opacity:0 under JS and fade in ~0.5s after the observer fires;
capturing on WaitVisible(main) catches mid-transition ghosts. --settle adds
a post-wait delay so transitions and canvas animations (cyberpunk rain)
finish before the screenshot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Alex Dunmow 2026-07-06 10:23:43 +08:00
parent e71bf16d71
commit 098a2091b9
2 changed files with 9 additions and 0 deletions

View File

@ -27,6 +27,7 @@ func newThemeScreenshotCmd() *cobra.Command {
var mobile bool var mobile bool
var width, height int var width, height int
var scale float64 var scale float64
var settle time.Duration
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "screenshot", Use: "screenshot",
Short: "Render this theme's showcase page and write preview.png into the repo", Short: "Render this theme's showcase page and write preview.png into the repo",
@ -70,6 +71,7 @@ the rest of the CLI.`,
WaitSelector: waitSelector, WaitSelector: waitSelector,
Timeout: 45 * time.Second, Timeout: 45 * time.Second,
Scale: scale, Scale: scale,
Settle: settle,
}) })
if err != nil { if err != nil {
return err return err
@ -89,6 +91,7 @@ the rest of the CLI.`,
WaitSelector: waitSelector, WaitSelector: waitSelector,
Timeout: 45 * time.Second, Timeout: 45 * time.Second,
Scale: scale, Scale: scale,
Settle: settle,
}) })
if err != nil { if err != nil {
return err return err
@ -128,6 +131,7 @@ the rest of the CLI.`,
Timeout: 45 * time.Second, Timeout: 45 * time.Second,
Mode: mode, Mode: mode,
Scale: scale, Scale: scale,
Settle: settle,
}) })
if err != nil { if err != nil {
return err return err
@ -159,6 +163,7 @@ the rest of the CLI.`,
cmd.Flags().IntVar(&height, "height", 900, "Desktop viewport height") cmd.Flags().IntVar(&height, "height", 900, "Desktop viewport height")
cmd.Flags().StringVar(&pages, "pages", "", "Comma-separated page slugs to capture into --screenshots-dir (e.g. /,/blog,/about)") cmd.Flags().StringVar(&pages, "pages", "", "Comma-separated page slugs to capture into --screenshots-dir (e.g. /,/blog,/about)")
cmd.Flags().StringVar(&screenshotsDir, "screenshots-dir", "screenshots", "Directory for --pages captures (packed into the .bnp)") cmd.Flags().StringVar(&screenshotsDir, "screenshots-dir", "screenshots", "Directory for --pages captures (packed into the .bnp)")
cmd.Flags().DurationVar(&settle, "settle", 0, "Extra wait after --wait matches before capturing (e.g. 1500ms; lets reveal transitions and canvas animations finish)")
cmd.Flags().Float64Var(&scale, "scale", 1, "Device scale factor (2 = retina PNGs at Width*2 x Height*2)") cmd.Flags().Float64Var(&scale, "scale", 1, "Device scale factor (2 = retina PNGs at Width*2 x Height*2)")
cmd.Flags().StringVar(&modes, "modes", "", `Comma-separated color modes for --pages captures: "light", "dark" or "light,dark" (sets the bn-theme cookie per capture; empty = site default, unsuffixed filenames)`) cmd.Flags().StringVar(&modes, "modes", "", `Comma-separated color modes for --pages captures: "light", "dark" or "light,dark" (sets the bn-theme cookie per capture; empty = site default, unsuffixed filenames)`)
return cmd return cmd

View File

@ -26,6 +26,7 @@ type Options struct {
Timeout time.Duration // overall navigation+capture timeout Timeout time.Duration // overall navigation+capture timeout
Mode string // "" (site default), "light" or "dark" — sets the bn-theme cookie + emulated prefers-color-scheme before navigation Mode string // "" (site default), "light" or "dark" — sets the bn-theme cookie + emulated prefers-color-scheme before navigation
Scale float64 // device scale factor; 0 = 1.0. 2 captures retina PNGs (Width*2 × Height*2 px) Scale float64 // device scale factor; 0 = 1.0. 2 captures retina PNGs (Width*2 × Height*2 px)
Settle time.Duration // extra wait after WaitSelector before capturing — lets scroll-reveal transitions and canvas animations finish (0 = capture immediately)
} }
// PreviewURL composes the gallery-page URL with the render-only override. // PreviewURL composes the gallery-page URL with the render-only override.
@ -99,6 +100,9 @@ func Capture(ctx context.Context, opts Options) ([]byte, error) {
} else { } else {
tasks = append(tasks, chromedp.WaitReady("body", chromedp.ByQuery)) tasks = append(tasks, chromedp.WaitReady("body", chromedp.ByQuery))
} }
if opts.Settle > 0 {
tasks = append(tasks, chromedp.Sleep(opts.Settle))
}
if opts.FullPage { if opts.FullPage {
tasks = append(tasks, chromedp.FullScreenshot(&buf, 90)) tasks = append(tasks, chromedp.FullScreenshot(&buf, 90))
} else { } else {