PictrueBrowser 组件
Indicator看之前封装的dots组件
import { FC, useState } from 'react'
import { useEffect } from 'react'
import IconArrowLeft from '@/assets/svg/icon-arrow-left'
import IconArrowRight from '@/assets/svg/icon-arrow-right'
import IconClose from '@/assets/svg/icon-close'
import IconTriangleBottom from '@/assets/svg/icon-triangle-bottom'
import Indicator from '../indicator'
export interface IProps {
pictureUrls?: string[] // 图片数组
closeClick: (e: any) => void // 关闭图片
}
const PictrueBrowser: FC<IProps> = function (props) {
const { pictureUrls, closeClick } = props
// 记录当前浏览的图片
const [currentIndex, setCurrentIndex] = useState(0)
// 当图片展示出来 让滚动功能消失
useEffect(() => {
document.body.style.overflow = 'hidden'
return () => {
// 关闭图片浏览后 恢复默认
document.body.style.overflow = 'auto'
}
}, [])
// 点击控制器切换图片
function controlClickHandle(isNext: boolean) {
let newIndex = isNext ? currentIndex + 1 : currentIndex - 1
if (newIndex < 0) newIndex = pictureUrls?.length! - 1
if (newIndex > pictureUrls?.length! - 1) newIndex = 0
setCurrentIndex(newIndex)
}
return (
<div className="fixed z-[999] left-0 right-0 bottom-0 top-0 bg-[#333] flex flex-col ">
{/* 关闭按钮 设为层级最高 */}
<div className=" relative h-[86px] ">
<div
className=" absolute z-[9999] top-[15px] right-[25px] cursor-pointer"
onClick={closeClick}
>
<IconClose />
</div>
</div>
{/* 图片展示 */}
<div className=" relative flex-1 flex items-center px-[10px]">
{/* 控制器 设为层级第二高 */}
<div className="absolute z-10 top-0 left-0 right-0 bottom-0 flex items-center justify-between w-[100%] text-white ">
<div
className=" cursor-pointer"
onClick={(e) => controlClickHandle(false)}
>
<IconArrowLeft width={77} height={77} />
</div>
<div
className=" cursor-pointer"
onClick={(e) => controlClickHandle(true)}
>
<IconArrowRight width={77} height={77} />
</div>
</div>
{/* 图片 */}
<div className="relative flex h-[100%] overflow-hidden w-[100%] ">
{/* 可以用react-transition-group库来实现切换动画 */}
<img
className=" absolute top-0 left-0 right-0 mx-auto h-[100%] max-w-[105vh] select-none "
src={pictureUrls?.[currentIndex]}
alt=""
/>
</div>
</div>
{/* 指示器 */}
<div className="flex justify-center h-[100px] my-[20px] ">
<div className=" b-[10px] max-w-[105vh] text-white ">
{/* 描述 */}
<div className="flex justify-between ">
<div>
<span>
{currentIndex + 1}/{pictureUrls?.length}
</span>
<span>room apartment图片{currentIndex + 1}</span>
</div>
<div className="flex items-center cursor-pointer ">
<span>隐藏图片列表</span>
<IconTriangleBottom />
</div>
</div>
{/* 图片列表 */}
<div className="mt-2">
<Indicator selectIndex={currentIndex}>
{pictureUrls?.map((item, index) => {
return (
<div
className="mr-[15px] cursor-pointer"
key={item}
onClick={(e) => setCurrentIndex(index)}
>
<img
className="h-[67px] opacity-50"
src={item}
alt=""
style={currentIndex == index ? { opacity: '1' } : {}}
/>
</div>
)
})}
</Indicator>
</div>
</div>
</div>
</div>
)
}
export default PictrueBrowser
// 设置一个方便调试的name 可以不写 默认为组件名称
PictrueBrowser.displayName = 'PictrueBrowser'
使用,点击图片即可预览
import PictrueBrowser from '@/components/picture-browser'
import type { FC } from 'react'
import { useState } from 'react'
import style from './index.module.scss'
export interface IProps {
pictureUrls?: string[]
}
const DetailPicture: FC<IProps> = function (props) {
const { pictureUrls } = props
// 定义是否展示图片浏览 PictrueBrowser
const [showBrowser, setShowBrowser] = useState(false)
// 点击图片展示图片浏览
function showBrowserHandle() {
setShowBrowser(true)
}
return (
<div className={style.wrapper}>
<div className={style.top}>
<div className={style.left}>
<div className={style.item} onClick={showBrowserHandle}>
<img src={pictureUrls?.[0]} alt="" />
<div className={style.cover}></div>
</div>
</div>
<div className={style.right}>
{pictureUrls?.slice(1, 5).map((item, index) => {
return (
<div
className={style.item}
key={item}
onClick={showBrowserHandle}
>
<img src={item} alt="" />
<div className={style.cover}></div>
</div>
)
})}
</div>
</div>
<div className={style.showBtn} onClick={showBrowserHandle}>
查看照片
</div>
{/* 预览图片 */}
{showBrowser && (
<PictrueBrowser
pictureUrls={pictureUrls}
closeClick={(e) => setShowBrowser(false)}
/>
)}
</div>
)
}
export default DetailPicture
// 设置一个方便调试的name 可以不写 默认为组件名称
DetailPicture.displayName = 'DetailPicture'