vue在图片上打标签类似小红书,配合html2canvas截图存储,html2canvas截图后图片丢失只剩标签
1.需求:拿到一张网络图片给他打上标签,标签可以编辑,拖动改变位置,将打完标签的图片传给后端进行存储,效果如下
2.实现:
没有找到合适的插件直接使用,在jquery.image-label.js插件的基础上进行改造使用。
2.1 首先jquery.image-label.js是个js插件,需要将其引入到vue中(jquery.image-label.js下载地址)
import $ from "jquery"
import '@sub/imageLabel/contextmenu.css'
import '@sub/imageLabel/jquery.image-label.css'
import '@sub/imageLabel/jquery.image-label.js'
import '@sub/imageLabel/contextMenu.js'
如此引入会报一个jquery的错误,原因是js文件中没有jquery,所以在需要的俩个js文件最上方引入
import $ from "jquery";
2.2打标签:$(’.image_tofile’).imageLabel(‘create’);
creatLabel(){
$('.image_tofile').imageLabel('create');
},
//删除标签(原js中只支持单个保存,改造了一下可以多个保存,每次删除最后添加的标签)
deleceImgLabel(){
$('.image_tofile').imageLabel('hide');
},
jquery.image-label.js的删除标签改造
2.3 使用html2canvas方法将打完标签后的图片截图传给后端
a.下载依赖:npm install html2canvas
b.引入import html2canvas from ‘html2canvas’
components: {
html2canvas
},
c.使用
saveLabel(){
var that = this;
var container=document.querySelector('.kbs-label-area');//需要截图的dom,由于上面用到标签里面用到的类名就是kbs-label-area
// 第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等
html2canvas(container,{
backgroundColor: "transparent"
}).then(canvas => {
var base64img=canvas.toDataURL();//得到的路径是base64,如果不用给后端传可以就此路径直接渲染
console.log(base64img)
that.filesParmas.files={//这里是传后端服务器用到的参数,根据各自项目需求进行修改
name:that.currentImg.originName,
raw:that.dataURLtoFile(base64img),//后端接口需要文件流,这里转一下
self:true
};
that.multipartUploadPre();
});
},
//将base64转化成文件流
dataURLtoFile(dataurl) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], this.currentImg.originName, { type: mime });//得到的就是file文件流
},
3.坑来了,截图成功后发现图片没有了只剩个标签
解决方法:就是在打标签之前就图片地址转成base64
//打标签方法
creatLabel(){
if(this.dialogImgUrl.indexOf('data:image')==-1){//直接打标签如果发生跨域,就需要先就图片转成base64
tranToBase64(data){
this.getBase64Img({'url':this.addRoutePrefix(this.currentImg.url),'callback':'base64Success'});
},
}else{
$('.image_tofile').imageLabel('create');
}
},
//图片转base64方法
Vue.prototype.getBase64Img = function(params) {
if (params && params.url) {
var that = this;
var image = new Image();
image.src = params.url + "?" + Math.random();
image.crossOrigin = 'anonymous';
image.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, image.width, image.height);
var ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase();
var dataURL = canvas.toDataURL("image/" + ext);//这就是转化后的图片地址
if (params.callback) {
if (params.data) {
that[params.callback](dataURL, params.data);
} else {
that[params.callback](dataURL);
}
};
return dataURL;
}
}
};
//转化图片后的回调(如果是单页面使用就不用封装成公共方法,直接赋值就可以)
base64Success(img,data){
this.dialogImgUrl = img;
if(data&&data=='creat'){
$('.image_tofile').imageLabel('create');
};
},
完美解决!