详解canvas drawImage()方式绘图照片无法显示的难题

日期:2021-02-27 类型:科技新闻 

关键词:网站建设,创建网站,免费建站平台,智能建站,企业建网站

canvas有个很强劲的api是drawImage()(w3c):

他的关键作用便是绘图照片、视頻,乃至别的画布等。

难题:

慕名赶来,却1脚踩空,低下头1看,地面上1个大坑。

事儿是这样的,在我看完w3c的详细介绍和很有说动力和课堂教学力的demo后,本着实践活动出真谛的观念决策上手1试,这1试没事儿~

我依照流水线工程项目铺设下列几点基础工作中:

1. canvas标识+id

<canvas id="canvas1"></canvas>

2. 获得canvas+设定宽高

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

3. getContext('2d')提前准备画布

var ctx1 = cav1.getContext('2d');

4. new1个Image()目标,并付给他我喜爱...的照片(别想多了)的特性

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

5. 终究到了制图。笑容满面的写下这段编码:

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

流着哈喇子,我在访问器按下了F5。

随后1片死寂...

认为编码写错了,再回去细心查验1遍,没错啊。

拷贝w3c的重要特性名及方式再查验1遍,的确没错啊。

照片复印出来,也是有这个(人)图啊!

后来观查w3c的实例,和我编码的差别便是他的照片是在html里面的。

随后我就学着向html里面插进了照片,

<img src="./images/background.jpg" id="imgs" style="display:none"></img>

而且用getElementById获得这个元素,

var bgImg = document.getElementById('imgs')

再度实行制图居然能够了。

他居然能够了!

难过的想,就务必要实体线吗?不便是放到了canvas标识前边嘛!js载入也是有实体线啊,并且我還是用new的啊,比真人差哪了!

对啊,不便是放到前边了嘛。这就涉及到到1个次序难题啊!

js里载入的照片是放在制图前边没错,可是照片载入进来还必须个時间啊。必须给照片缓存的時间。等照片载入取得成功后才能够开展绘图。而drawImage这个方式,当照片在没载入完的状况下应用,他会不被启用。绘图就会不成功。原先这般!

就有人抬杠说img标识里的照片不必须時间载入吗?这时候候drawImage就不会受到限定了?!可是你不必忽视了,js开始的 window.onload 的啊,即使照片载入再慢,即使照片标识的次序在canvas标识的后面,可是我有window.onload罩着,我照片载入不完,你drawImage就没戏啊对不对。

大约次序是这样的:

<img src="">
window.onload = function(){
  drawImage
}

假如并不是在html构造中插进的照片,就被我的粗心大意绕开了这个限定:

照片做为1个資源恳求,在js中载入时,当然也会有1个照片载入的時间。

可是由于沒有限定,巨大的状况是当照片都还没载入结束就启用了drawImage,此方式他是不起功效的。

处理:

那有木有好的方式处理因照片载入次序致使drawImage制图不成功的状况呢?

我总结了下列3种方式:

1. 标识+window.onload

<img src="">
window.onload = function(){
  context.drawImage()
}

这类做法处理的关键是onload,将照片和drawImage分开载入,img先载入,保证载入结束之后再应用制图

 1⑵. 后期插进标识?是不是可行

有1种状况是,应用截图作用时,还可以用drawImage,而截图又不并不是截自身既有的照片,而是用1个照片的详细地址当主要参数.

我想这类的就必须js来建立1个img,并将详细地址赋给它.随后转化成照片再来截图了

var myImg = document.createElement('img');
myImg.src = '///';
document.body.appendChild(myImg);
ctx1.drawImage(myImg,0,0,wWidth,wHeight);

不想加过剩的标识?必要像下边这样用js来new1个image目标?

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

前边说了,这类应用 new Image() 建立的照片,必须给照片缓存的時间。等照片载入取得成功后才能够开展绘图。

照片目标是提前准备好了,但你如何了解照片何时真的载入进行呢?好,也有方法:

js每日任务实行中,你嫌我离你实行的時间太近是不,那把我独立拎出来再次排长队,等会再实行能够否?

2. 定时执行器多线程完成

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

这里为何延迟时间写了10,没写大伙儿熟习的1000或0呢?

由于在我的特殊wifi自然环境特殊台式机电工程脑的检测下,10能在照片载入完后恰好照片出来,而不像0那样不出来,也不想1000那样等半天出来。

但是试想1下,换1个更大的图,这个10还可用吗?wifi换为2g这个10还可用吗?

因此,定时执行器的缺陷便是,不可以确保時间到了之后照片早已载入进来了,网不快的话照样挂掉。

3. img.onload

window.onload给了大家思路,立即监视他载入进行不能以了嘛

应用img的载入恶性事件,监视照片载入取得成功后,再实行canvas的制图实际效果.而且这类方式可靠1些。

bgImg.onload = function(){
     console.log('照片载入取得成功');
     console.log(this);
     ctx1.drawImage(bgImg,0,0,wWidth,wHeight);
 }

实际上这3种方式全是1个关键,便是让照片先载入。即照片预载入。可是针对缓存文件照片,照片预载入还必须处理的是,当网页页面不更新时监视缓存文件照片的难题。

又发现1个难题。。。。最先,情况绘画完的模样长这样。

随后总算情况绘画出来了,我就开高兴心的再次吧。

因而我紧接着画了1条红线,以便防止看不见,我还把宽度提升到了20:

bgImg.onload = function(){
    ctx1.drawImage(bgImg,0,0,wWidth,wHeight);
  }
  /* 绘图红线以下: */
  ctx1.beginPath();
  ctx1.moveTo(10,wHeight);
  ctx1.lineTo(10,wHeight⑴00);

  ctx1.lineWidth = 20;
  ctx1.strokeStyle = 'red';

  ctx1.stroke();
  ctx1.closePath();

但我F5按下依然沒有转变,還是看不见红线。

找了半天直至我把情况图关闭才看到:

啊,原先他被情况图盖住啦!

但是,为何呢?

我在想有两种将会

1、等级难题

2、前后难题

有关1,就像css的z-index那种觉得,是情况图在上盖住了红线。难道说说情况图的等级比红线高?

这个构想我无法检测,因而舍弃开展第2种将会的揭密。

但是为何情况图会在上呢?是由于情况图后画?

这个能够最简单的根据console.log()复印观查实行次序

原先“元凶”居然是onload这个回调函数。他跟定时执行器1样,全是1个多线程每日任务。当然排在了同歩每日任务(下边的绘图线条)的后面

因此前边看似是1个很好的处理方式——onload,在这里也曝露了他的缺点。

很好、来看,promise学习培训大计宜尽早提上日程啊!哈哈哈

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。

上一篇:IE9下html5初试小刀 返回下一篇:没有了