Skip to content

Commit 1e47ba2

Browse files
committed
feat: image zoom
close #1183
1 parent 0e7a61d commit 1e47ba2

File tree

3 files changed

+81
-43
lines changed

3 files changed

+81
-43
lines changed

apps/renderer/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
"react-selecto": "^1.26.3",
8686
"react-shadow": "20.5.0",
8787
"react-virtuoso": "4.12.0",
88+
"react-zoom-pan-pinch": "^3.6.1",
8889
"rehype-infer-description-meta": "2.0.0",
8990
"rehype-parse": "9.0.1",
9091
"rehype-sanitize": "6.0.0",

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

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { FC } from "react"
88
import { Fragment, useCallback, useEffect, useRef, useState } from "react"
99
import { Blurhash } from "react-blurhash"
1010
import { useTranslation } from "react-i18next"
11+
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch"
1112
import { Keyboard, Mousewheel } from "swiper/modules"
1213
import type { SwiperRef } from "swiper/react"
1314
import { Swiper, SwiperSlide } from "swiper/react"
@@ -321,49 +322,70 @@ const FallbackableImage: FC<
321322
const width = Number.parseInt(props.width as string)
322323

323324
const { height: windowHeight, width: windowWidth } = useWindowSize()
325+
// px-20 pb-8 pt-10
326+
// wrapper side content w-[400px]
327+
const maxContainerHeight = windowHeight - 32 - 40
328+
const maxContainerWidth = windowWidth - 80 - 80 - 400
329+
330+
const wrapperClass = cn("relative !max-h-full", width <= height && "!h-full")
331+
const wrapperStyle: React.CSSProperties = {
332+
width:
333+
width && height && width > height
334+
? `${Math.min(maxContainerHeight * (width / height), width)}px`
335+
: undefined,
336+
maxWidth: width > height ? `${maxContainerWidth}px` : undefined,
337+
}
324338

325339
return (
326-
<div className={cn("center flex size-full flex-col", containerClassName)}>
340+
<div
341+
className={cn("center flex size-full flex-col", containerClassName)}
342+
onClick={stopPropagation}
343+
>
327344
{!isAllError && (
328-
<div
329-
className={cn("relative max-h-full", width <= height && "h-full")}
330-
style={{
331-
// px-20 pb-8 pt-10
332-
width:
333-
width && height && width > height
334-
? `${Math.min((windowHeight - 32 - 40) * (width / height), width)}px`
335-
: undefined,
336-
maxWidth: width > height ? `${windowWidth - 80 - 80 - 400}px` : undefined,
337-
}}
338-
>
339-
<img
340-
data-blurhash={blurhash}
341-
src={currentSrc}
342-
onLoad={() => setIsLoading(false)}
343-
onError={handleError}
344-
height={props.height}
345-
width={props.width}
346-
{...props}
347-
className={cn(
348-
"transition-opacity duration-700",
349-
isLoading ? "opacity-0" : "opacity-100",
350-
props.className,
351-
)}
352-
style={props.style}
353-
/>
354-
<div
355-
className={cn(
356-
"center absolute inset-0 size-full transition-opacity duration-700",
357-
isLoading ? "opacity-100" : "opacity-0",
358-
)}
345+
<TransformWrapper wheel={{ step: 1 }}>
346+
<TransformComponent
347+
wrapperClass={wrapperClass}
348+
wrapperStyle={wrapperStyle}
349+
contentClass={wrapperClass}
350+
contentStyle={wrapperStyle}
359351
>
360-
{blurhash ? (
361-
<Blurhash hash={blurhash} resolutionX={32} resolutionY={32} className="!size-full" />
362-
) : (
363-
<i className="i-mgc-loading-3-cute-re size-8 animate-spin text-white/80" />
364-
)}
365-
</div>
366-
</div>
352+
<img
353+
data-blurhash={blurhash}
354+
src={currentSrc}
355+
onLoad={() => setIsLoading(false)}
356+
onError={handleError}
357+
height={props.height}
358+
width={props.width}
359+
{...props}
360+
className={cn(
361+
"transition-opacity duration-700",
362+
isLoading ? "opacity-0" : "opacity-100",
363+
props.className,
364+
)}
365+
style={{
366+
maxHeight: `${maxContainerHeight}px`,
367+
...props.style,
368+
}}
369+
/>
370+
<div
371+
className={cn(
372+
"center absolute inset-0 size-full transition-opacity duration-700",
373+
isLoading ? "opacity-100" : "opacity-0",
374+
)}
375+
>
376+
{blurhash ? (
377+
<Blurhash
378+
hash={blurhash}
379+
resolutionX={32}
380+
resolutionY={32}
381+
className="!size-full"
382+
/>
383+
) : (
384+
<i className="i-mgc-loading-3-cute-re size-8 animate-spin text-white/80" />
385+
)}
386+
</div>
387+
</TransformComponent>
388+
</TransformWrapper>
367389
)}
368390
{isAllError && (
369391
<div

pnpm-lock.yaml

Lines changed: 19 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)