drawImage()方法图片不显示

canvas有个很强大的api是drawImage()(w3c):
他的主要功能就是绘制图片、视频,甚至其他画布等。

问题:
慕名赶来,却一脚踩空,低头一看,地上一个大坑。
事情是这样的,在我看完w3c的介绍和很有说服力和教学力的demo后,本着实践出真知的思想决定上手一试,这一试不要紧~

我按照流水线工程铺设以下几点基本工作:

  1. canvas标签+id

  1. 获取canvas+设置宽高

var cav1 = document.getElementById(‘canvas1’),
wWidth = 800,
wHeight = 600;
cav1.width = wWidth;
cav1.height = wHeight;

  1. getContext(‘2d’)准备画布

var ctx1 = cav1.getContext(‘2d’);

  1. new一个Image()对象,并付给他我喜欢…的图片(别想多了)的属性

var bgImg = new Image();
bgImg.src = ‘images/background.jpg’;

  1. 终于到了绘图。兴冲冲的写下这段代码:

ctx1.drawImage(bgImg,0,0,wWidth,wHeight);

代码写错了,再回去仔细检查一遍,没错啊。
复制w3c的关键属性名及方法再检查一遍,确实没错啊。
图片打印出来,也有这个(人)图啊!

后来观察w3c的案例,和我代码的区别就是他的图片是在html里边的。
然后我就学着向html里边插入了图片,

并且用getElementById获取这个元素,

var bgImg = document.getElementById(‘imgs’)

再次执行绘图竟然可以了。

他竟然可以了!
难过的想,就必须要实体吗?不就是放到了canvas标签前边嘛!js加载也有实体啊,而且我还是用new的啊,比真人差哪了!

对啊,不就是放到前边了嘛。这就涉及到一个顺序问题啊!
js里加载的图片是放在绘图前边没错,但是图片加载进来还需要个时间啊。需要给图片缓冲的时间。
等图片加载成功后才可以进行绘制。
而drawImage这个方法,当图片在没加载完的情况下使用,他会不被调用。绘制就会失败。
原来如此!

就有人抬杠说img标签里的图片不需要时间加载吗?这时候drawImage就不受限制了?!
但是你不要忽略了,js开头的 window.onload 的啊,就算图片加载再慢,就算图片标签的顺序在canvas标签的后边,但是我有window.onload罩着,我图片加载不完,你drawImage就没戏啊对不对。
大概顺序是这样的:

window.onload = function(){   drawImage }

如果不是在html结构中插入的图片,就被我的粗心绕过了这个限制:

图片作为一个资源请求,在js中加载时,自然也会有一个图片加载的时间。
但是因为没有限制,极大的情况是当图片还没有加载完毕就调用了drawImage,此方法他是不起作用的。
解决:
那有没有好的方法解决因图片加载顺序导致drawImage绘图失败的情况呢?
我总结了以下三种方法:

  1. 标签+window.onload
window.onload = function(){   context.drawImage() }

这种做法解决的核心是onload,将图片和drawImage分开加载,img先加载,确保加载完毕以后再使用绘图

  1. 定时器异步实现

setTimeout(function(){
ctx1.drawImage(bgImg,0,0,wWidth,wHeight);
},10)

这里为什么延迟写了10,没写大家熟悉的1000或者0呢?
因为在我的特定wifi环境特定台式机电脑的测试下,10能在图片加载完后刚好图片出来,而不像0那样不出来,也不想1000那样等半天出来。
可是试想一下,换一个更大的图,这个10还适用吗?wifi换成2g这个10还适用吗?

所以,定时器的缺点就是,不能保证时间到了以后图片已经加载进来了,网不快的话照样挂掉。
var Menu= function(context){
this.drawIni= function(){
context.clearRect(0,0,512,448);
setTimeout(function(){},1000);
firstImage.onload = function(){
   context.drawImage(firstImage,0,0); 
  };

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值