根据返回的图片和坐标,画出在图片上的对应的矩形框

需求

后台返回一张图片,还返回一组坐标,在前端展示图片,并把返回的坐标在图片对应的位置画出来

坐标的数据结构:rect:{width:100,height:100,left:50,top:50}

思路

把图片当作背景放在一个固定宽高的盒子里,上面放一层绝对定位的盒子
获取图片信息
对比图片与盒子的宽高比并计算出图片相对于盒子边缘的位置(留白)
计算坐标点所在的位置
根据计算后的位置动态的修改绝对定位的盒子。

示例图

应该就三种情况,左右留白,上下留白,以及刚刚好的。

背景图填充成这样的css属性是:background-size: "contain",

代码

dom结构
<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,
  };
}

主要是后面这个计算方法,不好的是需要固定盒子的宽高,如果盒子宽高有变化,就要重新计算。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值