162 lines
4.2 KiB
Plaintext
162 lines
4.2 KiB
Plaintext
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() { }
|
|
}
|