当图片根据宽高比进行伸缩时,图片是最清晰的
代码示例:
import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { Intl } from '@/components/Intl/index';
import style from './index.less';
import { MyIcon } from '../IconFont';
import { IStep } from '../../configs/guide-options';
interface IProps {
isShowGuide: boolean;
onShowGuideHandler: () => void;
guideOptions: (imgRatio: { x: number; y: number }) => IStep;
}
type Props = IProps;
export default function NewGuidelines(props: Props) {
const { isShowGuide, onShowGuideHandler, guideOptions } = props;
const [currentStep, setCurrentStep] = useState(0);
//图片缩放比
const [imgRatio, setImgRatioRatio] = useState({ x: 1, y: 1 });
//图片大小
const [imgSize, setImgSize] = useState({ width: '1440', height: '900' });
useEffect(() => {
if (!isShowGuide) {
setCurrentStep(0);
}
}, [isShowGuide]);
//监听屏幕变化
useEffect(() => {
if (isShowGuide) {
autoResize();
window.addEventListener('resize', autoResize);
} else {
window.removeEventListener('resize', autoResize);
}
return () => {
window.removeEventListener('resize', autoResize);
};
}, [isShowGuide]);
const stepHandler = useCallback(() => {
let tempCurrentStep = currentStep + 1;
if (tempCurrentStep === 8) {
tempCurrentStep = 7;
onShowGuideHandler();
}
setCurrentStep(tempCurrentStep);
}, [currentStep, onShowGuideHandler]);
//进行自适应
const autoResize = useCallback(
(event?, naturalWidth = 1440, naturalHeight = 900) => {
//获取原始图片宽高比,未知情况下可使用naturalWidth|naturalHeight获取
const scale = naturalHeight / naturalWidth;
//获取视口大小
const clientHeight = document.documentElement.clientHeight;
const clientWidth = document.documentElement.clientWidth;
let imgWidth;
let imgHeight;
//当视口宽度大于高度时,图片高度占满,宽度根据缩放比自适应
if (clientWidth > clientHeight) {
imgHeight = clientHeight;
imgWidth = clientHeight / scale;
imgWidth = Math.min(clientWidth, imgWidth);
} else {
//当视口宽度小于高度时,图片宽度占满,高度根据缩放比自适应
imgWidth = clientWidth;
imgHeight = clientWidth * scale;
imgHeight = Math.min(clientHeight, imgHeight);
}
//获取图片伸缩后,和原始图片高宽的比例
let imgRatioX = imgWidth / naturalWidth;
let imgRationY = imgHeight / naturalHeight;
//获取到图片伸缩后和原始图片高宽的比例,就能使得定位在图片上的其他元素,也根据图片变化,即伸缩相对位置不改变
setImgRatioRatio({ x: imgRatioX, y: imgRationY });
setImgSize({ width: imgWidth, height: imgHeight });
},
[]
);
const stepOptions = useMemo(() => guideOptions(imgRatio), [imgRatio]);
const GuideModel = () => {
return (
<div
className={style.guidemodel}
style={stepOptions[currentStep].boxPosition}
>
<div className={style.guideTitle}>
<span>{stepOptions[currentStep].title}</span>
<span
onClick={() => {
onShowGuideHandler();
}}
style={{ cursor: 'pointer' }}
>
<MyIcon type="icon-a-01_line1" />
</span>
</div>
<div className={style.guideDesc}>
<span>{stepOptions[currentStep].text}</span>
</div>
<div className={style.guideFooter}>
<div className={style.guideFooterLeft}>
<div className={style.guideFooterCount}>{currentStep + 1}/8</div>
<div className={style.guideFooterDotted}>
{stepOptions.map((item, index) => (
<div
key={item.text}
className={`${
currentStep === index && style.guideFooterDottedActive
}`}
/>
))}
</div>
</div>
<div className={style.guideFooterBtn} onClick={stepHandler}>
下一步
</div>
</div>
</div>
);
};
return (
<div
className={style.guide}
style={{ display: isShowGuide ? 'block' : 'none' }}
>
<div className={style.guideContainer}>
//设置图片大小
<div
className={style.imgbg}
style={{ width: `${imgSize.width}px`, height: `${imgSize.height}px` }}
>
<img src={stepOptions[currentStep].imgUrl} alt="" />
<GuideModel />
</div>
</div>
</div>
);
}