使用插件canvas手写板,横屏签名 - DCloud 插件市场
保存后签名是横屏的,上传时需正的
获取到图片路径后创建新的canvas
var t=this;
uni.canvasToTempFilePath({
canvasId: 'designature',
fileType: 'png',
quality: 1, //图片质量
success:function(res) {
console.log(res.tempFilePath)
//获取到原签名照片
t.rotate(res.tempFilePath);
},
fail(e){
console.log(e)
}
},this)
//旋转图片,生成新canvas实例
rotate(tempFilePaths){
const that = this
var _this = this;
uni.getImageInfo({
// 获取图片的信息
src: tempFilePaths,
success: (res1) => {
console.log(res1)
// 将canvas1的内容复制到canvas2中
let canvasContext = uni.createCanvasContext('handWriting2',this)
let rate = res1.height / res1.width
let width = 300 / rate
let height = 300
_this.cavWidth = 300 / rate
_this.cavWidth1 = 300
canvasContext.translate(height / 2, width / 2)
canvasContext.rotate((270 * Math.PI) / 180)
canvasContext.drawImage(tempFilePaths, -width / 2, -height / 2, width, height)
canvasContext.draw(false,(data)=>{
// 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中
uni.canvasToTempFilePath({
// 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。
canvasId: 'handWriting2',
fileType: 'png',
quality: 1, //图片质量
success(res2) {
// 调用uni.uploadFile上传图片即可
console.log(res2)
_this.$emit('getImg',res2.tempFilePath);
}
},_this)
});
}
})
}
获取到图片后转Base64
源码
//f-signature.vue
<template>
<!-- 签名横屏 -->
<view class="signa">
<view class="box">
<!-- :style="{'width':width,'height':height}" -->
<canvas class="canvas" disable-scroll="true" canvas-id="designature" @touchstart="starts"
@touchmove="moves" @touchend="end"></canvas>
<!--用于旋转图片的canvas容器-->
<canvas style="position: absolute" canvas-id="handWriting2"></canvas>
<view class="bottomBox u-flex">
<!-- <view class="tip">请你在此手动签写自己的签章,签写操作完毕点击保存按钮</view> -->
<view class="btn" @click="cancel">{
{ $t('specialApplication.fh') }}</view>
<view class="btn blue" style="margin-top: 4vw;" @click="clear">{
{ $t('specialApplication.qc') }}</view>
<view class="btn" @click="save">{
{ $t('specialApplication.qd') }}</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
resultUrl: '',
dom: null,
line: [],
width: '0px',
height: '0px',
radius: 0
}
},
created() {
uni.getSystemInfo({
success: (res) => {
this.width = res.windowWidth - 56 + 'px';
this.height = res.windowHeight - 154 + 'px';
}
});
this.dom = uni.createCanvasContext('designature',this);
},
methods: {
cancel(){
uni.navigateBack()
},
end(e) {
},
distance(a, b) {
let x = b.x - a.x;
let y = b.y - a.y;
return Math.sqrt(x * x + y * y);
},
starts(e) {
this.line.push({
points: [{
time: new Date().getTime(),
x: e.touches[0].x,
y: e.touches[0].y,
dis: 0
}]
})
let currentPoint = {
x: e.touches[0].x,
y: e.touches[0].y
}
this.currentPoint = currentPoint
this.drawer(this.line[this.line.length - 1]);
},
moves(e) {
let point = {
x: e.touches[0].x,
y: e.touches[0].y
}
this.lastPoint = this.currentPoint,
this.currentPoint = point
this.line[this.line.length - 1].points.push({
time: new Date().getTime(),
x: e.touches[0].x,
y: e.touches[0].y,
dis: this.distance(this.currentPoint, this.lastPoint)
})
this.drawer(this.line[this.line.length - 1])
},
drawer(item) {
let x1, x2, y1, y2, len, radius, r, cx, cy, t = 0.5,
x, y;
var time = 0;
if (item.points.length > 2) {
let lines = item.points[item.points.length - 3];
let line = item.points[item.points.length - 2];
let end = item.points[item.points.length - 1];
x = line.x;
y = line.y;
x1 = lines.x;
y1 = lines.y;
x2 = end.x;
y2 = end.y;
var dis = 0;
time = (line.time - lines.time) + (end.time - line.time)
dis = line.dis + lines.dis + end.dis;
var dom = this.dom;
var or = Math.min(time / dis * this.linePressure + this.lineMin, this.lineMax);
cx = (x - (Math.pow(1 - t, 2) * x1) - Math.pow(t, 2) * x2) / (2 * t * (1 - t))
cy = (y - (Math.pow(1 - t, 2) * y1) - Math.pow(t, 2) * y2) / (2 * t * (1 - t))
dom.setLineCap('round')
dom.beginPath();
dom.setStrokeStyle('black')
dom.setLineWidth(5)
dom.moveTo(x1, y1);
dom.quadraticCurveTo(cx, cy, x2, y2);
dom.stroke();
dom.draw(true)
}
},
clear() {
this.dom.clearRect(0, 0, 1000, 1000)
this.dom.draw()
},
save() {
var t=this;
uni.canvasToTempFilePath({
canvasId: 'designature',
fileType: 'png',
quality: 1, //图片质量
success:function(res) {
console.log(res.tempFilePath)
debugger
t.rotate(res.tempFilePath);
// t.$emit('getImg',res.tempFilePath)
},
fail(e){
console.log(e)
}
},this)
},
//旋转图片,生成新canvas实例
rotate(tempFilePaths){
const that = this
var _this = this;
uni.getImageInfo({
// 获取图片的信息
src: tempFilePaths,
success: (res1) => {
console.log(res1)
// 将canvas1的内容复制到canvas2中
let canvasContext = uni.createCanvasContext('handWriting2',this)
let rate = res1.height / res1.width
let width = 300 / rate
let height = 300
_this.cavWidth = 300 / rate
_this.cavWidth1 = 300
canvasContext.translate(height / 2, width / 2)
canvasContext.rotate((270 * Math.PI) / 180)
canvasContext.drawImage(tempFilePaths, -width / 2, -height / 2, width, height)
canvasContext.draw(false,(data)=>{
// 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中
uni.canvasToTempFilePath({
// 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。
canvasId: 'handWriting2',
fileType: 'png',
quality: 1, //图片质量
success(res2) {
// 调用uni.uploadFile上传图片即可
console.log(res2)
_this.$emit('getImg',res2.tempFilePath);
}
},_this)
});
}
})
},
}
}
</script>
<style scoped lang="scss">
.signa {
height: 100%;
width: 100%;
.box{
background-color: #fff;
width: 100%;
height: 100%;
}
.canvas {
position: relative;
// z-index: 9999;
width: 100%;
height: 100%;
}
.bottomBox{
flex-direction: column;
justify-content: center;
width: 80px;
height: 80vw;
padding: 10px;
// background-color: #007AFF;
position: fixed;
left: 50%;
bottom: -40vw;
transform: rotate(90deg);
margin-left: -50px;
margin-bottom: 72px;
.tip{
font-size: 11px;
color: #FF6F77;
}
.btn{
width: 100%;
background: #c70019;
border-radius: 6px;
margin-top: 14px;
text-align: center;
color: #fff;
font-size: 24rpx;
padding: 12px 0;
&.blue{
background: #fff;
color: #c70019;
border: solid 1px #c70019;
}
}
}
}
</style>
在需要的地方引入
<template>
<view>
<view class="autograph-canvas">
<f-signature @getImg="signature"></f-signature>
</view>
</view>
</template>
<script>
import fSignature from '@/components/f-signature/f-signature';
import {
pathToBase64,
base64ToPath
} from 'image-tools'
export default {
data() {
return {
}
},
components: {fSignature},
methods: {
signature(dataImg){
this.$store.commit('getValue', dataImg);
pathToBase64(dataImg).then(data => {
uni.setStorageSync('imgSig',data);
})
uni.navigateBack()
}
},
}
</script>
<style scoped>
.autograph-canvas {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 100%;
background: #fff;
z-index: 9999;
}
</style>