Skip to content

Instantly share code, notes, and snippets.

@yusukebe
Created January 30, 2024 06:45
Show Gist options
  • Save yusukebe/13a13db6a3a96faf18a9f5769c733b49 to your computer and use it in GitHub Desktop.
Save yusukebe/13a13db6a3a96faf18a9f5769c733b49 to your computer and use it in GitHub Desktop.
import { useState, startViewTransition, Suspense } from 'hono/jsx'
import { use } from 'hono/jsx'
import { render } from 'hono/jsx/dom'
import { Style, css, keyframes } from 'hono/css'
const App = () => {
const [show, setShow] = useState(false)
return (
<div onClick={() => startViewTransition(() => setShow(!show))}>
{show ? (
<Suspense fallback={'Loading...'}>
<TitleImage />
</Suspense>
) : (
<ThumbnailImage />
)}
</div>
)
}
const imagePromise = new Map<string, Promise<string>>()
const loadImage = (src: string) => {
if (!imagePromise.has(src)) {
imagePromise.set(
src,
new Promise((resolve) => {
;(async () => {
const image = new window.Image()
image.onload = () => resolve(src)
await new Promise((resolve) => setTimeout(resolve, 1000))
image.src = src
})()
})
)
}
return imagePromise.get(src) as Promise<string>
}
const ThumbnailImage = () => (
<img
class={css`
opacity: 0.8;
`}
src="https://avatars.githubusercontent.com/u/98495527?s=48&v=4"
/>
)
const TitleImage = () => {
const image = use(loadImage('https://github.com/honojs/hono/blob/main/docs/images/hono-title.png?raw=true'))
const fadeIn = keyframes`
from { opacity: 0; }
to { opacity: 1; }
`
return (
<div
class={css`
animation: ${fadeIn} 1s;
background: url('${image}');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
width: 500px;
height: 200px;
`}
/>
)
}
const root = document.getElementById('root') as HTMLElement
render(
<html>
<head>
<Style />
</head>
<div>
<App />
</div>
</html>,
root
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment