html轉canvas的實現方法,並將canvas的base64字符串上傳到七牛雲上

最近作了一個生成海報並上傳到七牛上的功能,前端生成圖片須要用到canvas,可是在項目中效率會很低,因此我找到了一個插件html2canvas,這個插件幫助咱們將html轉成canvas,不須要咱們去繪製了。html

安裝

// Install NPM

npm install --save html2canvas

// Install Yarn

yarn add html2canvas

使用

咱們先將html寫出來,並給要轉換的dom父元素一個id=htmlContent前端

<template>
  <div>
    <!-- 須要轉canvas的區域 -->
    <div id="htmlContent" style="padding: 10px; background: #f5da55">
      <h4 style="color: #000; ">Hello world!</h4>
    </div>
    <!-- end -->
    <div>
        <button @click='html2canvas'>生成canvas</button>
    </div>
  </div>
</template>

接着寫一個html2canvas方法並添加配置,.then裏面返回的就是生成的canvas,注意這裏html2canvas使用的是Promise語法,更多配置項能夠自行查找。ios

<script>
  export default {
    methods: {
      html2canvas () {
        let that = this
        let opts = {
          logging: true, // 啓用日誌記錄以進行調試 (發現加上對去白邊有幫助)
          allowTaint: true, // 否容許跨源圖像污染畫布
          backgroundColor: null, // 解決生成的圖片有白邊
          useCORS: true // 若是截圖的內容裏有圖片,解決文件跨域問題
        }
        html2canvas(document.querySelector('#htmlContent'), opts).then((canvas) => {
          let url = canvas.toDataURL('image/png')
          that.dataURL = url.split(';base64,')[1]
          document.querySelector('#img').src = url
        })
      },
    }
  }
</script>

拿到canvas以後須要轉換成base64上傳到七牛上面,因此這裏使用到了canvas的toDataURL方法去獲取base64字符串,注意這裏拿到的是';base64,'+字符串,因此須要分割split只要字符串git

canvas.toDataURL(_type_, _encoderOptions_)
* `type`可選

圖片格式,默認爲 `image/png`

* `encoderOptions`可選

在指定圖片格式爲 `image/jpeg 或` `image/webp的狀況下,能夠從 0 到 1 的區間內選擇圖片的質量`。若是超出取值範圍,將會使用默認值 `0.92`。其餘參數會被忽略。

ios13.4.1中失效的問題

在測試中遇到html2canvas的坑,在ios13.4.1版本中部分手機失效,去github上查詢發現是html2canvas@1.0.0-rc.5版本包有問題,將html2canvas回退版本到1.0.0-rc.4就行了
github issuegithub

上傳七牛雲

拿到base64了須要上傳到七牛雲上,七牛文檔提供了這個接口web

function putb64(){
  var pic = "填寫你的base64後的字符串";
  var url = "http://upload.qiniup.com/putb64/20264"; //非華東空間須要根據注意事項 1 修改上傳域名
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange=function(){
    if (xhr.readyState==4){
      document.getElementById("myDiv").innerHTML=xhr.responseText;
    }
  }
  xhr.open("POST", url, true);
  xhr.setRequestHeader("Content-Type", "application/octet-stream");
  xhr.setRequestHeader("Authorization", "UpToken 填寫你從服務端獲取的上傳token");
  xhr.send(pic);
}

我項目裏使用的axios,因此也將axios用法po出來
在上傳以前先請求後臺接口拿到token,這裏用到 async/await,而後設置headers,七牛的域名拼接上res.key'https://xxx.com/' + res.key就是圖片的地址啦。npm

async putb64 () {
  await this.getToken()
  let that = this
  let pic = this.dataURL
  let url = this.up_host + '/putb64/-1'
  http.post(url, pic, {
    headers: {
      'Content-Type': 'application/octet-stream',
      'Authorization': 'UpToken ' + this.token
    }
  })
    .then(res => {
      that.screenImgUrl = 'https://xxx.com/' + res.key + '?imageView2/0/w/1280/h/720'
      that.$emit('handleGetUrl', this.screenImgUrl)
    })
},
getToken () {
  let params = {
    bucket: 'bucket',
    file_name: 'test/' + new Date().getTime() + '.png'
  }
  return new Promise((resolve, reject) => {
    http.get('/qn/sign/v3', { params: params })
      .then(res => {
        this.token = res.token
        this.up_host = res.up_host
        resolve()
      })
  })
}

完整代碼

<template>
  <div>
    <!-- 須要轉canvas的區域 -->
    <div id="htmlContent" style="padding: 10px; background: #f5da55">
      <h4 style="color: #000; ">Hello world!</h4>
    </div>
    <!-- end -->
    <div>
        <button @click='html2canvas'>生成canvas</button>
    </div>
  </div>
</template>
<script>
  export default {
    data () {
      dataURL: '',
      up_host: '',
      token: ''
    },
    methods: {
        html2canvas () {
          let that = this
          let opts = {
            logging: true, // 啓用日誌記錄以進行調試 (發現加上對去白邊有幫助)
            allowTaint: true, // 否容許跨源圖像污染畫布
            backgroundColor: null, // 解決生成的圖片有白邊
            useCORS: true // 若是截圖的內容裏有圖片,解決文件跨域問題
          }
          html2canvas(document.querySelector('#htmlContent'), opts).then((canvas) => {
            let url = canvas.toDataURL('image/png')
            that.dataURL = url.split(';base64,')[1]
            document.querySelector('#img').src = url
          })
        },
        async putb64 () {
          await this.getToken()
          let pic = this.dataURL
          let url = this.up_host + '/putb64/-1'
          http.post(url, pic, {
            headers: {
              'Content-Type': 'application/octet-stream',
              'Authorization': 'UpToken ' + this.token
            }
          })
            .then(res => {
              this.screenImgUrl = 'https://xxx.com/' + res.key + '?imageView2/0/w/1280/h/720'
              this.$emit('handleGetUrl', this.screenImgUrl)
            })
        },
        getToken () {
          let params = {
            bucket: 'bucket',
            file_name: 'test/' + new Date().getTime() + '.png'
          }
          return new Promise((resolve, reject) => {
            http.get('/qn/sign/v3', { params: params })
              .then(res => {
                this.token = res.token
                this.up_host = res.up_host
                resolve()
              })
          })
        }
    }
  }
相關文章
相關標籤/搜索