JS v0.0.0
<template>
<div class="signatureBox">
<div class="signature-title">签名</div>
<div ref="canvasHW" class="canvasBox">
<canvas
ref="canvasF"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
@mousedown="mouseDown"
@mousemove="mouseMove"
@mouseup="mouseUp"
></canvas>
</div>
<div class="signature-btn">
<cube-button class="btn" type="info" @click.native.prevent="handleGoBack">
返回
</cube-button>
<cube-button
class="btn"
type="info"
@click.native.prevent="handleOverwrite"
>
重签
</cube-button>
<cube-button class="btn" type="info" @click.native.prevent="handleSubmit">
确认
</cube-button>
</div>
</div>
</template>
<script>
export default {
name: 'Signature',
data() {
return {
points: [],
canvasTxt: null,
stageInfo: [],
startX: 0,
startY: 0,
moveY: 0,
moveX: 0,
isDown: false,
strokeStyle: '#000',
lineWidth: 2,
};
},
mounted() {
this.initCanvas();
},
methods: {
initCanvas() {
const canvas = this.$refs.canvasF;
// 获取画布的高度
canvas.height = this.$refs.canvasHW.offsetHeight - 20;
// 获取画布的宽度
canvas.width = this.$refs.canvasHW.offsetWidth - 20;
// 创建 context 对象
this.canvasTxt = canvas.getContext('2d');
this.stageInfo = canvas.getBoundingClientRect();
},
// 电脑设备事件
mouseDown(ev) {
ev = ev || event;
ev.preventDefault();
if (ev) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.startX = obj.x;
this.startY = obj.y;
this.canvasTxt.beginPath();
this.canvasTxt.moveTo(this.startX, this.startY);
this.canvasTxt.lineTo(obj.x, obj.y);
this.canvasTxt.stroke();
this.canvasTxt.closePath();
this.points.push(obj);
this.isDown = true;
}
},
// 移动设备事件
touchStart(ev) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.startX = obj.x;
this.startY = obj.y;
this.canvasTxt.beginPath();
this.canvasTxt.moveTo(this.startX, this.startY);
this.canvasTxt.lineTo(obj.x, obj.y);
this.canvasTxt.stroke();
this.canvasTxt.closePath();
this.points.push(obj);
}
},
// 电脑设备事件
mouseMove(ev) {
ev = ev || event;
ev.preventDefault();
if (this.isDown) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.moveY = obj.y;
this.moveX = obj.x;
this.canvasTxt.strokeStyle = this.strokeStyle;
this.canvasTxt.lineWidth = this.lineWidth;
this.canvasTxt.beginPath();
this.canvasTxt.moveTo(this.startX, this.startY);
this.canvasTxt.lineTo(obj.x, obj.y);
this.canvasTxt.stroke();
this.canvasTxt.closePath();
this.startY = obj.y;
this.startX = obj.x;
this.points.push(obj);
}
},
// 移动设备事件
touchMove(ev) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.moveY = obj.y;
this.moveX = obj.x;
// 设置线条颜色
this.canvasTxt.strokeStyle = this.strokeStyle;
// 设置线条宽度
this.canvasTxt.lineWidth = this.lineWidth;
// 绘制开始路径
this.canvasTxt.beginPath();
// 定义线条开始坐标
this.canvasTxt.moveTo(this.startX, this.startY);
// 定义线条结束坐标
this.canvasTxt.lineTo(obj.x, obj.y);
// 绘制线条
this.canvasTxt.stroke();
this.canvasTxt.closePath();
this.startY = obj.y;
this.startX = obj.x;
this.points.push(obj);
}
},
// 电脑设备事件
mouseUp(ev) {
ev = ev || event;
ev.preventDefault();
if (ev) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.canvasTxt.beginPath();
this.canvasTxt.moveTo(this.startX, this.startY);
this.canvasTxt.lineTo(obj.x, obj.y);
this.canvasTxt.stroke();
this.canvasTxt.closePath();
this.points.push(obj);
this.points.push({ x: -1, y: -1 });
this.isDown = false;
}
},
// 移动设备事件
touchEnd(ev) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.canvasTxt.beginPath();
this.canvasTxt.moveTo(this.startX, this.startY);
this.canvasTxt.lineTo(obj.x, obj.y);
this.canvasTxt.stroke();
this.canvasTxt.closePath();
this.points.push(obj);
this.points.push({ x: -1, y: -1 });
}
},
// 返回
handleGoBack() {
this.handleOverwrite();
this.$emit('back');
},
// 重写
handleOverwrite() {
console.log('###');
this.canvasTxt.clearRect(
0,
0,
this.$refs.canvasF.width,
this.$refs.canvasF.height
);
this.points = [];
},
// 提交
handleSubmit() {
if (this.points.length < 50) {
return;
}
console.log('###', this.$refs.canvasF.toDataURL());
// this.$emit('content', this.$refs.canvasF.toDataURL());
},
},
};
</script>
<style lang="stylus" scoped>
.signatureBox
position fixed
right 0
bottom 0
left 0
background-color #fff
.signature-title
padding 10px 0
background-color #f26226
color #fff
text-align center
font-size 14px
.canvasBox
padding 10px
height 220px
canvas
border 1px solid #f26226
.signature-btn
display flex
justify-content center
box-sizing border-box
padding 0 10px 10px
.btn
display inline-block
margin-top 10px
margin-right 10px
margin-bottom 10px
padding 0
width 40%
height 30px
border-color #f26226
background-color #f26226
line-height 30px
&:last-child
margin-right 0
</style>
TS v0.0.1
<template>
<div class="signature__container">
<div ref="canvasContainer" class="canvas__container">
<div class="canvas__note">请在此区域内手写签名</div>
<!--
touchstart 移动端点击开始事件
touchmove 移动端点击滑动事件
touchend 移动端点击结束事件
mousedown PC端鼠标点击事件
mousemove PC端鼠标移动事件
mouseup PC端鼠标抬起事件
-->
<canvas
ref="canvasInstance"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
@mousedown="mouseDown"
@mousemove="mouseMove"
@mouseup="mouseUp"
/>
</div>
<div class="signature__btns">
<cube-button primary @click="handleSubmit">确认</cube-button>
<cube-button outline @click="handleOverwrite">重签</cube-button>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class SignatureDemo extends Vue {
points: Record<string, any>[] = [];
canvasTxt: Record<string, any> | null = null;
stageInfo: Record<string, any> = {};
startX = 0;
startY = 0;
moveY = 0;
moveX = 0;
isDown = false;
strokeStyle = '#000';
lineWidth = 2;
mounted() {
this.initCanvas();
}
initCanvas() {
const canvas: Record<string, any> = this.$refs.canvasInstance;
// 获取画布的高度
canvas.height = (this.$refs.canvasContainer as any).offsetHeight - 20;
// 获取画布的宽度
canvas.width = (this.$refs.canvasContainer as any).offsetWidth - 20;
// 创建 context 对象
this.canvasTxt = canvas.getContext('2d');
this.stageInfo = canvas.getBoundingClientRect();
}
/** 电脑设备事件 */
mouseDown(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.startX = obj.x;
this.startY = obj.y;
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
this.isDown = true;
}
}
/** 移动设备事件 */
touchStart(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.startX = obj.x;
this.startY = obj.y;
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
}
}
/** 电脑设备事件 */
mouseMove(ev: any) {
ev = ev || event;
ev.preventDefault();
if (this.isDown) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.moveY = obj.y;
this.moveX = obj.x;
if (this.canvasTxt) {
this.canvasTxt.strokeStyle = this.strokeStyle;
this.canvasTxt.lineWidth = this.lineWidth;
}
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.startY = obj.y;
this.startX = obj.x;
this.points.push(obj);
}
}
/** 移动设备事件 */
touchMove(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.moveY = obj.y;
this.moveX = obj.x;
if (this.canvasTxt) {
// 设置线条颜色
this.canvasTxt.strokeStyle = this.strokeStyle;
// 设置线条宽度
this.canvasTxt.lineWidth = this.lineWidth;
}
// 绘制开始路径
this.canvasTxt?.beginPath();
// 定义线条开始坐标
this.canvasTxt?.moveTo(this.startX, this.startY);
// 定义线条结束坐标
this.canvasTxt?.lineTo(obj.x, obj.y);
// 绘制线条
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.startY = obj.y;
this.startX = obj.x;
this.points.push(obj);
}
}
/** 电脑设备事件 */
mouseUp(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
this.points.push({ x: -1, y: -1 });
this.isDown = false;
}
}
/** 移动设备事件 */
touchEnd(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
this.points.push({ x: -1, y: -1 });
}
}
/** 重写 */
handleOverwrite() {
this.canvasTxt?.clearRect(
0,
0,
(this.$refs.canvasInstance as any).width,
(this.$refs.canvasInstance as any).height
);
this.points = [];
}
/** 提交 */
handleSubmit() {
if (this.points.length < 50) {
return;
}
console.log('###', (this.$refs.canvasInstance as any).toDataURL());
// this.$emit('content', this.$refs.canvasInstance.toDataURL());
}
}
</script>
<style lang="stylus" scoped>
@import '~common/stylus/variable'
@import '~common/stylus/mixin'
.signature__container
width 100vw
height 100vh
background #F9FBFF
.canvas__container
padding 10px
height calc(100vh - 100px)
.canvas__note
position fixed
top 300px
right 60px
left 60px
z-index -1
color #B9BFC8
text-align center
font-size 12px
line-height 17px
canvas
border 1px solid #f26226
.signature__btns
flex-row()
padding 0 10px
</style>
TS v0.0.2(横屏)
<template>
<div class="signature__container">
<!-- 按钮区域 -->
<div class="signature__btns">
<cube-button
class="signature__btn resign"
outline
@click="handleOverwrite"
>
清除手写板
</cube-button>
<cube-button class="signature__btn confirm" primary @click="handleSubmit">
确认签名
</cube-button>
<div v-if="false" class="canvas__note">请在此区域内手写签名</div>
</div>
<!-- 签字板区域 -->
<div ref="canvasContainer" class="canvas__container">
<!--
touchstart 移动端点击开始事件
touchmove 移动端点击滑动事件
touchend 移动端点击结束事件
mousedown PC端鼠标点击事件
mousemove PC端鼠标移动事件
mouseup PC端鼠标抬起事件
-->
<canvas
ref="canvasInstance"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd"
@mousedown="mouseDown"
@mousemove="mouseMove"
@mouseup="mouseUp"
/>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
@Component
export default class SignatureDemo extends Vue {
points: Record<string, any>[] = [];
canvasTxt: Record<string, any> | null = null;
stageInfo: Record<string, any> = {};
startX = 0;
startY = 0;
moveY = 0;
moveX = 0;
isDown = false;
strokeStyle = '#000';
lineWidth = 2;
mounted() {
this.initCanvas();
}
initCanvas() {
const canvas: Record<string, any> = this.$refs.canvasInstance;
// 获取画布的高度
canvas.height = (this.$refs.canvasContainer as any).offsetHeight;
// 获取画布的宽度
canvas.width = (this.$refs.canvasContainer as any).offsetWidth;
// 创建 context 对象
this.canvasTxt = canvas.getContext('2d');
this.stageInfo = canvas.getBoundingClientRect();
}
/** 电脑设备事件 */
mouseDown(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.startX = obj.x;
this.startY = obj.y;
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
this.isDown = true;
}
}
/** 移动设备事件 */
touchStart(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.startX = obj.x;
this.startY = obj.y;
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
}
}
/** 电脑设备事件 */
mouseMove(ev: any) {
ev = ev || event;
ev.preventDefault();
if (this.isDown) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.moveY = obj.y;
this.moveX = obj.x;
if (this.canvasTxt) {
this.canvasTxt.strokeStyle = this.strokeStyle;
this.canvasTxt.lineWidth = this.lineWidth;
}
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.startY = obj.y;
this.startX = obj.x;
this.points.push(obj);
}
}
/** 移动设备事件 */
touchMove(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.moveY = obj.y;
this.moveX = obj.x;
if (this.canvasTxt) {
// 设置线条颜色
this.canvasTxt.strokeStyle = this.strokeStyle;
// 设置线条宽度
this.canvasTxt.lineWidth = this.lineWidth;
}
// 绘制开始路径
this.canvasTxt?.beginPath();
// 定义线条开始坐标
this.canvasTxt?.moveTo(this.startX, this.startY);
// 定义线条结束坐标
this.canvasTxt?.lineTo(obj.x, obj.y);
// 绘制线条
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.startY = obj.y;
this.startX = obj.x;
this.points.push(obj);
}
}
/** 电脑设备事件 */
mouseUp(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev) {
const obj = {
x: ev.offsetX,
y: ev.offsetY,
};
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
this.points.push({ x: -1, y: -1 });
this.isDown = false;
}
}
/** 移动设备事件 */
touchEnd(ev: any) {
ev = ev || event;
ev.preventDefault();
if (ev.touches.length == 1) {
const obj = {
x: ev.targetTouches[0].clientX - this.stageInfo.left,
y: ev.targetTouches[0].clientY - this.stageInfo.top,
};
this.canvasTxt?.beginPath();
this.canvasTxt?.moveTo(this.startX, this.startY);
this.canvasTxt?.lineTo(obj.x, obj.y);
this.canvasTxt?.stroke();
this.canvasTxt?.closePath();
this.points.push(obj);
this.points.push({ x: -1, y: -1 });
}
}
/** 重写 */
handleOverwrite() {
this.canvasTxt?.clearRect(
0,
0,
(this.$refs.canvasInstance as any).width,
(this.$refs.canvasInstance as any).height
);
this.points = [];
}
/** 提交 */
handleSubmit() {
if (this.points.length < 50) {
return;
}
console.log('###', (this.$refs.canvasInstance as any).toDataURL());
// this.$emit('content', this.$refs.canvasInstance.toDataURL());
}
}
</script>
<style lang="stylus" scoped>
@import '~common/stylus/variable'
@import '~common/stylus/mixin'
.signature__container
position relative
overflow auto
box-sizing border-box
padding 33px 24px 33px 60.5px
width 100vw
height 100vh
.signature__btns
flex-row()
position absolute
top -50.5px
right calc(100vw - 100vh) // 100vw 屏幕宽度,剩下的宽度是 100vh - 100vw
left 0
justify-content space-between
padding 0 33px
transform rotate(90deg)
transform-origin bottom left
.signature__btn
width 150px
height 50.5px
border-radius 10px
background #FFFFFF
&.resign
background #FFFFFF
color #626773
&:after
border-radius 10PX
&.confirm
background #10CCA2
.canvas__container
height 100%
.canvas__note
color #B9BFC8
text-align center
font-size 12px
canvas
border 1px dashed #10CCA2
</style>
TS v0.0.3(简化)
<template>
<div class="signature__container">
<!-- 签字板区域 -->
<div ref="canvasContainer" class="canvas__container">
<div v-if="isShowNote" class="canvas__note" @touchstart="onHideNote">
请在此区域内手写签名
</div>
<!--
touchstart 移动端点击开始事件
touchmove 移动端点击滑动事件
touchend 移动端点击结束事件
-->
<canvas
ref="canvasRef"
class="canvas"
@touchstart="onTouchStart"
@touchmove="onTouchMove"
@touchend="onTouchEnd"
/>
</div>
<!-- 按钮区域 -->
<div class="signature__btns">
<cube-button class="signature__btn resign" outline @click="onRewrite">
清除手写板
</cube-button>
<cube-button class="signature__btn confirm" primary @click="onSubmit">
确认签名
</cube-button>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Emit } from 'vue-property-decorator';
/**
* ***
* 为什么该组件不使用整体旋转的方式实现的几点思考:
* 1. 整体旋转最根本的原先的绘制canvas的x、y坐标必须更改,代码修改难度大。
* ***
*/
/** 字体颜色 */
const STROKE_STYLE = '#202020';
/** 字体宽度 */
const LINE_WIDTH = 2;
@Component
export default class SignatureDemo extends Vue {
/** 是否展示提示信息 */
isShowNote = true;
/** canvas实例对象 */
canvasInstance: Record<string, any> | null = null;
/** 画布信息 */
stageInfo: Record<string, any> = {};
/** 绘制点位x轴坐标 */
startX = 0;
/** 绘制点位y轴坐标 */
startY = 0;
mounted() {
this.initial();
}
/** 初始化 */
initial() {
const canvas: Record<string, any> = this.$refs.canvasRef;
// 设置画布的高度
canvas.height = (this.$refs.canvasContainer as any).offsetHeight;
// 设置画布的宽度
canvas.width = (this.$refs.canvasContainer as any).offsetWidth;
// 创建 context 对象
this.canvasInstance = canvas.getContext('2d');
// 获取画布信息
this.stageInfo = canvas.getBoundingClientRect();
}
/** 隐藏提示信息 */
onHideNote() {
this.isShowNote = false;
}
/** 【移动设备】点击开始事件 */
onTouchStart(event: any) {
this.isShowNote = false;
event.preventDefault();
if (event.touches.length == 1) {
const obj = {
x: event.targetTouches[0].clientX - this.stageInfo.left,
y: event.targetTouches[0].clientY - this.stageInfo.top,
};
this.startX = obj.x;
this.startY = obj.y;
this.canvasInstance?.beginPath();
this.canvasInstance?.moveTo(this.startX, this.startY);
this.canvasInstance?.lineTo(obj.x, obj.y);
this.canvasInstance?.stroke();
this.canvasInstance?.closePath();
}
}
/** 【移动设备】点击移动事件 */
onTouchMove(event: any) {
event.preventDefault();
if (event.touches.length == 1) {
const obj = {
x: event.targetTouches[0].clientX - this.stageInfo.left,
y: event.targetTouches[0].clientY - this.stageInfo.top,
};
if (this.canvasInstance) {
// 设置线条颜色
this.canvasInstance.strokeStyle = STROKE_STYLE;
// 设置线条宽度
this.canvasInstance.lineWidth = LINE_WIDTH;
}
// 绘制开始路径
this.canvasInstance?.beginPath();
// 定义线条开始坐标
this.canvasInstance?.moveTo(this.startX, this.startY);
// 定义线条结束坐标
this.canvasInstance?.lineTo(obj.x, obj.y);
// 绘制线条
this.canvasInstance?.stroke();
// 停止绘制
this.canvasInstance?.closePath();
this.startY = obj.y;
this.startX = obj.x;
}
}
/** 【移动设备】点击结束事件 */
onTouchEnd(event: any) {
event.preventDefault();
if (event.touches.length == 1) {
const obj = {
x: event.targetTouches[0].clientX - this.stageInfo.left,
y: event.targetTouches[0].clientY - this.stageInfo.top,
};
this.canvasInstance?.beginPath();
this.canvasInstance?.moveTo(this.startX, this.startY);
this.canvasInstance?.lineTo(obj.x, obj.y);
this.canvasInstance?.stroke();
this.canvasInstance?.closePath();
}
}
/** 重置 */
onRewrite() {
this.canvasInstance?.clearRect(
0,
0,
(this.$refs.canvasRef as any).width,
(this.$refs.canvasRef as any).height
);
// 隐藏提示信息
this.isShowNote = true;
}
/** 提交 */
@Emit('submit')
onSubmit() {
return (this.$refs.canvasRef as any).toDataURL();
}
}
</script>
<style lang="stylus" scoped>
@import '~common/stylus/variable'
@import '~common/stylus/mixin'
.signature__container
position relative
box-sizing border-box
padding 33px 24px 33px 60.5px
width 100vw
height 100vh
background #F9FBFF
.canvas__container
height 100%
.canvas__note
position absolute
top -22px // 补偿字体高度
right calc(50vw - 100vh) // 100vw 屏幕宽度,剩下的宽度是 100vw - 100vh,因为超出屏幕所以要取反
left 50vw
z-index 1
color #B9BFC8
text-align center
font-size 22px
line-height 22px
transform rotate(90deg)
transform-origin bottom left
.canvas
border 1px dashed #10CCA2
border-radius 6px
background #FFFFFF
.signature__btns
flex-row()
position absolute
top -50.5px
right calc(100vw - 100vh) // 100vw 屏幕宽度,剩下的宽度是 100vw - 100vh,因为超出屏幕所以要取反
left 0
justify-content space-between
padding 0 33px
transform rotate(90deg)
transform-origin bottom left
.signature__btn
width 150px
height 50.5px
border-radius 10px
background #FFFFFF
&.resign
background #FFFFFF
color #626773
&:after
border-radius 10PX
&.confirm
background #10CCA2
</style>