原逻辑:纭毅YMS加注站点信息中有下载二维码的功能,点击后弹出弹窗,原功能下载二维码仅仅下载二维码图片
优化后:业务提出优化需要连同油站以及站点编码一起下载
参数名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
allowTaint | boolean | false | Whether to allow cross-origin images to taint the canvas—允许跨域 |
background | string | #fff | Canvas background color, if none is specified in DOM. Set undefined for transparent—canvas的背景颜色,如果没有设定默认透明 |
height | boolean | null | Define the heigt of the canvas in pixels. If null, renders with full height of the window.—canvas高度设定 |
letterRendering | boolean | false | Whether to render each letter seperately. Necessary if letter-spacing is used.—在设置了字间距的时候有用 |
logging | boolean | false | Whether to log events in the console.—在console.log()中输出信息 |
proxy | string | undefined | Url to the proxy which is to be used for loading cross-origin images. If left empty, cross-origin images won’t be loaded.—代理地址 |
taintTest | boolean | true | Whether to test each image if it taints the canvas before drawing them—是否在渲染前测试图片 |
timeout | number | 0 | Timeout for loading images, in milliseconds. Setting it to 0 will result in no timeout.—图片加载延迟,默认延迟为0,单位毫秒 |
width | number | null | Define the width of the canvas in pixels. If null, renders with full width of the window.—canvas宽度 |
useCORS | boolean | false | Whether to attempt to load cross-origin images as CORS served, before reverting back to proxy–这个我也不知道是干嘛的 |
// html
<el-dialog :title="$lang('站点二维码')" :width="'500px'" :visible.sync="QrcodeVisible" @close="close" class="qr-dialog" :close-on-click-modal="false">
<div ref="qrCode" id="image" style="width:470px;height:340px;box-sizing: border-box;">
<div class="center">{{stationForm.siteName}}{{stationForm.typeName}}</div>
<img style="width: 300px;margin-left: 80px;" id="imageSelfPd" crossorigin=“anonymous” alt="站点二维码">
<div class="center"><span v-if="stationForm.type !== '3'">{{stationForm.code}}</span><span v-if="stationForm.type === '3'" >{{stationForm.equipId}}</span></div>
</div>
<div slot="footer" class="center">
<el-button @click="close">{{$lang('取消')}}</el-button>
<el-button type="primary" @click="downLoadQrCode" :loading="keyLoading">{{$lang('下载二维码')}}</el-button>
</div>
</el-dialog>
5.1 先下载插件
npm i html2canvas -S
5.2 引入html2canvas
import html2canvas from 'html2canvas';
5.3 图片资源为本地可以直接应用;
图片是网络资源,存在canvas画布话的时候会发生空白,解决办法如下:
(1) 将图片放置服务器,通过nginx进行代理资源,前端访问图片便不涉及到跨域问题(后端配置)
(2) 使用base64图片传输,base64太大不便于传输的话,让后端写一个接口,上传图片base64数据返回图片地址(代码入下)
(3) 属性配置:1. img标签的crossorigin=“anonymous” 2. useCORS: true
getBase64(imgUrl) { // 将图片转为base64格式
window.URL = window.URL || window.webkitURL;
var xhr = new XMLHttpRequest();
xhr.open('get', imgUrl, true);
// 至关重要
xhr.responseType = 'blob';
xhr.onload = function () {
if (this.status === 200) {
// 得到一个blob对象
var blob = this.response;
console.log('blob', blob)
// 至关重要
const oFileReader = new FileReader();
oFileReader.onloadend = function (e) {
// 此处拿到的已经是 base64的图片了
const base64 = e.target.result;
const imgD = document.getElementById('imageSelfPd')
imgD.src = base64 // 将图片的src属性赋值
// console.log(imgD,'imgDimgDimgD');
};
oFileReader.readAsDataURL(blob);
}
}
xhr.send();
},
5.4 使用html2canvas插件画出dom节点,且下载。
downLoadQrCode() {
if (this.QrcodeUrl) {
const dom = document.querySelector('#image').getBoundingClientRect()
const config = {
allowTaint: false, // 开启跨域
useCORS: true, // 图片跨域
width: dom.offsetWidth,
height: dom.offsetHeight
scrollX: 0,
scrollY: 0,
x: 0,
y: 0
}
html2canvas(document.querySelector('#image'), config).then(canvas => {
var mA = document.createElement('a');
mA.href = canvas.toDataURL()
mA.setAttribute('download', '图片canvas.png');
mA.click();
})
}
},
5.5 常见的还有滚动条截图不全问题:
window.pageYoffset = 0;
document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
这种方法本地下载没有问题,构建后有问题,下载的图片是okb的。目前不知道原因。后面使用domtoimage解决了该问题。
移动端使用:
let html2canvas = null;
export default {
beforeMount() {
import('html2canvas').then((plugin) => {
html2canvas = plugin.default;
});
},
methods: {
// 获取分享图片 base64
getShareImgBase64() {
return new Promise((resolve) => {
setTimeout(() => {
// #capture 就是我们要获取截图对应的 DOM 元素选择器
html2canvas(document.querySelector('#capture'), {
useCORS: true, // 【重要】开启跨域配置
scale: window.devicePixelRatio < 3 ? window.devicePixelRatio : 2,
allowTaint: true, // 允许跨域图片
}).then((canvas) => {
const imgData = canvas.toDataURL('image/jpeg', 1.0);
resolve(imgData);
});
}, 300); // 这里加上 300ms 的延迟是为了让 DOM 元素完全渲染完成后再进行图片的生成
});
},
},
};
filter : 过滤器节点中默写不需要的节点;
bgcolor : 图片背景颜色;
height, width : 图片宽高;
style :传入节点的样式,可以是任何有效的样式;
quality : 图片的质量,也就是清晰度;一个介于 0 和 1 之间的数字,表示 JPEG 图像的图像质量(例如 0.92 => 92%)。默认为 1.0 (100%)
cacheBust : 将时间戳加入到图片的url中,相当于添加新的图片;
imagePlaceholder : 图片生成失败时,在图片上面的提示,相当于img标签的alt;
使用:
<!-- 站点二维码 -->
<el-dialog :title="$lang('站点二维码')" :width="'500px'" :visible.sync="QrcodeVisible" @close="close" class="qr-dialog" :close-on-click-modal="false">
<div ref="qrCode" id="image" style="width:480px;height:380px;box-sizing: border-box;padding-top:20px;">
<div class="center">{{stationForm.siteName}}{{stationForm.typeName}}</div>
<img style="display:block;width: 300px;margin: 0 auto;" id="imageSelfPd" :src="QrcodeUrl" crossOrigin="anonymous" alt="站点二维码">
<div class="center"><span v-if="stationForm.type !== '3'">{{stationForm.code}}</span><span v-if="stationForm.type === '3'" >{{stationForm.equipId}}</span></div>
</div>
<div slot="footer" class="center">
<el-button @click="close">{{$lang('取消')}}</el-button>
<el-button type="primary" @click="downLoadQrCode" :loading="keyLoading">{{$lang('下载二维码')}}</el-button>
</div>
</el-dialog>
npm install dom-to-image -S
import domtoimage from 'dom-to-image';
downLoadQrCode() {
if (this.QrcodeUrl) {
var node = document.getElementById('image');
domtoimage.toPng(node, { bgcolor: '#fff' }).then(dataUrl => {
var mA = document.createElement('a');
mA.href = dataUrl
mA.setAttribute('download', '图片canvas.png');
mA.click();
}).catch(error => {
console.error('oops, something went wrong!', error);
});
}
},
可能存在的问题:
使用toPng,结果:图片较为模糊;ios部分背景图片无法显示
import domtoimg from 'dom-to-image';
const node = document.getElementById('root')
try {
let dataUrl = await domtoimg.toPng(node)
// share to app
}catch (){}
使用toJpeg,结果:同toPng
使用toSvg,结果:客户端都显示正常,但友盟不支持svg格式图片分享,将svg转化为png格式后部分背景图片仍然显示异常