16.JS | canvas 繪制多圖

“處理圖片是我們普通市民的責任,積累跬步是我本身的興趣,所以加載圖片我每次都跑一次,如果遇到多張圖片的話我還會多跑幾次。”
——題記,改自《破壞之王》

正文

canvas一籮筐問題, 之前一文 JS | canvas 圖片模糊 講了合成圖的模糊,本文講講另一個,canvas繪制多圖,這也是在做H5的過程中遇到的一個坎,比如說合成圖少元素,比如說跨域等。

原始做法:
前提多張圖片,本地開發的時候,通過改變HTML img元素的路徑src(多個img元素在H5已有),進行繪制drawImage,比如說drawImage(document.getElementById('img1'), 0, 0),沒問題,多圖合成圖片效果正常;到了線上,報出一長串紅文,不好意思,您的圖片沒有權限,繪制失敗。ok,跨域么,翻資料,加個crossOrigin,允許跨域請求資源。這個可以一試。

使用其它域名下的圖片
HTMLImageElement上使用crossOrigin屬性,你可以請求加載其它域名上的圖片。如果圖片的服務器允許跨域訪問這個圖片,那么你可以使用這個圖片而不污染canvas,否則,使用這個圖片將會污染canvas

什么是“被污染”的 canvas?
盡管不通過 CORS 就可以在畫布中使用圖片,但是這會污染畫布。一旦畫布被污染,你就無法讀取其數據。例如,你不能再使用畫布的 toBlob(), toDataURL() 或 getImageData()方法,調用它們會拋出安全錯誤。
這種機制可以避免未經許可拉取遠程網站信息而導致的用戶隱私泄露。
[引自MDN]

最后方案(不在H5顯示img元素,從零創建):
通過js創建image對象,對于多張圖片,建立數組,加載完成多張圖片后,進行canvas繪制,后再進行合成圖片。這里有個強調,必須要在加載完成后,方可繪制,也就是說有先后順序,順序沒處理好,可能導致合成的圖片缺頭少尾,甚至空白。這里利用jquery的deffered來處理先后順序問題。

若調用 drawImage時,圖片沒加載完,那什么都不會發生(在一些舊的瀏覽器中可能會拋出異常)。

代碼如下:

//預加載
function preloadImg(list, imgs) {
  var def = $.Deferred(),
      len = list.length;
  $(list).each(function(i,e) {    
    var img = new Image(); 
    img.crossOrigin = ""; //跨域請求資源
    img.onload = (function(j) {
      return function() {
        imgs[j] = img
        len--;
        if(len == 0) {  def.resolve();  }
      };
    })(i);
    img.onerror = function() {
      len--;
      alert('fail to load image');
    };
    img.src = e; // 確保緩存的圖片也觸發 load 事件
  });
  console.log(def.promise())
  return def.promise();
}
$.when(preloadImg(list, imgs)).done(
  function() {
    draw事件
})

參考文章
https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Using_images

image.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一:canvas簡介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標簽 ②:HTML5 ...
    GreenHand1閱讀 4,718評論 2 32
  • 一、圖形的組合方式 globalAlpha是一個介于0和1之間的值(包括0和1),用于指定所有繪制的透明度。默認值...
    空谷悠閱讀 1,314評論 0 0
  • 線條樣式 繪制直線,第五章知識簡單回顧 lineWidth 設置或返回當前的線條寬度,單位為像素 lineCap ...
    Zd_silent閱讀 499評論 0 0
  • 弧度與sin及cos的關系 目的: 通過理解弧度與sin及cos的關系,可以根據弧度及半徑求出旋轉指定弧度后所到達...
    IOLG閱讀 2,086評論 0 0
  • 一、canvas簡介 1.1 什么是canvas?(了解) 是HTML5提供的一種新標簽 Canvas是一個矩形區...
    J_L_L閱讀 1,557評論 0 4