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

Safari中Canvas绘制图片尺寸偏大与Chrome显示不一致问题

Safari下Canvas绘制图片尺寸偏大问题解决方案

不需要将图片上传至imgur,更换图片存储位置完全无法解决该兼容问题。该问题的核心原因是你没有处理高分屏的设备像素比适配,加上Safari对图片原始尺寸的读取逻辑和Chrome存在差异,和图片存本地还是存图床没有关联。


问题根源

  • 现有Canvas初始化逻辑只设置了Canvas标签的像素宽高,没有区分CSS显示尺寸和实际渲染像素尺寸,在Retina等高分辨率屏幕下,Safari的默认像素比缩放逻辑和Chrome不一致,会导致绘制出来的元素尺寸出现偏差
  • 代码中读取图片尺寸用的是image.width,部分版本Safari在图片未完全完成解码时,该属性返回值和实际原始尺寸存在偏差,应该使用naturalWidth/naturalHeight读取图片的真实原始像素尺寸

修复步骤

1. 替换Canvas初始化及窗口resize逻辑

新增设备像素比适配,保证两个浏览器下Canvas的渲染基准一致:

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");

function resizeCanvas() {
  const dpr = window.devicePixelRatio || 1;
  // 设置Canvas的CSS显示尺寸为窗口大小
  c.style.width = `${window.innerWidth}px`;
  c.style.height = `${window.innerHeight}px`;
  // 按设备像素比设置Canvas实际渲染像素尺寸,避免高分屏模糊/尺寸偏差
  c.width = window.innerWidth * dpr;
  c.height = window.innerHeight * dpr;
  // 缩放上下文,后续绘制逻辑不需要额外调整坐标计算规则
  ctx.scale(dpr, dpr);
}

// 初始化执行
resizeCanvas();
window.addEventListener("resize", resizeCanvas);

2. 调整城堡类的图片尺寸读取逻辑

将图片尺寸读取属性替换为naturalWidth/naturalHeight,保证所有浏览器下拿到的图片原始尺寸一致:

class castle {
  constructor() {
    const castle = new Image()
    castle.src = './Img/castle.png'

    castle.onload = () => {
      this.scale = 0.5
      this.image = castle
      // 读取图片原始自然尺寸,兼容全浏览器
      this.width = this.image.naturalWidth * this.scale
      this.height = this.image.naturalHeight * this.scale
      this.position = {
        x: window.innerWidth / 2 - this.width / 2,
        y: window.innerHeight / 2 - this.height / 2
      }

      this.center = {
        x: window.innerWidth / 2,
        y: window.innerHeight / 2
      }
    }
  }

  draw() {
    ctx.drawImage(
      this.image,
      this.position.x,
      this.position.y,
      this.width,
      this.height
    )
  }
}

注意事项

  • 所有绘制逻辑中的坐标、尺寸计算,统一以window.innerWidth/innerHeight作为视口基准,不要直接读取c.width/c.height做计算——适配设备像素比后,c的实际像素宽高是乘以dpr后的值,直接使用会导致尺寸计算错误
  • 调整代码后先清空浏览器缓存再测试,避免旧的图片资源、脚本缓存导致异常复现
  • 如果项目中有多个Canvas绘制元素,所有图片资源的尺寸读取都建议替换为naturalWidth/naturalHeight,避免同类问题出现

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:06:23