Skip to content

Commit ed2bb15

Browse files
committed
Animate mask bean on load to avoid blinking
1 parent 883a6ad commit ed2bb15

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"use client"
2+
3+
import type { StaticImageData } from "next/image"
4+
import { useEffect, useState } from "react"
5+
6+
export interface ImageLoadedProps extends React.HTMLAttributes<HTMLDivElement> {
7+
image: string | StaticImageData
8+
}
9+
10+
export function ImageLoaded({ image, ...rest }: ImageLoadedProps) {
11+
const [loaded, setLoaded] = useState(false)
12+
13+
useEffect(() => {
14+
const img = new Image()
15+
const src = typeof image === "string" ? image : image.src
16+
img.src = src
17+
img.onload = () => setLoaded(true)
18+
}, [image])
19+
20+
return <div data-loaded={loaded} {...rest} />
21+
}

src/app/conf/2025/components/hero/index.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Button } from "../../../_design-system/button"
77
import graphqlFoundationWordmarkSvg from "../../assets/graphql-foundation-wordmark.svg"
88
import heroPhoto from "./hero-photo.jpeg"
99
import blurBean from "./blur-bean-cropped.webp"
10+
import { ImageLoaded } from "./image-loaded"
1011

1112
// - the background is made of even and odd stripes every 12px and a mask
1213
// - i can have two divs with repeating background image and a mask
@@ -78,9 +79,10 @@ function Stripes() {
7879
"repeating-linear-gradient(to right, black, black 12px, transparent 12px, transparent 24px)"
7980

8081
return (
81-
<div
82+
<ImageLoaded
8283
role="presentation"
83-
className="pointer-events-none absolute inset-x-0 bottom-[-385px] top-[-203px] -z-10"
84+
image={blurBean}
85+
className="pointer-events-none absolute inset-x-0 bottom-[-385px] top-[-203px] -z-10 translate-y-12 opacity-0 transition duration-500 ease-linear data-[loaded=true]:translate-y-0 data-[loaded=true]:opacity-100"
8486
// todo: animate opacity up after the image is loaded
8587
style={{
8688
maskImage: `url(${blurBean.src})`,
@@ -107,6 +109,6 @@ function Stripes() {
107109
WebkitMaskImage: maskOdd,
108110
}}
109111
/>
110-
</div>
112+
</ImageLoaded>
111113
)
112114
}

0 commit comments

Comments
 (0)