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

仅Safari中Canvas绘图导致包裹div无法调整大小问题求助

问题:Safari 14.0.3中,含绘图操作Canvas的可调整大小Div失效

我用div包裹canvas元素,给外层div设置了resize: both和overflow: auto样式,该功能在Chrome中正常工作,但在Safari 14.0.3里,只要对canvas执行绘图操作(比如clearRect、设置fillStyle),div就无法调整大小,鼠标悬停右下角调整区域时光标也不会变化。注释掉绘图相关的useEffect代码后,Safari中的div又能正常调整大小。我的应用需要支持在canvas上绘图,canvas还监听了mousemove、mousedown、mouseup事件。

代码示例:

function Base() {

  React.useEffect(() => {
    const canvas = document.getElementById("covering-canvas-11");
    const context = canvas.getContext("2d");

    console.log("context for convercaning canvas 11 is ", context);

    if (context) {
      context.clearRect(0, 0, 40, 40);
      context.fillStyle = "white";
    }
  });

  return (
    <div>
        <div
          style={{
            resize: "both",
            overflow: "auto",
            background: "#ccc",
            width: "40px",
            height: "40px",
          }}
        >
          <canvas id={`covering-canvas-11`} width="40px" height="40px"></canvas>
        </div>
    </div>
  );
}
ReactDOM.render(
  <Base />,
  document.getElementById('root')
);

解决方案

这是Safari的已知渲染Bug:当canvas内容被修改后,浏览器会错误地提升canvas元素的层级,遮挡住父div的resize控制点。可通过以下方式修复:

  • 调整层级关系:给父div添加position: relative和z-index: 1,同时给canvas设置position: relative和更低的z-index: 0,强制让父div的层级高于canvas,确保resize控制点能被鼠标捕获。修改后的代码片段:

    <div
      style={{
        resize: "both",
        overflow: "auto",
        background: "#ccc",
        width: "40px",
        height: "40px",
        position: "relative",
        zIndex: 1
      }}
    >
      <canvas 
        id={`covering-canvas-11`} 
        width="40px" 
        height="40px"
        style={{position: "relative", zIndex: 0}}
      ></canvas>
    </div>
    
  • 添加透明伪元素遮罩:给父div添加一个透明的伪元素覆盖层,不影响canvas交互但能确保resize控制点正常工作。先定义CSS类:

    .resize-container::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      pointer-events: none;
    }
    

    再给父div添加该类,并设置position: relative。

  • 优化useEffect执行逻辑:原代码的useEffect无依赖数组,会在每次组件渲染时重复执行绘图操作,加重Safari的渲染异常。添加空依赖数组让它只执行一次:

    React.useEffect(() => {
      // 绘图代码
    }, []);
    

    减少不必要的canvas重绘,降低触发Bug的概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:02:22