bug:后台返的网络图片路径保存不下来,返回base64格式即可
保存图片的方式
import html2canvas from “html2canvas”;
// 点击上传,获取图片url
toImg() {
let that = this
html2canvas(document.querySelector('.leftimg')).then(canvas => {
let imgUrl = canvas.toDataURL('image/png');
console.log(imgUrl);
that.dataURL = imgUrl; //base64格式
}).catch(error => {})
},
整个制作海报的代码(elementUI,vant上传图片,vue.js)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.2/lib/index.css" />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vant@2.2/lib/vant.min.js"></script>
</head>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
#app {
width: 100%;
height: 100vh;
display: flex;
justify-content: space-between;
}
.left {
background-color: #222D32;
width: 580px;
height: 100vh;
position: relative;
}
.leftimg {
width: 100%;
height: 100%;
}
.left .bgimg {
width: 475px;
height: 808px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.right {
flex: 1;
height: 100vh;
position: relative;
/* padding: 70px; */
}
/* 上传图片 */
.van-uploader__upload {
width: 120px;
height: 120px;
}
.van-uploader__preview-image {
width: 120px;
height: 120px;
}
.name {
position: absolute;
top: 100px;
left: 100px;
}
.Tel {
position: absolute;
top: 150px;
left: 100px;
}
.site {
position: absolute;
top: 200px;
left: 100px;
}
.date {
position: absolute;
top: 250px;
left: 100px;
}
.minTu {
margin-top: 50px;
}
.mintou {
margin-top: 50px;
}
.erweima {
width: 120px;
height: 120px;
position: absolute;
left: 230px;
top: 600px;
}
.tou {
width: 100px;
height: 100px;
position: absolute;
left: 100px;
top: 100px;
border-radius: 50px;
}
.minTu span {
display: block;
height: 50px;
float: left;
margin-right: 10px;
}
.minTu img {
width: 50px;
height: 50px;
}
.mintou img {
width: 50px;
height: 50px;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
/* .ipt {
position: absolute;
left: 165px;
bottom: 27px;
} */
.el-input-number--mini {
margin: 20px 20px 0 0;
}
.input {
margin: 40px 0 0;
}
.btn {
position: absolute;
bottom: 100px;
left: 48%;
}
</style>
<body>
<div id="app">
<div class="left">
<!-- <div class="canvas" ref="canvas"> -->
<div class="leftimg">
<img :src="bgimg[0].content" alt="" class="bgimg" v-if="bgimg[0]" />
<img :src="img1[0].content" alt="" class="tou" v-if="img1[0]" />
<img :src="img2[0].content" alt="" v-if="img2[0]" class="erweima" />
<pre class="name">{{ mingzi }}</pre>
<pre class="Tel">{{ dianhua }}</pre>
<pre class="site">{{ dizhi }}</pre>
<pre class="date">{{ riqi }}</pre>
</div>
<!-- </div> -->
</div>
<div class="right">
<!-- tab切换 -->
<el-menu :default-active="activeIndex2" class="el-menu-demo" mode="horizontal" @select="handleSelect"
background-color="#18BC9C" text-color="#fff" active-text-color="#ffd04b">
<el-menu-item index="1">背景图片</el-menu-item>
<el-submenu index="2">
<template slot="title">头像/二维码</template>
<el-menu-item index="21">头像</el-menu-item>
<el-menu-item index="22">二维码</el-menu-item>
<!-- <el-menu-item index="23">其他</el-menu-item> -->
</el-submenu>
<el-menu-item index="3">添加文本</el-menu-item>
</el-menu>
<!-- 背景图 -->
<div v-if="tab==1" style="padding: 20px;">
<div style="color:#333;margin-bottom:10px;">添加图像</div>
<van-uploader v-model="bgimg" multiple :max-count="1"></van-uploader>
<div class="ipt">
<el-tooltip class="item" effect="dark" content="宽度" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="bgwd" class="bgwd"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="高度" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="bghi" class="bgwd"></el-input-number>
</el-tooltip>
</div>
<img :src="dataURL" alt="" v-if="dataURL">
</div>
<!-- 图像 -->
<div v-if="tab==21" style="padding: 20px;">
<div style="color:#333;margin-bottom:10px;">添加头像</div>
<van-uploader v-model="img1" multiple :max-count="1"></van-uploader>
<div class="ipt">
<el-tooltip class="item" effect="dark" content="宽度" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="touw" class="touw"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="高度" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="touh" class="touh"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="横坐标" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="toux" class="toux"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="纵坐标" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="touy" class="touy"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="圆角弧度" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="tour" class="touy"></el-input-number>
</el-tooltip>
</div>
</div>
<!-- 二维码 -->
<div v-if="tab==22" style="padding: 20px;">
<div style="color:#333;margin-bottom:10px;">添加二维码</div>
<van-uploader v-model="img2" multiple :max-count="1"></van-uploader>
<div class="ipt">
<el-tooltip class="item" effect="dark" content="宽度" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="imgw" class="imgw"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="高度" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="imgh" class="imgh"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="横坐标" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="imgx" class="imgx"></el-input-number>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="纵坐标" placement="top-start">
<el-button>上左</el-button>
<el-input-number size="mini" v-model="imgy" class="imgy"></el-input-number>
</el-tooltip>
</div>
</div>
<!-- 文本 -->
<div v-if="tab==3" style="padding:0 20px 20px;">
<el-input v-model="mingzi" type="textarea" :rows="2" placeholder="名字" class="input">
</el-input>
<!-- 名字纵轴 -->
<el-tooltip class="item" effect="dark" content="横轴" placement="top">
<el-input-number size="mini" v-model="namex" :step="10"></el-input-number>
</el-tooltip>
<!-- 名字横轴 -->
<el-tooltip class="item" effect="dark" content="纵轴" placement="top">
<el-input-number size="mini" v-model="namey" :step="10"></el-input-number>
</el-tooltip>
<!-- 名字体大小 -->
<el-tooltip class="item" effect="dark" content="字体大小" placement="top">
<el-input-number size="mini" v-model="namesize"></el-input-number>
</el-tooltip>
<!-- 字体加粗 -->
<el-checkbox v-model="checked">是否加粗</el-checkbox>
<!-- 颜色 -->
<el-color-picker v-model="color1" size="mini" style="position: relative;top:10px;left:10px;">
</el-color-picker>
<!-- 电话 -->
<el-input v-model="dianhua" type="textarea" :rows="2" placeholder="电话" class="input">
</el-input>
<!-- 电话纵轴 -->
<el-tooltip class="item" effect="dark" content="横轴" placement="top">
<el-input-number size="mini" v-model="TELx" :step="10"></el-input-number>
</el-tooltip>
<!-- 电话横轴 -->
<el-tooltip class="item" effect="dark" content="纵轴" placement="top">
<el-input-number size="mini" v-model="TELy" :step="10"></el-input-number>
</el-tooltip>
<!-- 名字体大小 -->
<el-tooltip class="item" effect="dark" content="字体大小" placement="top">
<el-input-number size="mini" v-model="Telsize1"></el-input-number>
</el-tooltip>
<!-- 字体加粗 -->
<el-checkbox v-model="checked1">是否加粗</el-checkbox>
<!-- 颜色 -->
<el-color-picker v-model="color2" size="mini" style="position: relative;top:10px;left:10px;">
</el-color-picker>
<!-- 地址 -->
<el-input v-model="dizhi" type="textarea" :rows="2" placeholder="地址" class="input">
</el-input>
<!-- 地址纵轴 -->
<el-tooltip class="item" effect="dark" content="横轴" placement="top">
<el-input-number size="mini" v-model="sitex" :step="10"></el-input-number>
</el-tooltip>
<!-- 地址横轴 -->
<el-tooltip class="item" effect="dark" content="纵轴" placement="top">
<el-input-number size="mini" v-model="sitey" :step="10"></el-input-number>
</el-tooltip>
<!-- 名字体大小 -->
<el-tooltip class="item" effect="dark" content="字体大小" placement="top">
<el-input-number size="mini" v-model="sitesize1"></el-input-number>
</el-tooltip>
<!-- 字体加粗 -->
<el-checkbox v-model="checked2">是否加粗</el-checkbox>
<!-- 颜色 -->
<el-color-picker v-model="color3" size="mini" style="position: relative;top:10px;left:10px;">
</el-color-picker>
<el-input v-model="riqi" type="textarea" :rows="2" placeholder="日期" class="input">
</el-input>
<!-- 日期纵轴 -->
<el-tooltip class="item" effect="dark" content="横轴" placement="top">
<el-input-number size="mini" v-model="datex" :step="10"></el-input-number>
</el-tooltip>
<!-- 日期横轴 -->
<el-tooltip class="item" effect="dark" content="纵轴" placement="top">
<el-input-number size="mini" v-model="datey" :step="10"></el-input-number>
</el-tooltip>
<!-- 名字体大小 -->
<el-tooltip class="item" effect="dark" content="字体大小" placement="top">
<el-input-number size="mini" v-model="datesize1"></el-input-number>
</el-tooltip>
<!-- 字体加粗 -->
<el-checkbox v-model="checked3">是否加粗</el-checkbox>
<!-- 颜色 -->
<el-color-picker v-model="color4" size="mini" style="position: relative;top:10px;left:10px;">
</el-color-picker>
</div>
<!-- 上传 -->
<div>
<el-button type="danger" class="btn" @click="toImg">上传<i class="el-icon-upload el-icon--right"></i>
</el-button>
</div>
</div>
</div>
</body>
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- 引入canvas -->
<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js"></script>
<script>
new Vue({
el: "#app",
data: function () {
return {
dataURL: '', //
activeIndex2: '1', //tab切换默认第一个高亮
tab: 1, //当前选中的 1,2,3
bgimg: [], //背景图
bgwd: 475,
bghi: 808,
img1: [], //头像
touw: 100,
touh: 100,
toux: 100,
touy: 100,
tour: 50,
img2: [], //二维码
imgw: 120,
imgh: 120,
imgx: 230,
imgy: 600,
visible: false,
tabPosition: "top",
input10: "",
namex: "100",
TELx: "100",
sitex: "100",
datex: "100",
namey: "100",
TELy: "150",
sitey: "200",
datey: "250",
mingzi: "",
riqi: "",
dizhi: "",
dianhua: "",
namesize: "18",
Telsize1: "18",
sitesize1: "18",
datesize1: "18",
checked: false,
checked1: false,
checked2: false,
checked3: false,
color1: "#333",
color2: "#333",
color3: "#333",
color4: "#333"
};
},
watch: {
bghi(newName, oldName) {
document.querySelector(".bgimg").style.height = newName + "px";
},
bgwd(newName, oldName) {
document.querySelector(".bgimg").style.width = newName + "px";
},
imgw(newName, oldName) {
document.querySelector(".erweima").style.width = newName + "px";
},
imgh(newName, oldName) {
document.querySelector(".erweima").style.height = newName + "px";
},
imgx(newName, oldName) {
document.querySelector(".erweima").style.left = newName + "px";
},
imgy(newName, oldName) {
document.querySelector(".erweima").style.top = newName + "px";
},
touw(newName, oldName) {
document.querySelector(".tou").style.width = newName + "px";
},
touh(newName, oldName) {
document.querySelector(".tou").style.height = newName + "px";
},
toux(newName, oldName) {
document.querySelector(".tou").style.left = newName + "px";
},
touy(newName, oldName) {
document.querySelector(".tou").style.top = newName + "px";
},
tour(newName, oldName) {
document.querySelector(".tou").style.borderRadius = newName + "px";
},
namex(newName, oldName) {
document.querySelector(".name").style.left = newName + "px";
},
namey(newName, oldName) {
document.querySelector(".name").style.top = newName + "px";
},
namesize(newName, oldName) {
document.querySelector(".name").style.fontSize = newName + "px";
},
Telsize1(newName, oldName) {
document.querySelector(".Tel").style.fontSize = newName + "px";
},
sitesize1(newName, oldName) {
document.querySelector(".site").style.fontSize = newName + "px";
},
datesize1(newName, oldName) {
document.querySelector(".date").style.fontSize = newName + "px";
},
checked(newName, oldName) {
if (newName) {
document.querySelector(".name").style.fontWeight = 700;
} else {
document.querySelector(".name").style.fontWeight = 400;
}
},
checked1(newName, oldName) {
if (newName) {
document.querySelector(".Tel").style.fontWeight = 700;
} else {
document.querySelector(".Tel").style.fontWeight = 400;
}
},
checked2(newName, oldName) {
if (newName) {
document.querySelector(".site").style.fontWeight = 700;
} else {
document.querySelector(".site").style.fontWeight = 400;
}
},
checked3(newName, oldName) {
if (newName) {
document.querySelector(".date").style.fontWeight = 700;
} else {
document.querySelector(".date").style.fontWeight = 400;
}
},
color1(newName, oldName) {
document.querySelector(".name").style.color = newName;
},
color2(newName, oldName) {
document.querySelector(".Tel").style.color = newName;
},
color3(newName, oldName) {
document.querySelector(".site").style.color = newName;
},
color4(newName, oldName) {
document.querySelector(".date").style.color = newName;
},
sitex(newName, oldName) {
document.querySelector(".site").style.left = newName + "px";
},
sitey(newName, oldName) {
document.querySelector(".site").style.top = newName + "px";
},
Telx(newName, oldName) {
document.querySelector(".site").style.top = newName + "px";
},
datex(newName, oldName) {
document.querySelector(".date").style.left = newName + "px";
},
datey(newName, oldName) {
document.querySelector(".date").style.top = newName + "px";
},
TELx(newName, oldName) {
document.querySelector(".Tel").style.left = newName + "px";
},
TELy(newName, oldName) {
document.querySelector(".Tel").style.top = newName + "px";
}
},
methods: {
// 点击tab切换
handleSelect(key, keyPath) {
console.log(key, keyPath);
this.tab = key
},
// 点击上传,获取图片url
toImg() {
let that = this
html2canvas(document.querySelector('.leftimg')).then(canvas => {
let imgUrl = canvas.toDataURL('image/png');
console.log(imgUrl);
that.dataURL = imgUrl;
}).catch(error => {})
},
/*将base64转换为file*/
dataURLtoFile(dataurl, filename) { //将base64转换为文件
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], filename, {
type: mime
});
},
// ajax上传图片——文件流方式
upload(base64, name) {
return new Promise((resolve, reject) => {
let file = dataURLtoFile(base64, name);
// 实例化FormData
var formdata = new FormData();
// 将文件信息存入formdata,键名为file
// formdata会将文件信息序列化为ajax可识别的数据类型
formdata.append("file", file);
$.ajax({
type: "post",
url: `${baseURL}/api/common/upload?token=${localStorage.getItem('token')}`,
data: formdata, // formdata直接赋值给data
processData: false, //formdata已将数据序列化,无需在处理
contentType: false, //formdata无需设置请求头
success: function (res) {
resolve(res.data)
}
});
})
}
}
});
</script>
</html>