
4 changed files with 157 additions and 4 deletions
@ -0,0 +1,4 @@ |
|||||
|
export default definePageConfig({ |
||||
|
navigationBarTitleText: '企业采购', |
||||
|
navigationBarTextStyle: 'black' |
||||
|
}) |
@ -0,0 +1,115 @@ |
|||||
|
import { useEffect, useState, useRef } from 'react' |
||||
|
import { Image } from '@nutui/nutui-react-taro' |
||||
|
import { CmsAd } from "@/api/cms/cmsAd/model"; |
||||
|
import { getCmsAd } from "@/api/cms/cmsAd"; |
||||
|
import navTo from "@/utils/common"; |
||||
|
|
||||
|
const NaturalFullscreenBanner = () => { |
||||
|
const [bannerData, setBannerData] = useState<CmsAd | null>(null) |
||||
|
const [isLoading, setIsLoading] = useState(true) |
||||
|
const containerRef = useRef<HTMLDivElement>(null) |
||||
|
const imageRef = useRef<HTMLImageElement>(null) |
||||
|
|
||||
|
// 加载图片数据
|
||||
|
const loadBannerData = () => { |
||||
|
setIsLoading(true) |
||||
|
getCmsAd(447) |
||||
|
.then(data => { |
||||
|
setBannerData(data) |
||||
|
setIsLoading(false) |
||||
|
}) |
||||
|
.catch(error => { |
||||
|
console.error('图片数据加载失败:', error) |
||||
|
setIsLoading(false) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 处理图片加载完成后调整显示方式
|
||||
|
const handleImageLoad = () => { |
||||
|
if (imageRef.current && containerRef.current) { |
||||
|
// 获取图片原始宽高比
|
||||
|
const imgRatio = imageRef.current.naturalWidth / imageRef.current.naturalHeight; |
||||
|
// 获取容器宽高比
|
||||
|
const containerRatio = containerRef.current.offsetWidth / containerRef.current.offsetHeight; |
||||
|
|
||||
|
// 根据比例差异微调显示方式
|
||||
|
if (imgRatio > containerRatio) { |
||||
|
// 图片更宽,适当调整以显示更多垂直内容
|
||||
|
imageRef.current.style.objectPosition = 'center'; |
||||
|
} else { |
||||
|
// 图片更高,适当调整以显示更多水平内容
|
||||
|
imageRef.current.style.objectPosition = 'center'; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 设置全屏尺寸
|
||||
|
useEffect(() => { |
||||
|
const setFullscreenSize = () => { |
||||
|
if (containerRef.current) { |
||||
|
// 减去可能存在的导航栏高度,使显示更自然
|
||||
|
const windowHeight = window.innerHeight - 48; // 假设导航栏高度为48px
|
||||
|
const windowWidth = window.innerWidth; |
||||
|
|
||||
|
containerRef.current.style.height = `${windowHeight}px`; |
||||
|
containerRef.current.style.width = `${windowWidth}px`; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
// 初始化尺寸
|
||||
|
setFullscreenSize(); |
||||
|
|
||||
|
// 监听窗口大小变化
|
||||
|
const resizeHandler = () => setFullscreenSize(); |
||||
|
window.addEventListener('resize', resizeHandler); |
||||
|
return () => window.removeEventListener('resize', resizeHandler); |
||||
|
}, []); |
||||
|
|
||||
|
useEffect(() => { |
||||
|
loadBannerData() |
||||
|
}, []) |
||||
|
|
||||
|
if (isLoading) { |
||||
|
return ( |
||||
|
<div ref={containerRef} className="flex items-center justify-center bg-gray-100"> |
||||
|
<span className="text-gray-500 text-sm">加载中...</span> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
// 获取第一张图片,如果有
|
||||
|
const firstImage = bannerData?.imageList?.[0]; |
||||
|
|
||||
|
if (!firstImage) { |
||||
|
return ( |
||||
|
<div ref={containerRef} className="flex items-center justify-center bg-gray-100"> |
||||
|
<span className="text-gray-500 text-sm">暂无图片数据</span> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
return ( |
||||
|
<div ref={containerRef} className="relative overflow-hidden bg-black"> |
||||
|
<Image |
||||
|
ref={imageRef} |
||||
|
className="absolute inset-0" |
||||
|
src={firstImage.url} |
||||
|
mode={'scaleToFill'} |
||||
|
onClick={() => firstImage.path && navTo(firstImage.path)} |
||||
|
lazyLoad={false} |
||||
|
alt="全屏 banner 图" |
||||
|
onLoad={handleImageLoad} |
||||
|
style={{ |
||||
|
width: '100%', |
||||
|
height: '100%', |
||||
|
// 优先保持比例,只裁剪必要部分
|
||||
|
objectFit: 'cover', |
||||
|
// 默认居中显示,保留图片主体内容
|
||||
|
objectPosition: 'center center' |
||||
|
}} |
||||
|
/> |
||||
|
</div> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
export default NaturalFullscreenBanner |
Loading…
Reference in new issue