canvas.drawImage()加载问题

银雨星空
  • 19

参考代码

    /** @type {HTMLCanvasElement} */
    let canvas = document.querySelector("#canvs");
    let ctx = canvas.getContext("2d")
    let img = new Image();
    img.src = "img/h.png";
    window.onload = function() {
        ctx.drawImage(img, 108, 101)
    }

网上说因为img加载问题,ctx.drawImage需要使用.complete === true和.onload确定何时准备就绪。
但是有三个疑问:
1.canvas创建和赋值是同步代码,执行到下一行就已经完成,ctx.drawImage所考虑的img的加载是指什么?(对于创建变量,执行js程序,这个加载是啥?)
2.既然用window.onload可以为什么canvas.onload不可以?
3.如果说canvas.onload不可以是因为canvas加载(展示到页面中)时img还没加载,而window.onload是在img加载后执行的,那为什么下面的代码是可行的?此时img才创建,对于ctx.drawImage不就没有加载的机会?

    window.onload = function() {
        let img = new Image();
        img.src = "img/h.png";
        ctx.drawImage(img, 108, 101)
    }//该情况可行。

小白勿喷,十分乐意接受简洁直接或深入底层的讲解,感谢解答!
补充:
已经通过网友宝贵意见,明确了标准写法:(不过,上述问题仍然存在!)

/** @type {HTMLCanvasElement} */
let canvas = document.querySelector("#canvs");
let ctx = canvas.getContext("2d")
let img = new Image();
img.src = "img/h.png";
img.onload = function() {
    ctx.drawImage(img, 108, 101)
}
回复
阅读 635
3 个回答
  1. image 是作为 drawImage 的物料使用的,你既然知道 drawImage 是同步执行的,就应该知道,作为同步代码,它有物料就用,没有就不用,实在不行就抛错;
    所谓巧妇难为无米之炊,你让孩子去买米,总要等他把米带回来,你才能淘米下锅吧。
  2. canvas 只是提供了一个画布,画布本身没有引用任何资源,所以它没有 onload 事件;
    你让二哈帮你去买。二哈:汪汪汪?
  3. 问题 3 中的代码应该是因为 html 中引用了同样的图片资源,window.onload 的时候图片已经被加载到本地了,所以才能第一时间完成图片加载,可以用另外的、未被 html 所引入的图片进行验证。
    而且这可能与浏览器的实现有关,换一个浏览器品牌或者换一个浏览器版本可能就画不出来了。

正确的写法:

let canvas = document.querySelector("#canvs");
let ctx = canvas.getContext("2d")
let img = new Image();
img.src = "img/h.png";
img.onload = function() {
    ctx.drawImage(img, 108, 101)
}

就是要等图片加载完再绘制

你使用 window.onload 也能成功并不是因为用法正确,有两种可能:

  1. 这个图片在页面中有其他 <img/> 标签引用
  2. 图片比较小
  1. img加载就是drawImage所需要的图像源-HTMLImageElement类型。
  2. window.onload 其实此处使用img.onload才是最正确的。至于window为什么可以需要你排查(dom元素也就是img标签有这个图片。最简单的测试你换一个网络大图片 然后window.onload必然不行。行你找我 我说的~~)
  3. 同上
补充说明

这个问题 其实这个也是实现层面的问题
就会给你一个错觉window.onload是否包含image.onload其实并不是的。你要理解一点资源加载(此处)是异步的资源 所以onload并不能很好的表现。
其实如果有一个类似jq的ready() 就很好测试了。可以参考一下讨论:https://github.com/whatwg/htm...
这个也是我让你测试大图片的原因

或者最简单的办法 你写一个window.onload在图片加载之前然后输出图片的加载状态

new Image() 其实更过用途也是图片的预加载=>缓存

明确一点 异步资源例如ajax 还有 资源请求 不会影响onload 但是资源加载可能有网络的原因你需要测试
可以查看 w3c 图片加载属于JavaScript-XMLHttpRequest https://www.w3.org/standards/...

宣传栏