You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.3 KiB

2 months ago
<template>
<view class="l-signature" id="l-signature" ref="l-signature" :style="drawableStyle">
<view class="l-signature-landscape" ref="l-signature-landscape" v-if="landscape && url !=''" :style="landscapeStyle">
<image class="l-signature-image" ref="l-signature-image" :src="url" :style="imageStyle"></image>
</view>
</view>
</template>
<script lang="uts">
import { Signature } from './signature.uts'
import {LSignatureToTempFilePathOptions, LSignatureToFileSuccess, LSignatureOptions} from '../../index.uts'
// type SignatureToFileSuccessCallback = (res : UTSJSONObject) => void
// type SignatureToFileFailCallback = (res : TakeSnapshotFail) => void
// type SignatureToFileCompleteCallback = (res : any) => void
/**
* LimeSignature 手写板签名
* @description 手写板签名插件,uvue专用版。
* @tutorial https://ext.dcloud.net.cn/plugin?id=4354
* @property {Number} penSize 画笔大小
* @property {String} penColor 画笔颜色
* @property {String} backgroundColor 背景颜色,不填则为透明
* @property {Boolean} disableScroll 当在写字时禁止屏幕滚动以及下拉刷新nvue无效
*/
export default {
props: {
styles: {
type: String,
default: ''
},
penColor: {
type: String,
default: 'black'
},
penSize: {
type: Number,
default: 2
},
backgroundColor: {
type: String,
default: ''
},
openSmooth: {
type: Boolean,
default: false
},
minLineWidth: {
type: Number,
default: 2
},
maxLineWidth: {
type: Number,
default: 6
},
minSpeed: {
type: Number,
default: 1.5
},
maxWidthDiffRate: {
type: Number,
default: 20
},
maxHistoryLength: {
type: Number,
default: 20
},
disableScroll: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
},
landscape:{
type: Boolean,
default: true
},
},
data() {
return {
signature: null as Signature | null,
landscapeStyle: new Map<string, any>(),
imageStyle: new Map<string, any>(),
url: ''
}
},
computed: {
drawableStyle() : string {
let style : string = ''
if (this.backgroundColor != '') {
style += `background-color: ${this.backgroundColor};`
}
if (this.styles != '') {
style += this.styles
}
return style
},
param() : LSignatureOptions {
const options : LSignatureOptions = {
penColor: this.penColor,
openSmooth: this.openSmooth,
disableScroll: this.disableScroll,
disabled: this.disabled,
penSize: this.penSize,
minLineWidth: this.minLineWidth,
maxLineWidth: this.maxLineWidth,
minSpeed: this.minSpeed,
maxWidthDiffRate: this.maxWidthDiffRate,
maxHistoryLength: this.maxHistoryLength
}
return options
}
},
mounted() {
this.createSelectorQuery().select('#l-signature').boundingClientRect((rect)=>{
const {height, width} = rect as NodeInfo
this.landscapeStyle.set('width', `${height}px`)
this.landscapeStyle.set('height', `${width}px`)
this.imageStyle.set('width', `${width}px`)
this.imageStyle.set('height', `${height}px`)
this.imageStyle.set('transform', `rotate(-90deg) translateY(${width}px)`)
const el = this.$refs['l-signature'] as Element
this.signature = new Signature(el)
this.$watch('param', (v : LSignatureOptions) => {
this.signature?.setOption(v)
}, { immediate: true })
}).exec()
},
methods: {
clear() {
this.signature?.clear()
},
redo() {
this.signature?.redo()
},
undo() {
this.signature?.undo()
},
canvasToTempFilePath(options : LSignatureToTempFilePathOptions) {
// const success = options.get('success')// as SignatureToFileSuccessCallback | null
// const fail = options.get('fail') as SignatureToFileFailCallback | null
// const complete = options.get('complete') as SignatureToFileCompleteCallback | null
// const format = options.getString('format')??'png'
const success = options.success // as SignatureToFileSuccessCallback | null
const fail = options.fail // as SignatureToFileFailCallback | null
const complete = options.complete// as SignatureToFileCompleteCallback | null
const format = options.format ?? 'png'
const el = this.$refs['l-signature'] as Element
el.takeSnapshot({
format,
success: (res) => {
if(this.landscape){
this.url = res.tempFilePath
setTimeout(()=>{
const image = this.$refs['l-signature-landscape'] as Element
image.takeSnapshot({
format,
success: (res2) => {
success?.({
tempFilePath: res2.tempFilePath,
isEmpty: this.signature?.isEmpty ?? false
} as LSignatureToFileSuccess)
}
})
},300)
} else {
success?.({
tempFilePath: res.tempFilePath,
isEmpty: this.signature?.isEmpty ?? false
} as LSignatureToFileSuccess)
}
},
fail: (res) => {
fail?.(res)
},
complete: (res) => {
complete?.(res)
}
} as TakeSnapshotOptions)
}
}
}
</script>
<style lang="scss">
.l-signature {
flex: 1;
&-landscape{
position: absolute;
pointer-events: none;
left: 1000rpx;
}
&-image{
transform-origin: 0% 0%;
}
}
</style>