Skip to content

Commit

Permalink
feat: image zoom
Browse files Browse the repository at this point in the history
close #1183
  • Loading branch information
hyoban committed Nov 13, 2024
1 parent 1d77c09 commit 4b5b603
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 43 deletions.
1 change: 1 addition & 0 deletions apps/renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"react-selecto": "^1.26.3",
"react-shadow": "20.5.0",
"react-virtuoso": "4.12.0",
"react-zoom-pan-pinch": "^3.6.1",
"rehype-infer-description-meta": "2.0.0",
"rehype-parse": "9.0.1",
"rehype-sanitize": "6.0.0",
Expand Down
94 changes: 55 additions & 39 deletions apps/renderer/src/components/ui/media/preview-media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { FC } from "react"
import { Fragment, useCallback, useEffect, useRef, useState } from "react"
import { Blurhash } from "react-blurhash"
import { useTranslation } from "react-i18next"
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch"
import { Keyboard, Mousewheel } from "swiper/modules"
import type { SwiperRef } from "swiper/react"
import { Swiper, SwiperSlide } from "swiper/react"
Expand Down Expand Up @@ -322,48 +323,63 @@ const FallbackableImage: FC<

const { height: windowHeight, width: windowWidth } = useWindowSize()

const wrapperClass = cn("relative !max-h-full", width <= height && "!h-full")
const wrapperStyle = {
// px-20 pb-8 pt-10
width:
width && height && width > height
? `${Math.min((windowHeight - 32 - 40) * (width / height), width)}px`
: undefined,
maxWidth: width > height ? `${windowWidth - 80 - 80 - 400}px` : undefined,
}

return (
<div className={cn("center flex size-full flex-col", containerClassName)}>
<div
className={cn("center flex size-full flex-col", containerClassName)}
onClick={stopPropagation}
>
{!isAllError && (
<div
className={cn("relative max-h-full", width <= height && "h-full")}
style={{
// px-20 pb-8 pt-10
width:
width && height && width > height
? `${Math.min((windowHeight - 32 - 40) * (width / height), width)}px`
: undefined,
maxWidth: width > height ? `${windowWidth - 80 - 80 - 400}px` : undefined,
}}
>
<img
data-blurhash={blurhash}
src={currentSrc}
onLoad={() => setIsLoading(false)}
onError={handleError}
height={props.height}
width={props.width}
{...props}
className={cn(
"transition-opacity duration-700",
isLoading ? "opacity-0" : "opacity-100",
props.className,
)}
style={props.style}
/>
<div
className={cn(
"center absolute inset-0 size-full transition-opacity duration-700",
isLoading ? "opacity-100" : "opacity-0",
)}
<TransformWrapper wheel={{ step: 1 }}>
<TransformComponent
wrapperClass={wrapperClass}
wrapperStyle={wrapperStyle}
contentClass={wrapperClass}
contentStyle={wrapperStyle}
>
{blurhash ? (
<Blurhash hash={blurhash} resolutionX={32} resolutionY={32} className="!size-full" />
) : (
<i className="i-mgc-loading-3-cute-re size-8 animate-spin text-white/80" />
)}
</div>
</div>
<img
data-blurhash={blurhash}
src={currentSrc}
onLoad={() => setIsLoading(false)}
onError={handleError}
height={props.height}
width={props.width}
{...props}
className={cn(
"transition-opacity duration-700",
isLoading ? "opacity-0" : "opacity-100",
props.className,
)}
style={props.style}
/>
<div
className={cn(
"center absolute inset-0 size-full transition-opacity duration-700",
isLoading ? "opacity-100" : "opacity-0",
)}
>
{blurhash ? (
<Blurhash
hash={blurhash}
resolutionX={32}
resolutionY={32}
className="!size-full"
/>
) : (
<i className="i-mgc-loading-3-cute-re size-8 animate-spin text-white/80" />
)}
</div>
</TransformComponent>
</TransformWrapper>
)}
{isAllError && (
<div
Expand Down
23 changes: 19 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4b5b603

Please sign in to comment.