dengrui/components/mosowe-canvas-image/mosowe-canvas-image.vue

454 lines
11 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- mosowe-canvas-image -->
<template>
<view class='mosowe-canvas-image'>
<view class="slot-view" @click="createCanvas">
<slot></slot>
</view>
<view class="canvas-wrap-box">
<!-- 主面板绘制 -->
<canvas class="canvas-wrap" canvas-id="canvas" :style="'width: '+ width +'px; height: '+ height +'px;'"></canvas>
<!-- 这个是用来绘制圆形图片的 -->
<canvas class="canvas-wrap" canvas-id="canvas-arc" :style="'width: '+ canvasArcWidth +'px; height: '+ canvasArcHeight +'px;'"></canvas>
</view>
</view>
</template>
<script>
import QR from './wxqrcode.js';
export default {
name: 'mosowe-canvas-image',
components: {},
props: {
imgType: { // 图片类型
type: String,
default: 'jpg',
validator: () => {
return ['jpg', 'png'];
}
},
compress: { // 是否开启压缩
type: Boolean,
default: false
},
compressSize: { // 压缩界限超过界限压缩默认2M
type: [Number, String],
default: 1024*1024*2
},
showPreview: { // 生成图像后是否预览
type: Boolean,
default: false
},
height: { // canvas高度
type: [String, Number],
default: 200
},
width: { // canvas宽度
type: [String, Number],
default: 200
},
lists: {
type: Array,
default: () => {
return [];
}
}
},
data () {
return {
canvas: null,
listsIndex: 0,
listsLength: 0,
canvasArc: null,
canvasArcWidth: 100,
canvasArcHeight: 100,
compressQuality: 20,
compressQualityH5: 5,
};
},
watch: {},
// 组件实例化之前
beforeCreate () {},
// 组件创建完成
created () {
this.canvas = uni.createCanvasContext('canvas', this);
this.canvasArc = uni.createCanvasContext('canvas-arc', this);
},
// 组件挂载之前
beforeMount () {},
// 组件挂载之后
mounted () {},
// 组件数据更新时
beforeUpdate () {},
// 组价更新
updated () {},
// 组件销毁前
beforeDestroy () {},
// 组件销毁后
destroyed () {},
// 页面方法
methods: {
// 开始绘制
createCanvas () {
this.clearCanvas();
if (this.lists.length === 0) {
uni.showToast({
title: 'lists不能为空',
icon: 'none'
});
return;
}
this.listsIndex = 0;
this.listsLength = this.lists.length - 1;
uni.showToast({
title:'正在生成图片...',
icon:'loading'
})
this.dataDrawCanvas();
},
// 数据绘制
dataDrawCanvas () {
let item = this.lists[this.listsIndex];
if (item.type === 'image') { // 图片
if (item.content.indexOf('https://') > -1) { // https://网络图片
// #ifndef H5
// 非H5
this.downloadImageNotH5(item);
// #endif
// #ifdef H5
// H5
this.downloadImageH5(item);
// #endif
} else { // 本地选择图片
if (this.compress && item.hasOwnProperty('file') && item.file.size > this.compressSize) { // 大于限制2M压缩
this.compressImage(item);
} else {
if (item.arc) {
this.drawImageArc(item);
} else {
this.drawImage(item);
}
}
}
} else if (item.type === 'text') { // 文本
this.drawText(item);
} else if (item.type === 'rect') { // 矩形(线条)
this.drawRect(item);
} else if (item.type === 'arc') { // 圆形
this.drawArc(item);
} else if (item.type === 'qr') { // 二维码
this.drawQR(item);
}
},
// #ifndef H5
// https图片下载本地并绘制非H5
downloadImageNotH5 (item) {
uni.downloadFile({
url: item.content,
header: {
'Access-Control-Allow-Origin': '*',
},
success: (res) => {
item.content = res.tempFilePath;
if (item.arc) {
this.drawImageArc(item);
} else {
this.drawImage(item);
}
},
fail: (res) => {
// console.log(res);
}
});
},
// #endif
// #ifdef H5
// https图片下载本地并绘制H5
downloadImageH5 (item) {
let image = null;
image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.crossOrigin = 'Anonymous';
image.src = item.content;
image.onload = () => {
let canvas = document.createElement('canvas');
canvas.width = item.width;
canvas.height = item.height;
let ctx = canvas.getContext('2d');
ctx.drawImage(
image,
0,
0,
item.width,
item.height
);
let dataURL = canvas.toDataURL('image/png');
if (item.arc) { // 绘制圆形
item.content = dataURL;
this.drawImageArc(item);
} else {
this.canvas.globalAlpha = item.hasOwnProperty('globalAlpha') ? item.globalAlpha : 1;
this.canvas.drawImage(
dataURL,
item.x,
item.y,
item.hasOwnProperty('width') ? item.width : this.width,
item.hasOwnProperty('height') ? item.height : this.height
);
this.checkDrawOver();
}
};
},
// #endif
// 图片压缩
compressImage (item) {
// uni.showLoading({
// title: '压缩中...',
// mask: true
// });
uni.showToast({
title: '压缩中...',
icon:'loading'
})
// 非H5压缩
// #ifndef H5
uni.compressImage({
src: item.content,
quality: this.compressQuality,
success: (res) => {
// uni.showLoading({
// title: '正在生成图片...',
// mask: true
// });
uni.showToast({
title: '正在生成图片...',
icon:'loading'
})
item.content = res.tempFilePath;
if (item.arc) {
this.drawImageArc(item);
} else {
this.drawImage(item);
}
},
fail: (res) => {
// console.log(res);
uni.showToast({
title: '压缩失败',
icon: 'none'
});
}
});
// #endif
// H5压缩
// #ifdef H5
let image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.crossOrigin = 'Anonymous';
image.src = item.content;
image.onload = () => {
let canvas = document.createElement('canvas');
canvas.width = item.width;
canvas.height = item.height;
let ctx = canvas.getContext('2d');
ctx.drawImage(
image,
0,
0,
item.width,
item.height
);
let dataURL = canvas.toDataURL('image/png');
item.content = dataURL;
if (item.arc) {
this.drawImageArc(item);
} else {
this.drawImage(item);
}
};
// #endif
},
// 圆形图片另外绘制canvas,png格式
drawImageArc (item) {
this.canvasArc.clearRect(0, 0, this.canvasArcWidth, this.canvasArcHeight);
this.canvasArcWidth = item.arcR * 2;
this.canvasArcHeight = item.arcR * 2;
this.canvasArc.save();
let arcT = setTimeout(() => {
clearTimeout(arcT);
this.canvasArc.arc(item.arcR, item.arcR, item.arcR, 0, 2 * Math.PI);
this.canvasArc.clip();
// this.canvasArc.closePath();
this.canvasArc.drawImage(
item.content,
item.arcX,
item.arcY,
item.width,
item.height
);
this.canvasArc.draw(false, setTimeout(() => {
let t = setTimeout(() => {
clearTimeout(t);
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: item.arcR * 2,
height: item.arcR * 2,
fileType: 'png',
canvasId: 'canvas-arc',
success: (res) => {
item.width = item.arcR * 2;
item.height = item.arcR * 2;
item.content = res.tempFilePath;
this.drawImage(item);
},
fail: (res) => {
// console.log(res);
},
complete: () => {
this.canvasArc.restore();
this.canvasArc.fillRect(0, 0, 0, 0);
this.canvasArc.clearRect(0, 0, this.canvasArcWidth, this.canvasArcHeight);
}
}, this);
}, 100);
}));
}, 100);
},
// 图片绘制
drawImage (item) {
this.canvas.globalAlpha = item.hasOwnProperty('globalAlpha') ? item.globalAlpha : 1;
this.canvas.drawImage(
item.content,
item.x,
item.y,
item.hasOwnProperty('width') ? item.width : this.width,
item.hasOwnProperty('height') ? item.height : this.height
);
this.checkDrawOver();
},
// 文本绘制
drawText (item) {
this.canvas.setFillStyle(item.hasOwnProperty('color') ? item.color : '#000000');
this.canvas.setFontSize(item.hasOwnProperty('size')? item.size : 20);
this.canvas.setTextAlign(item.hasOwnProperty('align') ? item.align: 'left');
this.canvas.globalAlpha = item.hasOwnProperty('globalAlpha') ? item.globalAlpha : 1;
if (item.maxWidth) {
this.canvas.fillText(item.content, item.x, item.y, item.maxWidth);
} else {
this.canvas.fillText(item.content, item.x, item.y);
}
this.checkDrawOver();
},
// 矩形(线条)绘制
drawRect (item) {
this.canvas.setFillStyle(item.hasOwnProperty('color') ? item.color : '#000000');
this.canvas.globalAlpha = item.hasOwnProperty('globalAlpha') ? item.globalAlpha : 1;
this.canvas.fillRect(item.x, item.y, item.width, item.height);
this.checkDrawOver();
},
// 圆形绘制
drawArc (item) {
this.canvas.arc(item.arcX, item.arcY, item.arcR, 0, 2 * Math.PI);
this.canvas.setFillStyle(item.hasOwnProperty('color') ? item.color : '#000000');
this.canvas.globalAlpha = item.hasOwnProperty('globalAlpha') ? item.globalAlpha : 1;
this.canvas.fill();
this.canvas.closePath();
this.checkDrawOver();
},
// 二维码绘制
drawQR (item) {
item['qr'] = QR.createQrCodeImg(item.content, {
size: parseInt(300)
});
this.canvas.globalAlpha = item.hasOwnProperty('globalAlpha') ? item.globalAlpha : 1;
this.canvas.drawImage(
item.qr,
item.x,
item.y,
item.hasOwnProperty('width') ? item.width : this.width,
item.hasOwnProperty('height') ? item.height : this.height
);
this.checkDrawOver();
},
// 判断是否绘制完
checkDrawOver () {
if (this.listsIndex < this.listsLength) { // lists未画完
this.listsIndex++;
this.dataDrawCanvas();
} else {
this.canvasImage();
}
},
// 绘制到画布并生成图片
canvasImage () {
this.listsIndex = 0;
this.canvas.draw(false, setTimeout(() => {
setTimeout(() => {
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: Number(this.width),
height: Number(this.height),
fileType: this.imgType,
canvasId: 'canvas',
success: (res) => {
this.$emit('canvasImage', res.tempFilePath);
if (this.showPreview) {
this.showPreviewFn(res.tempFilePath);
}
},
fail: (res) => {
// console.log(res);
},
complete: () => {
// uni.hideLoading();
}
}, this);
}, 500);
}));
},
// 预览图
showPreviewFn (img) {
uni.previewImage({
current: 0,
urls: [img]
});
},
// 清空画布
clearCanvas () {
this.canvas.clearRect(0, 0, this.width, this.height);
},
}
};
</script>
<style lang='scss' scoped>
.mosowe-canvas-image{
overflow: hidden;
.canvas-wrap-box{
overflow: hidden;
height: 0;
width: 0;
position: fixed;
left:200%;
top: 0;
}
.canvas-wrap {
overflow: hidden;
height: 0;
width: 0;
}
}
</style>