mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-23 07:26:47 +00:00
Plog 图片组件
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import Head from 'next/head'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
/**
|
||||
* 图片懒加载
|
||||
* @param {*} param0
|
||||
@@ -21,20 +22,21 @@ export default function LazyImage({
|
||||
}) {
|
||||
const maxWidth = siteConfig('IMAGE_COMPRESS_WIDTH')
|
||||
const defaultPlaceholderSrc = siteConfig('IMG_LAZY_LOAD_PLACEHOLDER')
|
||||
|
||||
const imageRef = useRef(null)
|
||||
const [adjustedSrc, setAdjustedSrc] = useState(
|
||||
placeholderSrc || siteConfig('IMG_LAZY_LOAD_PLACEHOLDER')
|
||||
const [currentSrc, setCurrentSrc] = useState(
|
||||
placeholderSrc || defaultPlaceholderSrc
|
||||
)
|
||||
|
||||
if (!placeholderSrc) {
|
||||
placeholderSrc = siteConfig('IMG_LAZY_LOAD_PLACEHOLDER')
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片加载成功回调
|
||||
* 占位图加载成功
|
||||
*/
|
||||
const handleImageLoad = () => {
|
||||
const handleThumbnailLoaded = () => {
|
||||
if (typeof onLoad === 'function') {
|
||||
// onLoad() // 触发传递的onLoad回调函数
|
||||
}
|
||||
}
|
||||
// 原图加载完成
|
||||
const handleImageLoaded = img => {
|
||||
if (typeof onLoad === 'function') {
|
||||
onLoad() // 触发传递的onLoad回调函数
|
||||
}
|
||||
@@ -44,13 +46,27 @@ export default function LazyImage({
|
||||
*/
|
||||
const handleImageError = () => {
|
||||
if (imageRef.current) {
|
||||
imageRef.current.src = defaultPlaceholderSrc
|
||||
// 尝试加载 placeholderSrc,如果失败则加载 defaultPlaceholderSrc
|
||||
if (imageRef.current.src !== placeholderSrc && placeholderSrc) {
|
||||
imageRef.current.src = placeholderSrc
|
||||
} else {
|
||||
imageRef.current.src = defaultPlaceholderSrc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const adjustedImageSrc = adjustImgSize(src, maxWidth)
|
||||
setAdjustedSrc(adjustedImageSrc)
|
||||
const adjustedImageSrc =
|
||||
adjustImgSize(src, maxWidth) || defaultPlaceholderSrc
|
||||
|
||||
// 加载原图
|
||||
const img = new Image()
|
||||
img.src = adjustedImageSrc
|
||||
img.onload = () => {
|
||||
setCurrentSrc(adjustedImageSrc)
|
||||
handleImageLoaded(adjustedImageSrc)
|
||||
}
|
||||
img.onerror = handleImageError
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
entries => {
|
||||
@@ -79,9 +95,9 @@ export default function LazyImage({
|
||||
// 动态添加width、height和className属性,仅在它们为有效值时添加
|
||||
const imgProps = {
|
||||
ref: imageRef,
|
||||
src: priority ? adjustedSrc : placeholderSrc,
|
||||
src: currentSrc,
|
||||
alt: alt,
|
||||
onLoad: handleImageLoad,
|
||||
onLoad: handleThumbnailLoaded, // 缩略图加载完成
|
||||
onError: handleImageError // 添加onError处理函数
|
||||
}
|
||||
|
||||
@@ -106,6 +122,7 @@ export default function LazyImage({
|
||||
if (style) {
|
||||
imgProps.style = style
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
@@ -113,24 +130,25 @@ export default function LazyImage({
|
||||
{/* 预加载 */}
|
||||
{priority && (
|
||||
<Head>
|
||||
<link rel='preload' as='image' href={adjustedSrc} />
|
||||
<link rel='preload' as='image' href={adjustImgSize(src, maxWidth)} />
|
||||
</Head>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据窗口尺寸决定压缩图片宽度
|
||||
* @param {*} src
|
||||
* @param {*} maxWidth
|
||||
* @returns
|
||||
*/
|
||||
|
||||
const adjustImgSize = (src, maxWidth) => {
|
||||
if (!src) {
|
||||
return siteConfig('IMG_LAZY_LOAD_PLACEHOLDER')
|
||||
return null
|
||||
}
|
||||
const screenWidth = window.screen.width
|
||||
const screenWidth =
|
||||
(typeof window !== 'undefined' && window?.screen?.width) || maxWidth
|
||||
|
||||
// 屏幕尺寸大于默认图片尺寸,没必要再压缩
|
||||
if (screenWidth > maxWidth) {
|
||||
|
||||
Reference in New Issue
Block a user