项目地址
https://github.com/hismeyy/react-component-100
组件描述
组件适用于展示图片的地方,提供了small,medium,large三种大小。可以删除图片,也可以全屏预览图片。
样式展示
前置依赖
今天我们的这个挑战需要用用到了 react-icons
依赖,因此,我们需要先安装它。
# 使用 npm
npm install react-icons# 或者使用 yarn
yarn add react-icons
使用的话,大家可以看这个网站。大家进去可以找需要的图标。具体使用里面有介绍,非常简单。
react-icons 图标
好了,下面我们展示代码。
代码展示
Img.tsx
import { useState } from 'react'
import './Img.css'
import { MdClose } from 'react-icons/md';interface ImgProps {src: string;alt: string;size?: 'small' | 'medium' | 'large';onClose?: () => void;
}const Img = ({ src, alt, size = 'small', onClose }: ImgProps) => {const [showPreview, setShowPreview] = useState(false);const [visible, setVisible] = useState(true);const handleClose = () => {setVisible(false);if (onClose) {onClose();}};if (!visible) return null;return (<div className={`img-container img-${size}`}><button className={`img-close img-close-${size}`} onClick={handleClose}><MdClose /></button><div className={`img img-${size}`} onClick={() => setShowPreview(true)}><img src={src} alt={alt} /></div>{showPreview && (<div className="img-preview-overlay" onClick={() => setShowPreview(false)}><div className="img-preview-content"><img src={src} alt={alt} /></div></div>)}</div>)
}export default Img
Img.css
.img-container {position: relative;
}.img {overflow: hidden;display: flex;align-items: center;justify-content: center;cursor: pointer;border-radius: 5%;
}.img-small {width: 80px;height: 80px;font-size: 10px;
}.img-medium {width: 160px;height: 160px;font-size: 14px;
}.img-large {width: 240px;height: 240px;font-size: 16px;
}.img img {width: 100%;height: 100%;object-fit: cover;object-position: center;
}.img::after {content: "预 览";display: flex;align-items: center;justify-content: center;color: #fff;position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.6);opacity: 0;border-radius: 5%;transition: opacity 0.3s ease;
}.img:hover::after {opacity: 1;
}.img-preview-overlay {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;background-color: rgba(0, 0, 0, 0.9);display: flex;align-items: center;justify-content: center;z-index: 1000;animation: fadeIn 0.3s ease;
}.img-preview-content {max-width: 90%;max-height: 90vh;position: relative;
}.img-preview-content img {max-width: 100%;max-height: 90vh;object-fit: contain;
}@keyframes fadeIn {from {opacity: 0;}to {opacity: 1;}
}.img-close {all: unset;background-color: rgb(114, 114, 114);border-radius: 50%;color: #fff;font-size: 20px;cursor: pointer;display: flex;align-items: center;justify-content: center;font-weight: bold;position: absolute;transition: all 0.3s ease;z-index: 5;
}.img-close:hover {background-color: rgb(82, 82, 82);transform: scale(1.1);
}.img-close-small {width: 10px;height: 10px;top: -2px;right: -2px;font-size: 10px;
}.img-close-medium {width: 15px;height: 15px;top: -3px;right: -3px;font-size: 15px;
}.img-close-large {width: 20px;height: 20px;top: -5px;right: -5px;font-size: 16px;
}
使用
App.tsx
import './App.css'
import Img from './components/img/img01/Img'function App() {const handleImageClose = () => {console.log('图片被关闭了');};return (<><Imgsrc="https://picsum.photos/500/500"alt="Random image"size="large"onClose={handleImageClose}/></>);
}export default App