React与ASP.NET Core中Syncfusion PDF及响应式图片坐标问题求助
问题解答:响应式图片坐标偏移与React展示后端PDF
问题1:响应式图片的坐标偏移处理
预设坐标基于原图尺寸,当图片通过width:100%缩放后,坐标未同步缩放导致点击区域偏移。核心解决思路是动态计算缩放比例,实时更新<area>的coords属性:
实现步骤
- 配置或获取图片的原始宽高
- 监听图片加载完成事件,获取当前渲染的实际宽高
- 计算缩放比例:
scaleX = 实际宽度 / 原图宽度,scaleY = 实际高度 / 原图高度 - 用缩放比例重新计算每个区域的坐标并更新
- 监听窗口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>展示:
实现步骤
- 发送请求时指定响应类型为Blob
- 将返回的Blob转换为临时URL
- 用iframe组件展示该URL
- 组件卸载时释放临时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
相关产品推荐
相关产品推荐

