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

使用JavaScript向HTML Canvas插入图片不显示问题求助

Canvas图片不显示问题修复方案

问题原因

你的代码存在三个核心问题:

  • 没有在draw函数中应用缩放和平移变换,scale、translatePos参数完全没有被使用,缩放拖拽逻辑失效
  • 图片加载是异步操作,你每次调用draw都会重新创建Image实例发起请求,图片加载完成的时机晚于draw函数执行,导致首次渲染看不到图片
  • 绘制图片时没有做画布状态管理,也没有适配变换后的坐标,就算图片加载出来也不会显示在预期位置

修复后的完整代码

HTML代码

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

<body onmousedown="return false;">
  <div id="wrapper">
    <canvas id="myCanvas" width="578" height="200">
  </canvas>
    <div id="buttonWrapper">
      <input type="button" id="plus" value="+"><input type="button" id="minus" value="-">
    </div>
  </div>
  <h2 id="status">
    0, 0
  </h2>
</body>

CSS代码

body {
  margin: 0px;
  padding: 0px;
}

#wrapper {
  position: relative;
  border: 1px solid #9C9898;
  width: 578px;
  height: 200px;
}

#buttonWrapper {
  position: absolute;
  width: 30px;
  top: 2px;
  right: 2px;
}

input[type="button"] {
  padding: 5px;
  width: 30px;
  margin: 0px 0px 2px 0px;
}

JS代码

// 提前预加载图片,避免每次重绘都重新请求
let base_image = new Image();
base_image.src = 'https://www.gstatic.com/webp/gallery3/1.sm.png';
// 图片加载完成后再触发首次绘制
let imgLoaded = false;
base_image.onload = function() {
  imgLoaded = true;
  draw(scale, translatePos);
}

let translatePos;
let scale = 1.0;
const scaleMultiplier = 0.8;

function draw(scale, translatePos) {
  // 图片未加载完成直接返回
  if(!imgLoaded) return;
  var canvas = document.getElementById("myCanvas");
  var context = canvas.getContext("2d");
  
  // 清空画布
  context.clearRect(0, 0, canvas.width, canvas.height);
  // 保存当前上下文状态
  context.save();
  // 应用平移和缩放变换
  context.translate(translatePos.x, translatePos.y);
  context.scale(scale, scale);
  // 绘制图片,调整偏移量让图片居中对齐
  context.drawImage(base_image, -base_image.width/2, -base_image.height/2);
  // 恢复上下文状态,避免后续操作叠加变换
  context.restore();
}

window.onload = function() {
  var canvas = document.getElementById("myCanvas");

  translatePos = {
    x: canvas.width / 2,
    y: canvas.height / 2
  };

  var startDragOffset = {};
  var mouseDown = false;

  // 缩放按钮事件
  document.getElementById("plus").addEventListener("click", function() {
    scale /= scaleMultiplier;
    draw(scale, translatePos);
  }, false);

  document.getElementById("minus").addEventListener("click", function() {
    scale *= scaleMultiplier;
    draw(scale, translatePos);
  }, false);

  // 拖拽事件
  canvas.addEventListener("mousedown", function(evt) {
    mouseDown = true;
    startDragOffset.x = evt.clientX - translatePos.x;
    startDragOffset.y = evt.clientY - translatePos.y;
  });

  canvas.addEventListener("mouseup", function(evt) {
    mouseDown = false;
  });

  canvas.addEventListener("mouseover", function(evt) {
    mouseDown = false;
  });

  canvas.addEventListener("mouseout", function(evt) {
    mouseDown = false;
  });

  canvas.addEventListener("mousemove", function(evt) {
    if (mouseDown) {
      translatePos.x = evt.clientX - startDragOffset.x;
      translatePos.y = evt.clientY - startDragOffset.y;
      draw(scale, translatePos);
    }
  });
};

jQuery(document).ready(function() {
  $("#wrapper").mousemove(function(e) {
    $('#status').html(e.pageX + ', ' + e.pageY);
  });
})

额外优化说明

  • 把鼠标坐标监听的mouseover改成了mousemove,坐标会跟随鼠标移动实时更新,更符合使用习惯
  • 增加了图片加载完成标识,避免图片加载完成前执行绘制逻辑报错
  • 每次重绘前清空画布,避免缩放拖拽时出现重影

内容的提问来源于stack exchange,提问作者Zubair Nazer Oliyat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:06:05