最近作了一个生成海报并上传到七牛上的功能,前端生成图片须要用到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`。其余参数会被忽略。
在测试中遇到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() }) }) } } }