css 根据图片大小绘制坐标轴

css 根据图片大小绘制坐标轴

背景:客户要求在展示的图片上绘制网格坐标轴, 并且图片尺寸不固定,根据图片尺寸计算出每个格子的尺寸。
如图
在这里插入图片描述
首先要注意的点

  • 图片的宽高不固定
  • 图片随着屏幕自适应
  • 网格固定分成10块
  • 实时获取当前图片尺寸

代码实现:

// js
  const [offsetHeight, setoffsetHeight] = useState();
  const [offsetWidth, setoffsetWidth] = useState();


// 图片上传/ 回显部分
  <Form
     form={form}
     name="images_form"
     autoComplete="off"
   >

	  <Item noStyle dependencies={['background']}>
	    {({ getFieldValue }) => {
	      const background = getFieldValue('background') as UploadFile[];
	      const { status } = background?.[0] || {};
	      if (background?.length > 0) {
	      // 如果是新上传的图片
	        if (background?.[0].originFileObj) {
	          const fr = new FileReader();
	          fr.readAsDataURL(background?.[0].originFileObj);
	          fr.onload = (e) => {
	            const img = new window.Image();
	            img.src = (e.target?.result || '') as string;
	            document.body.appendChild(img);
	            img.onload = () => {
	              setoffsetHeight(img.offsetHeight);
	              setoffsetWidth(img.offsetWidth);
	              document.body.removeChild(img);
	            };
	          };
	        } else {
	        // 只有图片url时
	          const img = new window.Image();
	          img.src = background[0].url || '';
	          document.body.appendChild(img);
	          img.onload = () => {
	            setoffsetHeight(img.offsetHeight);
	            setoffsetWidth(img.offsetWidth);
	            document.body.removeChild(img);
	          };
	        }
	      }
	
	      return (
	        <Item
	          name="background"
	          rules={[{ required: true, message: '请上传背景图' }]}
	          valuePropName="fileList"
	          style={{ marginBottom: 0 }}
	        >
	          <UploadImg id="images_form_background" maxCount={1}>
	            {uploadButton(status === 'uploading')}
	          </UploadImg>
	        </Item>
	      );
	    }}
	  </Item>
</Form>

// 网格尺寸计算
const generateMultiples = (n: number, is: number) => {
  // 创建一个空数组用于存储结果
  const multiplesArray = [];

  // 使用循环来计算倍数
  for (let i = is; i <= 10; i++) {
    multiplesArray.push(parseInt(n * i, 10));
  }
  return multiplesArray;
};


// 图片展示部分
 <Flex className="preview-image" align="center" justify="center">
   <div className={posterCode ? 'grids' : 'nonegrids'}>
     {
       offsetHeight && offsetWidth && posterCode ? (
         <div>
           <div
             className="preview-image-grid"
             style={{
               backgroundSize: '10% 10%',
             }}
           />
           <div className="preview-image-top">
             {
               generateMultiples(offsetWidth / 10, 1).map(
                 (item) => <div><span>{item}</span></div>,
               )
             }
           </div>
           <div
             className="preview-image-left"
           >
             {
               generateMultiples(offsetHeight / 10, 0).map((item) => <span style={{ display: 'inline-flex' }}>{item}</span>)
             }
           </div>
         </div>
       ) : null
     }

     <Image
       height="100%"
       id="images"
       src={'/XXX/XXXX/imgsrc'}
       fallback={emptyImg}
     />
   </div>
 </Flex>

css

      .preview-image {
        flex: 1 1 auto;
        height: calc(100% - 72px);
        position: relative;
        .ant-image-img {
          width: 100%;
          object-fit: contain;
        }
        .nonegrids {
          width: 100%;
          height: 100%;
        }
        .grids {
          width: 100%;
          height: 100%;
          .preview-image-grid {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            // /*90度直线,100灰度,0.1透明度,5%宽度,0透明度背景*/
            background: linear-gradient(90deg, rgba(0, 0, 0, 0.3) 1%, transparent 1px), 
            /*0度直线,100灰度,0.1透明度,5%宽度,0透明度背景*/
            linear-gradient(rgba(0, 0, 0, 0.3) 1%, transparent 1px);
            // /*横纵向宽距*/
            background-size: 10px 10px;
            font-size: 0;
            text-align: center;
            z-index: 1000 !important;
            border: 0.5 solid #646a73;
          }
          .preview-image-top {
            width: 100%;
            position: absolute;
            top: -15px;
            left: 0;
            font-size: 10px;
            z-index: 1000 !important;
            display: flex;
            flex-direction: row;
            flex-wrap: nowrap;
            div {
              width: 100%;
              text-align: right;
            }
          }
          .preview-image-left {
            position: absolute;
            top: 0;
            left: -17px;
            width: 10px;
            height: 100%;
            font-size: 10px;
            z-index: 1000 !important;
            display: flex;
            flex-wrap: wrap;
            justify-content: flex-end;
            align-content: space-between;
          }
        }
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值