Skip to content

Commit 930e328

Browse files
committed
feat: zoom on long image
1 parent 1e47ba2 commit 930e328

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

apps/renderer/src/components/ui/media/preview-media.tsx

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ActionButton, MotionButtonBase } from "@follow/components/ui/button/index.js"
22
import { RootPortal } from "@follow/components/ui/portal/index.js"
3+
import { useMeasure } from "@follow/hooks"
34
import { IN_ELECTRON } from "@follow/shared/constants"
45
import type { MediaModel } from "@follow/shared/hono"
56
import { stopPropagation } from "@follow/utils/dom"
@@ -153,6 +154,7 @@ export const PreviewMediaContent: FC<{
153154
height={media[0].height}
154155
width={media[0].width}
155156
blurhash={media[0].blurhash}
157+
haveSideContent={!!children}
156158
/>
157159
)}
158160
</Wrapper>
@@ -262,6 +264,7 @@ export const PreviewMediaContent: FC<{
262264
height={med.height}
263265
width={med.width}
264266
blurhash={med.blurhash}
267+
haveSideContent={!!children}
265268
/>
266269
)}
267270
</SwiperSlide>
@@ -271,14 +274,19 @@ export const PreviewMediaContent: FC<{
271274
)
272275
}
273276

277+
function parseNumber(value: string | number | undefined) {
278+
return typeof value === "string" ? Number.parseInt(value) : value
279+
}
280+
274281
const FallbackableImage: FC<
275282
Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src"> & {
276283
src: string
277284
containerClassName?: string
278285
fallbackUrl?: string
279286
blurhash?: string
287+
haveSideContent?: boolean
280288
}
281-
> = ({ src, onError, fallbackUrl, containerClassName, blurhash, ...props }) => {
289+
> = ({ src, onError, fallbackUrl, containerClassName, blurhash, haveSideContent, ...props }) => {
282290
const [currentSrc, setCurrentSrc] = useState(() => replaceImgUrlIfNeed(src))
283291
const [isAllError, setIsAllError] = useState(false)
284292

@@ -318,38 +326,54 @@ const FallbackableImage: FC<
318326
}
319327
}, [currentSrc, currentState, fallbackUrl, src])
320328

321-
const height = Number.parseInt(props.height as string)
322-
const width = Number.parseInt(props.width as string)
329+
const height = parseNumber(props.height)
330+
const width = parseNumber(props.width)
323331

324332
const { height: windowHeight, width: windowWidth } = useWindowSize()
325333
// px-20 pb-8 pt-10
326334
// wrapper side content w-[400px]
327335
const maxContainerHeight = windowHeight - 32 - 40
328-
const maxContainerWidth = windowWidth - 80 - 80 - 400
336+
const maxContainerWidth = windowWidth - 80 - 80 - (haveSideContent ? 400 : 0)
337+
338+
const [scale, setScale] = useState(1)
329339

330-
const wrapperClass = cn("relative !max-h-full", width <= height && "!h-full")
340+
const wrapperClass = cn("relative !max-h-full", width && height && width <= height && "!h-full")
331341
const wrapperStyle: React.CSSProperties = {
332342
width:
333343
width && height && width > height
334344
? `${Math.min(maxContainerHeight * (width / height), width)}px`
335345
: undefined,
336-
maxWidth: width > height ? `${maxContainerWidth}px` : undefined,
346+
maxWidth: width && height && width > height ? `${maxContainerWidth}px` : undefined,
337347
}
338348

349+
const [ref, { width: imgWidth }] = useMeasure()
350+
339351
return (
340352
<div
341353
className={cn("center flex size-full flex-col", containerClassName)}
342354
onClick={stopPropagation}
343355
>
344356
{!isAllError && (
345-
<TransformWrapper wheel={{ step: 1 }}>
357+
<TransformWrapper
358+
wheel={{ step: 1 }}
359+
onZoom={(e) => {
360+
setScale(e.state.scale)
361+
}}
362+
>
346363
<TransformComponent
347364
wrapperClass={wrapperClass}
348-
wrapperStyle={wrapperStyle}
365+
wrapperStyle={{
366+
...wrapperStyle,
367+
minWidth:
368+
scale > 1 && !haveSideContent
369+
? `${Math.min(maxContainerWidth / 2, scale * imgWidth)}px`
370+
: undefined,
371+
}}
349372
contentClass={wrapperClass}
350373
contentStyle={wrapperStyle}
351374
>
352375
<img
376+
ref={ref}
353377
data-blurhash={blurhash}
354378
src={currentSrc}
355379
onLoad={() => setIsLoading(false)}
@@ -358,7 +382,7 @@ const FallbackableImage: FC<
358382
width={props.width}
359383
{...props}
360384
className={cn(
361-
"transition-opacity duration-700",
385+
"mx-auto transition-opacity duration-700",
362386
isLoading ? "opacity-0" : "opacity-100",
363387
props.className,
364388
)}

0 commit comments

Comments
 (0)