效果图如下图所示:
代码如下,功能也自行删减:
<template>
<div class="popularize-modal">
<canvas
style="border:1px solid #ededf0;width:240px;height:325px;"
id="tutorial"
width="480"
height="650">
canvas>
<div class="btn-group">
<button class="btn-item" @click="downloadPoster">download海报button>
<button class="btn-item" @click="downloadQrcodeUrl">download二维码button>
<button class="btn-item" @click="copyUrl">copy链接button>
div>
<div class="tip">推广推广推广推广推广div>
div>
template>
<script>
export default {
data() {
return {
shareObj: {
spuImage: 'https://',
title: 'mmmm',
desc: '是的哇 ',
priceStr: '9.41',
qrCodeUrl: 'https://',
shareLink: 'https://'
}
}
},
mounted() {
this.drawCanvas();
},
beforeDestroy() {
this.resetCanvas();
}
methods: {
resetCanvas() {
let canvas = document.getElementById('tutorial');
let ctx = canvas.getContext('2d');
// 复原canvas大小
ctx.scale(0.5, 0.5);
}
drawCanvas() {
let canvas = document.getElementById('tutorial');
//获得 2d 上下文对象
let ctx = canvas.getContext('2d');
// 放大两倍,解决绘制模糊问题,记得卸载或者消失的时候重置大小
ctx.scale(2, 2);
ctx.lineWidth = 1;
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, 480, 650);
let img = new Image(); // 创建img元素
// 图片允许跨域的未经身份验证的下载
img.setAttribute('crossOrigin', 'Anonymous');
img.src = this.shareObj.spuImage; // 设置图片源地址
img.onload = () => {
// 实现图片类似cover剪裁效果
let x = 12; //渲染的坐标
let y = 12;
let canW = 216;
let canH = 184;
const imageWidth = img.width;
const imageHeight = img.height;
const imageRatio = imageWidth / imageHeight;
const canvasRatio = canW / canH;
let sx; let sy; let sHeight; let sWidth;
if (imageRatio < canvasRatio) {
sWidth = imageWidth;
sHeight = sWidth / canvasRatio;
sx = 0;
sy = (imageHeight - sHeight) / 2;
} else {
sHeight = imageHeight;
sWidth = imageHeight * canvasRatio;
sy = 0;
sx = (imageWidth - sWidth) / 2;
}
ctx.drawImage(img, 12, 12, 216, 184);
};
this.drawText(ctx, this.shareObj.title, 12, 195, 216, 14, 2, '#1b1c33');
this.drawText(ctx, this.shareObj.desc, 12, 236, 140, 10, 2, '#8d8e99');
this.drawText(ctx, `¥${this.shareObj.priceStr}`, 12, 280, 140, 20, 2, '#ff4d30');
// 二维码
let qrImg = new Image();
qrImg.setAttribute('crossOrigin', 'Anonymous');
qrImg.src = this.shareObj.qrCodeUrl;
qrImg.onload = () => {
ctx.drawImage(qrImg, 175, 240, 60, 60);
};
this.drawText(ctx, '长按图片识别', 174, 294, 140, 10, 2, '#bdbdbd');
},
// 绘制text换行
// ctx: 画布对象,text: 绘制文本内容, x: x坐标, y: y坐标,
// fongtSize: 需要绘制的字体大小, lineNum: 需要绘制最多行数, fillStyle: 字体颜色
drawText(ctx, text, x, y, w, fontSize, lineNum, fillStyle) {
var chr = text.split('');
var temp = '';
var row = [];
ctx.font = `${fontSize}px Arial`;
ctx.fillStyle = fillStyle;
ctx.textBaseline = 'middle';
for (let i = 0; i < chr.length; i += 1) {
if (ctx.measureText(temp).width < w) {
// doNothing
} else {
row.push(temp);
temp = '';
}
temp += chr[i];
}
row.push(temp);
// 绘制展示的行数
let line = row.length > lineNum ? lineNum : row.length;
for (let i = 0; i < line; i += 1) {
// 这里+4是为了让上下行的间距变大一点,可自行设置
ctx.fillText(row[i], x, y + ((i + 1) * (fontSize + 4)));
}
},
// canvas海报
downloadPoster() {
let canvas = document.getElementById('tutorial');
// 转换成base64格式
let url = canvas.toDataURL('image/png');
let oA = document.createElement('a');
oA.download = `${this.shareObj.title}.png` || 'download.png';// 设置下载的文件名,默认是'download'
oA.href = url;
document.body.appendChild(oA);
oA.click();
oA.remove(); // 下载之后把创建的元素删除
},
// 二维码
downloadQrcodeUrl() {
if (!this.shareObj.qrCodeUrl) {
return 0;
}
var image = new Image();
// 解决跨域 Canvas 污染问题
image.setAttribute('crossOrigin', 'anonymous');
image.src = this.shareObj.qrCodeUrl;
image.onload = () => {
let canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext('2d');
context.drawImage(image, 0, 0, image.width, image.height);
let url = canvas.toDataURL('image/png'); //得到图片的base64编码数据
let oA = document.createElement('a'); // 生成一个a元素
let event = new MouseEvent('click'); // 创建一个单击事件
oA.download = `${this.shareObj.title}.png` || 'download.png'; // 设置图片名称,直接加后缀名称可防止title里面出现.(点) ,而没法生成.png的情况
oA.href = url; // 将生成的URL设置为a.href属性
oA.dispatchEvent(event); // 触发a的单击事件
};
},
// 复制连接
copyUrl() {
let url = this.shareObj.shareLink;
let oInput = document.createElement('input');
oInput.value = url;
document.body.appendChild(oInput);
oInput.select(); // 选择对象;
document.execCommand('Copy'); // 执行浏览器复制命令
oInput.remove();
}
}
}
script>
<style lang="less" scoped>
.popularize-modal {
text-align: center;
.btn-group {
margin-top: 20px;
.btn-item {
margin-right: 16px;
}
}
.tip {
margin-top: 34px;
font-size: 14px;
line-height: 14px;
color: #999;
width: 100%;
text-align: left;
}
}
style>