123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- 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() { }
- }
|