記一次營銷活動踩坑

虛光發表於2019-03-07

html2canvas

canvas無法呼叫toDataURL

詳情描述

canvas設定了allowTaint
ps:
allowTaint:Whether to allow cross-origin images to taint the canvas

允許繪製跨域圖片,但是不允許呼叫 canvas.toDataURL
複製程式碼

解決方案

如果需要得到 Base64 的話,不適合開啟 allowTaint
1. 禁用 allowTaint
2. 解決跨域圖片,參考一下個問題
複製程式碼

canvas無法載入跨域圖片

詳情描述

canvas 繪製的時候需要 load 跨域圖片(比如cdn,或者其他域的圖片)

解決方案

在img標籤上面增加 crossorigin="anonymous" 
config 設定 useCORS: true
注意:base64的圖片,不要新增 crossorigin="anonymous" 
複製程式碼

ios 上面偶發截圖不全

詳情描述

在 ios 上面,特別是 iphonex 容易出現偶發截圖不全(某張圖片丟失)
猜測是圖片已經載入完畢,但是還未渲染完畢,就開始轉base64,導致截圖不全(ios特有。。。)
複製程式碼

解決方案

檢視html2canvas 日誌,發現有一個

記一次營銷活動踩坑

有一個圖片的Finished loading鉤子

    在這裡做了一個sleep..
複製程式碼

記一次營銷活動踩坑

圖片丟失狀態(不一定丟失下面你這種,還有可能是背景)

記一次營銷活動踩坑
正常截圖

記一次營銷活動踩坑

pad 寬屏適配

詳情描述

在寬度大於540的機型上面,rem適配失敗,定位不準
複製程式碼

解決方案

    適配的方案是採用的 flexible.js + px2rem,通過觀察flexible原始碼得知
複製程式碼

記一次營銷活動踩坑

    這一段程式碼限定住了html的元素fontSize,因此將if語句中的 540 改為 width 可以完成簡單的適配
複製程式碼

微信/支付寶的sdk差異

需要注意的

1. Wechat可以長按識別base64的圖片,但是其他webview不行
2. 微信不支援canvas跨域載入本地的base64圖片,支付寶可以
3. 微信/支付寶sdk選擇照片返回的是app內的圖片地址,如果想獲得圖片上傳,需要自己轉base64,微信的轉出Base64需要自己新增 data:image/jpeg;base64, 頭部資訊
複製程式碼

分離 Promise 的res,不在 Promise 的建構函式中 res/rej 一個 Promise 物件,封裝一個獲得file的舉例

class myPormise {
  constructor() {
    this.init();
  }
  res(value) {
    this.$r(value);
  }
  init() {
    console.log("初始化promise");
    this.p = new Promise(res => {
      this.$r = res;
    });
  }
}
export class GetInputFile {
  constructor(type) {
    this.inputEle = document.createElement("input");
    this.inputEle.setAttribute("accept", "image/*");
    this.inputEle.setAttribute("type", "file");
    if (type == "camera") {
      //如果是camera則直接呼叫照相機
      this.inputEle.setAttribute("capture", "camera");
    }
    this.inputEle.addEventListener("change", this.uploadFile.bind(this));
    //document.append(this.inputEle);
    this.avatarFile = new myPormise();
    window.inputEle = this.inputEle;
    console.log("建立GetInputFile", this.inputEle);
  }
  click() {
    this.inputEle.click();
    return this;
  }
  uploadFile(e) {
    let files = e.target.files || e.dataTransfer.files;
    if (!files.length) {
      console.log("not image");
      return;
    }
    this.avatarFile.res(files[0]);
  }
  getfile() {
    return this.avatarFile.p;
  }
  destroyed() {
    for (let i in this) {
      if (i !== "destroyed") this[i] = null;
    }
  }
}

export function chooseImageH5(sourceType) {
  const getInputFile = new GetInputFile(sourceType[0]);
  return new Promise(res => {
    console.log("other選擇圖片");
    getInputFile
      .click()
      .getfile()
      .then(e => {
        res(e);
      });
  });
}
複製程式碼