mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-03 20:26:36 +08:00
bug处理
This commit is contained in:
@@ -16,29 +16,57 @@ interface ReaderComicProps {
|
||||
onScrolled: () => void
|
||||
}
|
||||
|
||||
function ComicImage({ src, theme }: { src: string; theme: { bg: string; text: string; accent: string } }) {
|
||||
function ComicImage({
|
||||
src,
|
||||
theme,
|
||||
fit = false,
|
||||
}: {
|
||||
src: string
|
||||
theme: { bg: string; text: string; accent: string }
|
||||
// fit:单页模式用。整页缩放至视口内,长图不再被 overflow-hidden 的容器裁掉。
|
||||
fit?: boolean
|
||||
}) {
|
||||
const [state, setState] = useState<'loading' | 'ok' | 'error'>('loading')
|
||||
|
||||
// 换章后 src 变了要重新回到 loading:否则上一章加载失败的第 N 张会一直
|
||||
// 显示「图片加载失败」,而 key 不变(滚动模式按序号做 key)不会重挂载。
|
||||
useEffect(() => {
|
||||
setState('loading')
|
||||
}, [src])
|
||||
|
||||
// <img> 必须始终留在渲染树里(不能 display:none):浏览器不会去拉取
|
||||
// display:none 的 loading="lazy" 图片,onLoad 就永远不会触发,于是更没机会
|
||||
// 脱离 loading —— 之前用 hidden 藏图就死在这里,漫画只剩一个转圈。
|
||||
// 改成图片正常参与布局,未加载时用 minHeight 占位,转圈/失败信息盖在上层。
|
||||
return (
|
||||
<div className="relative w-full">
|
||||
<div
|
||||
className={`relative flex w-full items-center justify-center ${fit ? 'h-full' : ''}`}
|
||||
style={{ backgroundColor: theme.bg }}
|
||||
>
|
||||
<img
|
||||
src={src}
|
||||
loading="lazy"
|
||||
alt=""
|
||||
onLoad={() => setState('ok')}
|
||||
onError={() => setState('error')}
|
||||
className={fit ? 'block max-h-full w-auto max-w-full object-contain' : 'block w-full'}
|
||||
style={state === 'ok' ? undefined : { minHeight: '10rem' }}
|
||||
/>
|
||||
{state === 'loading' && (
|
||||
<div className="flex h-64 w-full items-center justify-center" style={{ color: theme.text }}>
|
||||
<div
|
||||
className="pointer-events-none absolute inset-0 flex items-center justify-center"
|
||||
style={{ color: theme.text }}
|
||||
>
|
||||
<Loader2 className="animate-spin opacity-50" size={22} />
|
||||
</div>
|
||||
)}
|
||||
{state === 'error' ? (
|
||||
<div className="flex h-40 w-full items-center justify-center text-xs opacity-50" style={{ color: theme.text }}>
|
||||
{state === 'error' && (
|
||||
<div
|
||||
className="pointer-events-none absolute inset-0 flex items-center justify-center text-xs opacity-60"
|
||||
style={{ color: theme.text }}
|
||||
>
|
||||
图片加载失败
|
||||
</div>
|
||||
) : (
|
||||
<img
|
||||
src={src}
|
||||
loading="lazy"
|
||||
alt=""
|
||||
onLoad={() => setState('ok')}
|
||||
onError={() => setState('error')}
|
||||
className={`block w-full ${state === 'loading' ? 'hidden' : ''}`}
|
||||
style={{ backgroundColor: theme.bg }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
@@ -83,7 +111,7 @@ export function ReaderComic({ images, theme, mode, page, onZone, initialImage, o
|
||||
const idx = Math.min(Math.max(page, 0), images.length - 1)
|
||||
return (
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<ComicImage key={images[idx]} src={images[idx]} theme={theme} />
|
||||
<ComicImage key={images[idx]} src={images[idx]} theme={theme} fit />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user