概述
客户需求,需要一个用户自己上传图片,功能不大,思路得清楚,前背景不动,后背景(用户上传的图片)可以移动,缩放,最后根据用户缩放图片的把整个页面绘制成海报,上传服务器,用户可以保存。页面不多,没有引入UI库,有用到的可以参考看一下
详细
客户需求,需要一个用户自己上传图片,功能不大,思路得清楚,前背景不动,后背景(用户上传的图片)可以移动,缩放,最后根据用户缩放图片的把整个页面绘制成海报,上传服务器,用户可以保存。页面不多,没有引入UI库,有用到的可以参考看一下。
next文件有线上的代码,把
depro
字短设置false和true,可以切换本地测试,还是线上用户自己上传图片
html2canvas针对线上的图片,本地测试存在跨域问题
全demo一共四个页面
演示图(引导页):
演示图(上传,拖拽,裁剪,生成海报)
部分代码:
index
<template>
<div style="width: 100%;height: 100%;background: #eee" ref="imageWrapper">
<div class="xj" v-if="show">
<div class="upload">
<input type="file" accept="image/gif,image/jpeg,image/jpg,image/png" @change="changeImage($event)">
<img src="../../assets/xj.png" alt="">
</div>
</div>
<div class="name" v-if="!show">
<span style="color: #ec550b">{{option.name}}</span>
<span style="color: #ec550b;padding-top: 7px">恭喜您成为第{{num}}位代言人</span>
</div>
<div class="btn" v-if="show">
<span @click="btn()">生 成 海 报</span>
</div>
<div>
<div class="bg"></div>
<div class="box" >
<!-- rotate(' + angle + 'deg)'-->
<img
:src="img"
class="pic"
id="pic"
:style="{'transform': 'translate('+ posX + 'px,' + posY + 'px) translateZ(0px) scale(' + dis + ') '}"
/>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import AlloyFinger from "../../utils/alloyfinger";
import html2canvas from "html2canvas"
var url = "http://hb.8sdy.cn"
export default {
name: "next",
data() {
return {
depro:true,
show:true,
option: {},
posX: 0,
posY: 0,
dis: 1,
angle: 0,
img: "",
images: "",
imgUrl:"",
num:""
}
},
created() {
this.option = this.$route.query;
},
mounted() {
this.getData();
},
methods: {
toImage(id) {
html2canvas(this.$refs.imageWrapper).then(canvas => {
let dataURL = canvas.toDataURL("image/png");
this.imgUrl = dataURL;
if (this.imgUrl !== "") {
sessionStorage.setItem('img',dataURL);
this.$router.push({path: "/poster",
query: {
id: id,
}})
// this.dialogTableVisible = true;
}
});
},
getData() {
let that = this;
let element = document.getElementById("pic");
this.af = new AlloyFinger(element, {
// rotate: function (evt) {
// console.log("实现旋转");
// that.angle += evt.angle;
// },
pinch: function (evt) {
console.log("实现缩放");
that.dis = evt.zoom;
},
pressMove: function (evt) {
console.log("实现移动");
that.posX += evt.deltaX;
that.posY += evt.deltaY;
},
tap: function (evt) {
console.log("单击");
//点按触发
},
doubleTap: function (e) {
console.log("双击");
//双击屏幕触发
},
longTap: function (e) {
console.log("长按");
//长按屏幕750ms触发
},
swipe: function (e) {
//e.direction代表滑动的方向
console.log("swipe" + e.direction);
},
});
},
changeImage(e) {
//假数据
if(this.depro){
this.img = require("../../assets/demo.jpg")
return
}
//正式的
let that = this
let file = e.target.files[0]
let formdata = new FormData();
let config = {
headers: {
'Content-Type': 'multipart/form-data'
}
};
formdata.append('file', file);
axios.post(url + '/index/index/upload', formdata, config
).then(function (response) {
if (response.data.code == 1) {
that.img = url + response.data.data
that.images = response.data.data
} else {
alert(response.data.msg)
}
}).catch(function (error) {
console.log(error);
});
},
btn() {
if(this.depro){
this.show = false
this.num = 10
setTimeout(()=>{
this.toImage(10);
this.show = true
},200)
return
}
this.show = false
let that = this
if (that.images == "") {
this.show = true
alert("请上传图片")
return
}
axios.post(url + "/index/index/add", {
name: that.option.name,
worknum: that.option.num,
mechanism: that.option.jigou,
images: that.images,
})
.then(function (response) {
console.log(response)
that.num = response.data.data.id
setTimeout(()=>{
that.toImage(response.data.data.id);
that.show = true
},200)
})
.catch(function (error) {
this.show = true
console.log(error);
});
}
}
}
</script>
<style scoped>
.bg {
background: url("../../assets/bg3.png") no-repeat;
background-size: 100% 100%;
width: 100%;
height: 100%;
position: absolute;
pointer-events: none;
z-index: 9;
}
.box {
width: 100vw;
height: 100vh;
overflow: hidden;
text-align: center;
}
.pic {
width: 30rem;
margin: 2rem auto;
}
.name{
display: flex;
flex-flow: column;
position: absolute;
bottom: 140px;
/*left: 15px;*/
z-index: 999;
width: 100%;
align-items: center;
}
.name span{
font-size: 17px;
}
.xj {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
position: absolute;
top: 160px;
z-index: 999;
}
.xj img {
width: 50px;
height: 50px;
}
.upload {
width: 50px;
height: 50px;
position: relative;
}
.upload input {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
}
.btn {
position: fixed;
bottom: 10px;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
z-index: 99;
}
.btn span {
width: 90%;
background: #FFFFFF;
height: 45px;
line-height: 45px;
border-radius: 25px;
color: #000;
text-align: center;
font-size: 18px;
font-weight: bold;
}
</style>
form页面
<template>
<div class="bg">
<div class="lists">
<div class="list">
<span>工号</span>
<input type="text" v-model="num" placeholder="请输入工号">
</div>
<div class="list">
<span>姓名</span>
<input type="text" v-model="name" placeholder="请输入姓名">
</div>
<div class="list">
<span>机构</span>
<input type="text" v-model="jigou" placeholder="请输入机构">
</div>
<div class="btn">
<span @click="goPage('/next')"> 下 一 步 </span>
</div>
</div>
<div class="toast" v-show="toastShow">
{{toastText}}
</div>
</div>
</template>
<script>
export default {
name: "form",
data() {
return {
toastShow: false,
toastText: '',
num:"",
name:"",
jigou:""
}
},
methods: {
goPage(url) {
if (this.num == ""){
this.toast('请输入工号')
return
}
if (this.name == ""){
this.toast('请输入姓名')
return
}
if (this.jigou == ""){
this.toast('请输入机构')
return
}
let that = this
this.$router.push({path: url,query: {
num: that.num,
name:that.name,
jigou:that.jigou
}})
},
toast (e) {
let self = this
self.toastText = e
self.toastShow = true
setTimeout(function(){
self.toastShow = false
}, 1500)
}
}
}
</script>
<style scoped>
.bg {
background: url("../../assets/bg4.jpeg") no-repeat;
background-size: cover;
width: 100%;
height: 100%;
}
.lists {
width: 100%;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
height: 100%;
}
.list {
display: flex;
width: 100%;
margin-bottom: 30px;
align-items: center;
}
.list span {
text-align: right;
padding-right: 5%;
color: #FFFFFF;
font-size: 15px;
padding-left: 8%;
}
.list input {
width: 70%;
background: transparent;
outline: none;
border: 1px solid #EEE;
padding: 10px 10px;
box-sizing: border-box;
color: #FFFFFF;
font-size: 15px;
border-radius: 4px;
}
input::-webkit-input-placeholder {
color: #FFFFFF;
}
.btn {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
.btn span {
width: 85%;
background: #FFFFFF;
height: 40px;
line-height: 40px;
border-radius: 20px;
color: #000;
text-align: center;
font-size: 16px;
font-weight: bold;
}
.toast{
position: fixed;
z-index: 2000;
left: 50%;
top:45%;
transition:all .5s;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
-o-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
text-align: center;
border-radius: 5px;
color:#FFF;
background: rgba(17, 17, 17, 0.7);
height: 45px;
line-height: 45px;
padding: 0 15px;
max-width: 150px;
}
</style>
程序可以理解成一个活动demo,有需要的可以参考一下