integrated_traffic_uniapp/uni_modules/lime-signature/components/l-signature/signature.uts

162 lines
4.2 KiB
Plaintext
Raw Normal View History

2024-03-25 19:16:41 +08:00
import { LSignatureOptions, Point, Line } from '../../index.uts'
let points : Line = []
let undoStack : Line[] = [];
let redoStack : Line[] = [];
let lastX = 0;
let lastY = 0;
export class Signature {
el : UniElement
options : LSignatureOptions = {
penColor: 'black',
openSmooth: true,
disableScroll: true,
disabled: false,
penSize: 2,
minLineWidth: 2,
maxLineWidth: 6,
minSpeed: 1.5,
maxWidthDiffRate: 20,
maxHistoryLength: 20
} as LSignatureOptions
ctx : DrawableContext
isEmpty : boolean = true
isDrawing : boolean = false
// historyList : Point[][] = []
// id : string
// instance : ComponentPublicInstance
constructor(el : UniElement) {
this.el = el
this.ctx = el.getDrawableContext() as DrawableContext
this.init()
}
init() {
this.el.addEventListener('touchstart', this.onTouchStart)
this.el.addEventListener('touchmove', this.onTouchMove)
this.el.addEventListener('touchend', this.onTouchEnd)
}
remove() {
this.el.removeEventListener('touchstart', this.onTouchStart as UniCallbackWrapper)
this.el.removeEventListener('touchmove', this.onTouchMove as UniCallbackWrapper)
this.el.removeEventListener('touchend', this.onTouchEnd as UniCallbackWrapper)
}
setOption(options : LSignatureOptions) {
this.options = options
}
disableScroll(event : UniTouchEvent) {
event.stopPropagation()
if (this.options.disableScroll) {
{
event.preventDefault()
}
}
}
getTouchPoint(event : UniTouchEvent) : Point {
const rect = this.el.getBoundingClientRect()
const touche = event.touches[0];
const x = touche.clientX
const y = touche.clientY
// const force = touche.force
return {
x: x - rect.left,
y: y - rect.top
} as Point
}
onTouchStart: (event : UniTouchEvent) => void = (event : UniTouchEvent) =>{
if (this.options.disabled) {
return
}
this.disableScroll(event)
const { x, y } = this.getTouchPoint(event)
this.isDrawing = true;
this.isEmpty = false
lastX = x
lastY = y
points.push({ x, y } as Point);
}
onTouchMove: (event : UniTouchEvent) => void = (event : UniTouchEvent) =>{
if (this.options.disabled || !this.isDrawing) {
return
}
this.disableScroll(event)
const { x, y } = this.getTouchPoint(event)
const lineWidth = this.options.penSize
const strokeStyle = this.options.penColor
const point = { x, y } as Point
const last = { x: lastX, y: lastY } as Point
this.drawLine(point, last, lineWidth, strokeStyle)
lastX = x
lastY = y
points.push({ x, y, c: strokeStyle, w: lineWidth } as Point);
}
onTouchEnd: (event : UniTouchEvent) => void = (event : UniTouchEvent) =>{
this.disableScroll(event)
this.isDrawing = false;
undoStack.push(points);
redoStack = [] as Line[];
points = [] as Point[];
}
drawLine(point : Point, last : Point, lineWidth : number, strokeStyle : string) {
const ctx = this.ctx
ctx.lineWidth = lineWidth
ctx.strokeStyle = strokeStyle
ctx.lineCap = 'round'
ctx.lineJoin = 'round'
ctx.beginPath()
ctx.moveTo(last.x, last.y)
ctx.lineTo(point.x, point.y)
ctx.stroke()
ctx.update()
}
// addHistory() { }
clear() {
this.ctx.reset()
this.ctx.update()
this.isEmpty = true
undoStack = [] as Line[];
redoStack = [] as Line[];
points = [] as Point[];
}
undo() {
if(redoStack.length == this.options.maxHistoryLength && this.options.maxHistoryLength != 0){
return
}
this.ctx.reset()
if(undoStack.length > 0){
const lastPath : Line = undoStack.pop()!;
redoStack.push(lastPath);
if(undoStack.length == 0){
this.isEmpty = true
this.ctx.update()
return
}
for (let l = 0; l < undoStack.length; l++) {
for (let i = 1; i < undoStack[l].length; i++) {
const last = undoStack[l][i - 1]
const point = undoStack[l][i]
this.drawLine(point, last, point.w!, point.c!)
}
}
} else {
this.ctx.update()
}
}
redo() {
if(redoStack.length < 1) return
const lastPath : Line = redoStack.pop()!;
undoStack.push(lastPath);
this.isEmpty = false
for (let l = 0; l < undoStack.length; l++) {
for (let i = 1; i < undoStack[l].length; i++) {
const last = undoStack[l][i - 1]
const point = undoStack[l][i]
this.drawLine(point, last, point.w!, point.c!)
}
}
}
// restore() { }
}