后台返回一张图片,还返回一组坐标,在前端展示图片,并把返回的坐标在图片对应的位置画出来
坐标的数据结构:
rect:{width:100,height:100,left:50,top:50}
把图片当作背景放在一个固定宽高的盒子里,上面放一层绝对定位的盒子
获取图片信息
对比图片与盒子的宽高比并计算出图片相对于盒子边缘的位置(留白)
计算坐标点所在的位置
根据计算后的位置动态的修改绝对定位的盒子。
应该就三种情况,左右留白,上下留白,以及刚刚好的。
背景图填充成这样的css属性是:
background-size: "contain",
<div
className={styles.bg}
style={{
width:'500px',
height: '300px'
backgroundImage: `这里是后台返回的图片信息的图片路径`,
backgroundRepeat: "no-repeat",
backgroundSize: "contain",
backgroundPosition: "center",
}}
>
<div
style={{
display: `${position.width ? "block" : "none"}`,
position: "absolute",
border: "3px solid red",
width: `${position.width}px`,
height: `${position.height}px`,
top: `${position.top}px`,
left: `${position.left}px`,
}}
/>
</div>
</div>
// 存放计算后的矩形框的位置
const [position, setPosition] = useState<{
width: number;
height: number;
left: number;
top: number;
}>({ width: 0, height: 0, left: 0, top: 0 });
let imageInfo = 后台返回的数据信息
let oImg = new Image();
oImg.src = imageInfo.url; // 图片路径;
oImg.onload = function () {
let oImgW = oImg.naturalWidth;// 图片的实际宽度
let oImgH = oImg.naturalHeight;// 图片的实际高度
// 计算矩形框
let { width, height, left, top } = calculateRectProportion(
500,// 盒子的宽度
300,// 盒子的高度
oImgW,
oImgH,
imageInfo.rectModel.width,// 矩形框宽
imageInfo.rectModel.height,// 矩形框高
imageInfo.rectModel.left,// 矩形框left
imageInfo.rectModel.top// 矩形框top
);
setPosition({ width, height, left, top });
};
function calculateRectProportion(
boxW: number,
boxH: number,
conW: number,
conH: number,
rectW: number,
rectH: number,
rectL: number,
rectT: number
) {
/*
boxW:盒子宽
boxH:盒子高
conW:内容宽
conH:内容高
rectW:矩形宽
rectH:矩形高
rectL:矩形距离图片左边距离
rectT:矩形距离图片顶部距离
*/
// 计算盒子宽高比,一般都是宽大于高,宽高比小于1
let boxAspectRatio = boxW / boxH;
// 计算内容宽高比较
let conAspectRatio = conW / conH;
// 比较盒子和内容宽高比的大小,如大于0,则为垂直居中,上下留白,繁殖水平居中,左右留白
let compareSizeBoxConAspectRatio = conAspectRatio - boxAspectRatio;
// 计算留白宽高及内容在盒子中显示的宽高
let leaveBlankW = 0;
let leaveBlankH = 0;
let showConInBoxW = 0;
let showConInBoxH = 0;
if (compareSizeBoxConAspectRatio > 0) {
// 大于零,上下留白,左右充满
leaveBlankW = 0;
leaveBlankH = ((1 / boxAspectRatio - 1 / conAspectRatio) / 2) * boxW;
showConInBoxW = boxW;
showConInBoxH = boxW / conAspectRatio;
} else if (compareSizeBoxConAspectRatio < 0) {
// 小于0,左右留白,上下充满
leaveBlankW = ((boxAspectRatio - conAspectRatio) / 2) * boxH;
leaveBlankH = 0;
showConInBoxW = boxH * conAspectRatio;
showConInBoxH = boxH;
} else {
leaveBlankW = 0;
leaveBlankH = 0;
showConInBoxW = boxW;
showConInBoxH = boxH;
}
// 计算矩形框宽高
let realRectW = (showConInBoxW * rectW) / conW;
let realRectH = (showConInBoxH * rectH) / conH;
// 计算矩形距离盒子的距离,同上边宽高
let realRectL = 0;
let realRectT = 0;
if (compareSizeBoxConAspectRatio > 0) {
realRectL = (showConInBoxW * rectL) / conW;
realRectT = leaveBlankH + (showConInBoxH * rectT) / conH;
} else if (compareSizeBoxConAspectRatio < 0) {
realRectL = leaveBlankW + (showConInBoxW * rectL) / conW;
realRectT = (showConInBoxH * rectT) / conH;
} else {
leaveBlankW = (showConInBoxW * rectL) / conW;
leaveBlankH = (showConInBoxH * rectT) / conH;
}
return {
width: realRectW,
height: realRectH,
left: realRectL,
top: realRectT,
};
}