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

解决react-map-gl与deck.gl屏幕外地图PDF截图不完整问题

问题原因

大尺寸页面(如A3横向)打印时,jsPDF默认仅能捕获浏览器视口内的内容,而基于WebGL渲染的deck.gl和react-map-gl图层,即便开启preserveDrawingBuffer={true},也会因地图容器尺寸未适配打印需求,只渲染视口可见区域。小尺寸页面能正常工作,是因为其整体尺寸处于浏览器视口范围内。

可行解决方案

1. 临时调整地图容器尺寸适配打印规格

打印前动态将地图容器的宽高修改为目标PDF页面的像素尺寸(需匹配PDF的DPI,比如默认72DPI下,A3横向的像素宽为1654、高为1169),等待地图完整渲染后恢复原尺寸,再执行PDF生成。

示例代码(在PrintMap组件中修改打印逻辑):

const handlePrint = async () => {
  const mapContainer = document.getElementById('map-container');
  const originalStyle = {
    width: mapContainer.style.width,
    height: mapContainer.style.height
  };

  // 按A3横向72DPI设置打印尺寸,可根据选择的页面类型动态切换
  const printDims = { width: 1654, height: 1169 };

  // 临时放大容器
  mapContainer.style.width = `${printDims.width}px`;
  mapContainer.style.height = `${printDims.height}px`;

  // 给deck.gl足够时间渲染完整地图(时间可根据图层复杂度调整)
  await new Promise(resolve => setTimeout(resolve, 600));

  // 生成PDF
  const doc = new jsPDF({
    orientation: 'landscape',
    unit: 'px',
    format: [printDims.width, printDims.height]
  });

  doc.html(mapContainer, {
    callback: (pdf) => {
      pdf.save('map.pdf');
      // 恢复容器原尺寸
      mapContainer.style.width = originalStyle.width;
      mapContainer.style.height = originalStyle.height;
    },
    x: 0,
    y: 0
  });
};

2. 强制地图组件重新渲染

调整容器尺寸后,通过修改组件key的方式,强制react-map-gl和DeckGL重新挂载并渲染完整区域:

示例代码(Map组件):

const Map = ({ isPrinting, printWidth, printHeight }) => {
  const mapStyle = {
    width: isPrinting ? `${printWidth}px` : '100%',
    height: isPrinting ? `${printHeight}px` : '100vh'
  };

  return (
    <div id="map-container" style={mapStyle}>
      <ReactMapGL
        key={isPrinting ? 'print-view' : 'normal-view'}
        preserveDrawingBuffer={true}
        // 其他地图props
      >
        <DeckGL
          key={isPrinting ? 'print-deck' : 'normal-deck'}
          preserveDrawingBuffer={true}
          // 其他DeckGL props
        />
      </ReactMapGL>
    </div>
  );
};

3. 直接捕获DeckGL画布生成图片

跳过DOM捕获,直接提取DeckGL的WebGL画布转为图片,再添加到PDF中,确保内容完整:

示例代码:

const handlePrint = () => {
  const printDims = { width: 1654, height: 1169 };
  const deckCanvas = document.querySelector('.deckgl-overlay canvas');
  
  if (!deckCanvas) return;

  const doc = new jsPDF({
    orientation: 'landscape',
    unit: 'px',
    format: [printDims.width, printDims.height]
  });

  // 把画布转为图片添加到PDF
  const canvasData = deckCanvas.toDataURL('image/png');
  doc.addImage(canvasData, 'PNG', 0, 0, printDims.width, printDims.height);
  doc.save('map.pdf');
};
注意事项
  • 像素尺寸要和PDF的DPI匹配,比如使用300DPI时,A3横向的像素宽为6741、高为4799,需对应调整;
  • 等待渲染的延迟时间需根据地图图层的数量和复杂度调整,避免因渲染未完成导致空白;
  • 确保打印模式下,react-map-gl的viewport覆盖了完整的打印尺寸区域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 00:52:29