You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React与ASP.NET Core中Syncfusion PDF及响应式图片坐标问题求助

问题解答:响应式图片坐标偏移与React展示后端PDF

问题1:响应式图片的坐标偏移处理

预设坐标基于原图尺寸,当图片通过width:100%缩放后,坐标未同步缩放导致点击区域偏移。核心解决思路是动态计算缩放比例,实时更新<area>的coords属性:

实现步骤

  1. 配置或获取图片的原始宽高
  2. 监听图片加载完成事件,获取当前渲染的实际宽高
  3. 计算缩放比例:scaleX = 实际宽度 / 原图宽度,scaleY = 实际高度 / 原图高度
  4. 用缩放比例重新计算每个区域的坐标并更新
  5. 监听窗口resize事件,重复上述步骤保证适配

修改后的React组件代码

import { useState, useRef, useEffect } from 'react';
import cmr from './your-image-path.jpg'; // 替换为实际图片路径

function CmrForm() {
  const [selectedIdentifier, setSelectedIdentifier] = useState(null);
  const [scaledAreas, setScaledAreas] = useState([]);
  const imgRef = useRef(null);
  // 替换为你的图片实际原始尺寸
  const originalSize = { width: 1163, height: 653 };

  const handleClick = (event) => {
    const identifier = event.target.getAttribute("data-identifier");
    setSelectedIdentifier(identifier);
    console.log("Identifier of the clicked area:", identifier);
  };

  const formLayout = {
    xlg: 6,
    xl: 9,
    lg: 9,
    md: 6,
    sm: 8,
    xs: 12,
  };

  // 原始坐标数据
  const originalAreas = [
    { coords: "1025,10,1158,52", identifier: "1" },
    { coords: "85,56,619,202", identifier: "2" },
    { coords: "624,56,1163,202", identifier: "3" },
    { coords: "86,204,621,352", identifier: "4" },
    { coords: "621,204,1160,352", identifier: "5" },
    { coords: "87,358,622,453", identifier: "6" },
    { coords: "626,358,1161,453", identifier: "7" },
    { coords: "86,458,624,551", identifier: "8" },
    { coords: "85,555,623,653", identifier: "9" },
    { coords: "624,455,1160,653", identifier: "10" },
  ];

  // 计算缩放后的坐标
  const calculateScaledCoords = () => {
    if (!imgRef.current) return;
    const { width: renderedWidth, height: renderedHeight } = imgRef.current.getBoundingClientRect();
    const scaleX = renderedWidth / originalSize.width;
    const scaleY = renderedHeight / originalSize.height;

    const scaled = originalAreas.map(area => {
      const coordsArr = area.coords.split(',').map(num => parseInt(num));
      const scaledCoords = coordsArr.map((coord, index) => {
        return index % 2 === 0 ? Math.round(coord * scaleX) : Math.round(coord * scaleY);
      }).join(',');
      return { ...area, coords: scaledCoords };
    });
    setScaledAreas(scaled);
  };

  useEffect(() => {
    imgRef.current?.addEventListener('load', calculateScaledCoords);
    window.addEventListener('resize', calculateScaledCoords);
    calculateScaledCoords();

    return () => {
      imgRef.current?.removeEventListener('load', calculateScaledCoords);
      window.removeEventListener('resize', calculateScaledCoords);
    };
  }, []);

  return (
    <div className="padding-10">
      <div style={{ maxWidth: "65%", position: "relative" }}>
        <img
          ref={imgRef}
          src={cmr}
          style={{
            width: "100%",
            height: "auto",
          }}
          useMap="#form"
        />

        <map onClick={handleClick} name="form">
          {scaledAreas.map(area => (
            <area 
              key={area.identifier}
              shape="rect" 
              coords={area.coords} 
              data-identifier={area.identifier} 
            />
          ))}
        </map>
      </div>
      <Col {...formLayout}>
        {selectedIdentifier && <Form1 identifier={selectedIdentifier} />}
      </Col>
    </div>
  );
}

export default CmrForm;

问题2:React处理后端返回的PDF文件并展示

后端返回的是PDF二进制流,React需要正确处理Blob类型响应,通过URL.createObjectURL生成可访问链接,再用<iframe>或<embed>展示:

实现步骤

  1. 发送请求时指定响应类型为Blob
  2. 将返回的Blob转换为临时URL
  3. 用iframe组件展示该URL
  4. 组件卸载时释放临时URL,避免内存泄漏

示例代码

React请求与展示组件

import { useState, useEffect } from 'react';

function PdfViewer() {
  const [pdfUrl, setPdfUrl] = useState(null);

  const fetchPdf = async (id) => {
    try {
      const response = await fetch(`/api/showCmr/${id}`, {
        method: 'POST',
        credentials: 'include', // 需携带认证凭证时开启
        headers: {
          'Content-Type': 'application/json',
          // 添加必要的认证头,比如Authorization
        }
      });

      if (!response.ok) throw new Error('请求失败');
      
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      setPdfUrl(url);
    } catch (error) {
      console.error('获取PDF失败:', error);
    }
  };

  // 组件卸载时释放临时URL
  useEffect(() => {
    return () => {
      if (pdfUrl) URL.revokeObjectURL(pdfUrl);
    };
  }, [pdfUrl]);

  return (
    <div>
      <button onClick={() => fetchPdf(1)}>获取并展示PDF</button>
      {pdfUrl && (
        <iframe 
          src={pdfUrl} 
          width="100%" 
          height="600px" 
          title="PDF Viewer"
          style={{ border: 'none' }}
        />
      )}
    </div>
  );
}

注意事项

  • 若使用axios,需设置responseType: 'blob':
    const response = await axios.post(`/api/showCmr/${id}`, {}, {
      responseType: 'blob',
      withCredentials: true
    });
    const blob = response.data;
    
  • 后端认证逻辑需匹配,确保请求携带正确的凭证

内容的提问来源于stack exchange,提问作者Goktug Baris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:17:06