上来就干货!
autograph.vue
<template>
<page-box>
<v-header slot="header" title="确认签名"/>
<p :class="['autograph-tip', {'horizontal': isHorizontalScreen}]">确认无误,请在签名区签名</p>
<div
:class="['canvas-box',{'active': isWarning}, {'horizontal': isHorizontalScreen}]"
ref="canvasBox"
id="canvasBox"
>
<!-- <p class="tip" v-if="!isWarning">签名区</p> -->
</div>
<div slot="footer" :class="['footer', {'horizontal': isHorizontalScreen}]">
<p :class="['warning', {active: isWarning}]">
<span :class="['agree', {active: isAgree}]" @click="isAgree = !isAgree"></span>本人申明:本人已认真核对并确认以上内容真实无误。
</p>
<p class="btn-box">
<a href="javascript:;" class="short-btn reset" @click="resetCanvas">重置</a>
<a
href="javascript:;"
:class="['short-btn', 'submit', {active: isAgree}]"
@click="submit"
>提交</a>
</p>
</div>
</page-box>
</template>
<script>
import { mapGetters } from "vuex";
export default {
data() {
return {
isWarning: false,
isAgree: false,
headerHeight: "46",
canvas: null,
canvasTop: "", //画布上距离
canvasLeft: "", //画布左距离
isHorizontalScreen: false, //是否横屏
ctx: null //画布内容
};
},
mounted() {
this.verticalScreen();
if (/iP(hone|od|ad)/.test(window.navigator.userAgent)) {
//键盘收齐页面空白问题
const scrollHeight =
document.documentElement.scrollTop || document.body.scrollTop || 0;
window.scrollTo(0, Math.max(scrollHeight - 1, 0));
}
window.onresize = () => {
this.verticalScreen();
this.$nextTick(() => {
let canvasBox = this.$refs.canvasBox;
this.canvas.width = canvasBox.offsetWidth;
this.canvas.height = canvasBox.offsetHeight;
let canvasInfo = canvasBox.getBoundingClientRect();
this.canvasTop = Math.round(canvasInfo.top);
this.canvasLeft = Math.round(canvasInfo.left);
this.resetCanvas();
});
};
this.$nextTick(() => {
document.body.addEventListener("touchmove", this.preventDefault, {
passive: false
}); //passive防止阻止默认事件不生效
this.createdCanvas();
});
},
created() {},
computed: {
...mapGetters(["getUserInfo"])
},
methods: {
// 判断手机是横屏还是竖屏
verticalScreen() {
if (window.orientation == 180 || window.orientation == 0) {
// console.log("竖屏状态!");
this.isHorizontalScreen = false;
}
if (window.orientation == 90 || window.orientation == -90) {
// console.log("横屏状态!");
this.isHorizontalScreen = true;
}
},
// 阻止默认事件
preventDefault(event) {
event.preventDefault();
},
// 创建画布
createdCanvas() {
let canvasBox = this.$refs.canvasBox;
// console.log(canvasBox.offsetTop, canvasBox.offsetLeft)
let canvasInfo = canvasBox.getBoundingClientRect();
this.canvasTop = Math.round(canvasBox.offsetTop*1 + this.headerHeight*1); //首次进入canvasInfo.top不准
// console.log(this.canvasTop)
this.canvasLeft = Math.round(canvasInfo.left);
this.canvas = document.createElement("canvas");
this.canvas.setAttribute("id", "autograph");
canvasBox.appendChild(this.canvas);
this.canvas.width = canvasBox.offsetWidth - 4;
this.canvas.height = canvasBox.offsetHeight - 4;
this.ctx = this.canvas.getContext("2d");
this.ctx.fillStyle = "transparent"; //画布背景色
this.ctx.strokeStyle = "#333";
this.ctx.lineCap = "round";
this.ctx.lineJoin = "round";
this.ctx.lineWidth = 2;
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
this.canvas.addEventListener("touchstart", this.writeDown, { passive: false });
this.canvas.addEventListener("touchmove", this.write, { passive: false });
this.canvas.addEventListener("touchend", this.writeUp, { passive: false });
},
// 下笔
writeDown(e) {
e.preventDefault();
let touch = e.touches[0];
let pageX = touch.pageX - this.canvasLeft;
let pageY = touch.pageY - this.canvasTop;
this.ctx.beginPath();
this.ctx.moveTo(pageX, pageY);
},
//写字
write(e) {
e.preventDefault();
let touch = e.touches[0];
this.ctx.fillStyle = "#fff"; //画布背景色
let pageX = touch.pageX - this.canvasLeft;
let pageY = touch.pageY - this.canvasTop;
this.ctx.lineTo(pageX, pageY);
this.ctx.stroke();
this.isWarning = true;
},
// 写完
writeUp(e) {
e.preventDefault();
this.ctx.closePath();
},
// 重置
resetCanvas() {
this.isWarning = false;
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.fillStyle = "transparent"; //画布背景色
},
// 确认提交
submit() {
if (!this.isWarning) return this.$vux.toast.text("请在签名区签名");
if (!this.isAgree) return this.$vux.toast.text("请确认本人申明");
let that = this;
this.$vux.confirm.show({
content: "信息采集完成,提交后将无法再次修改,是否确认提交?",
confirmText: "确认提交",
cancelText: "我再看看",
onConfirm() {
that.autogranph();
}
});
},
autogranph() {
let imgBase64 = this.canvas.toDataURL();
this.$api
.saveHospitalInfo({signUrl: imgBase64 })
.then(res => {
this.$router.push(`/hosSuccess`);
})
.catch(err => {
console.log(err);
});
}
},
beforeRouteLeave(to, from, next) {
window.onresize = "";
document.body.removeEventListener("touchmove", this.preventDefault);
next();
}
};
</script>
<style lang="less" scoped>
.main {
position: relative;
}
.autograph-tip {
padding: 4% 15px 4% 60px;
background: url("~@/assets/images/ximg09.png") no-repeat 15px;
background-size: 20px;
color: @theme-color;
font-weight: 700;
&.horizontal {
padding: 1% 15px 0 50px;
background-size: 18px;
}
}
.canvas-box {
width: 90%;
height: 85%;
position: absolute;
left: 50%;
top: 12%;
transform: translate(-50%, 0);
border: 2px dashed @theme-color;
background: url("~@/assets/images/ximg10.png") no-repeat center;
background-size: 65%;
&.horizontal {
top: 16%;
height: 80%;
background-size: 50%;
}
&.active {
background: none;
}
.tip {
position: absolute;
top: 50%;
left: 0;
width: 100%;
text-align: center;
transform: translate(0, -50%);
font-size: 72px;
font-weight: 700;
color: rgba(72, 196, 160, 0.4);
z-index: 1;
}
}
.warning {
color: #f00000;
margin: 0 15px 10px;
line-height: 1.2;
padding-left: 20px;
position: relative;
opacity: 0;
visibility: hidden;
.agree {
position: absolute;
top: 1px;
left: 0;
width: 12px;
height: 12px;
background-color: #fff;
border: 1px solid @border-color;
border-radius: 2px;
&.active {
background: @theme-color url("~@/assets/images/ximg01.png") no-repeat
center;
background-size: 100%;
border-color: @theme-color;
}
}
&.active {
opacity: 1;
visibility: visible;
}
}
.btn-box {
display: flex;
justify-content: space-between;
padding: 0 15px 25px;
box-sizing: border-box;
.short-btn {
width: 2.8rem;
&.active {
background-color: @theme-color;
}
&.reset {
background-color: #fff;
border: 1px solid @theme-color;
color: @theme-color;
}
}
}
.footer.horizontal {
display: flex;
align-items: center;
.warning {
flex: 1;
}
.btn-box {
padding-bottom: 10px;
padding-left: 0;
width: 4.5rem;
}
.short-btn {
line-height: 0.6rem;
width: 1.8rem;
margin: 0;
}
}
</style>
<style lang="less">
.main {
position: relative;
}
</style>
有空再整理成组件,拜拜!
网友评论