{"version":3,"file":"signature_pad.umd.min.js","sources":["../src/point.ts","../src/bezier.ts","../src/signature_event_target.ts","../src/signature_pad.ts","../src/throttle.ts"],"sourcesContent":["// Interface for point data structure used e.g. in SignaturePad#fromData method\nexport interface BasicPoint {\n  x: number;\n  y: number;\n  pressure: number;\n  time: number;\n}\n\nexport class Point implements BasicPoint {\n  public x: number;\n  public y: number;\n  public pressure: number;\n  public time: number;\n\n  constructor(x: number, y: number, pressure?: number, time?: number) {\n    if (isNaN(x) || isNaN(y)) {\n      throw new Error(`Point is invalid: (${x}, ${y})`);\n    }\n    this.x = +x;\n    this.y = +y;\n    this.pressure = pressure || 0;\n    this.time = time || Date.now();\n  }\n\n  public distanceTo(start: BasicPoint): number {\n    return Math.sqrt(\n      Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2),\n    );\n  }\n\n  public equals(other: BasicPoint): boolean {\n    return (\n      this.x === other.x &&\n      this.y === other.y &&\n      this.pressure === other.pressure &&\n      this.time === other.time\n    );\n  }\n\n  public velocityFrom(start: BasicPoint): number {\n    return this.time !== start.time\n      ? this.distanceTo(start) / (this.time - start.time)\n      : 0;\n  }\n}\n","import { BasicPoint, Point } from './point';\n\nexport class Bezier {\n  public static fromPoints(\n    points: Point[],\n    widths: { start: number; end: number },\n  ): Bezier {\n    const c2 = this.calculateControlPoints(points[0], points[1], points[2]).c2;\n    const c3 = this.calculateControlPoints(points[1], points[2], points[3]).c1;\n\n    return new Bezier(points[1], c2, c3, points[2], widths.start, widths.end);\n  }\n\n  private static calculateControlPoints(\n    s1: BasicPoint,\n    s2: BasicPoint,\n    s3: BasicPoint,\n  ): {\n    c1: BasicPoint;\n    c2: BasicPoint;\n  } {\n    const dx1 = s1.x - s2.x;\n    const dy1 = s1.y - s2.y;\n    const dx2 = s2.x - s3.x;\n    const dy2 = s2.y - s3.y;\n\n    const m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 };\n    const m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0 };\n\n    const l1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);\n    const l2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);\n\n    const dxm = m1.x - m2.x;\n    const dym = m1.y - m2.y;\n\n    const k = l2 / (l1 + l2);\n    const cm = { x: m2.x + dxm * k, y: m2.y + dym * k };\n\n    const tx = s2.x - cm.x;\n    const ty = s2.y - cm.y;\n\n    return {\n      c1: new Point(m1.x + tx, m1.y + ty),\n      c2: new Point(m2.x + tx, m2.y + ty),\n    };\n  }\n\n  constructor(\n    public startPoint: Point,\n    public control2: BasicPoint,\n    public control1: BasicPoint,\n    public endPoint: Point,\n    public startWidth: number,\n    public endWidth: number,\n  ) {}\n\n  // Returns approximated length. Code taken from https://www.lemoda.net/maths/bezier-length/index.html.\n  public length(): number {\n    const steps = 10;\n    let length = 0;\n    let px;\n    let py;\n\n    for (let i = 0; i <= steps; i += 1) {\n      const t = i / steps;\n      const cx = this.point(\n        t,\n        this.startPoint.x,\n        this.control1.x,\n        this.control2.x,\n        this.endPoint.x,\n      );\n      const cy = this.point(\n        t,\n        this.startPoint.y,\n        this.control1.y,\n        this.control2.y,\n        this.endPoint.y,\n      );\n\n      if (i > 0) {\n        const xdiff = cx - (px as number);\n        const ydiff = cy - (py as number);\n\n        length += Math.sqrt(xdiff * xdiff + ydiff * ydiff);\n      }\n\n      px = cx;\n      py = cy;\n    }\n\n    return length;\n  }\n\n  // Calculate parametric value of x or y given t and the four point coordinates of a cubic bezier curve.\n  private point(\n    t: number,\n    start: number,\n    c1: number,\n    c2: number,\n    end: number,\n  ): number {\n    // prettier-ignore\n    return (       start * (1.0 - t) * (1.0 - t)  * (1.0 - t))\n         + (3.0 *  c1    * (1.0 - t) * (1.0 - t)  * t)\n         + (3.0 *  c2    * (1.0 - t) * t          * t)\n         + (       end   * t         * t          * t);\n  }\n}\n","export class SignatureEventTarget {\n  /* tslint:disable: variable-name */\n  private _et: EventTarget;\n  /* tslint:enable: variable-name */\n\n  constructor() {\n    try {\n      this._et = new EventTarget();\n    } catch (error) {\n      // Using document as EventTarget to support iOS 13 and older.\n      // Because EventTarget constructor just exists at iOS 14 and later.\n      this._et = document;\n    }\n  }\n\n  addEventListener(\n    type: string,\n    listener: EventListenerOrEventListenerObject | null,\n    options?: boolean | AddEventListenerOptions,\n  ): void {\n    this._et.addEventListener(type, listener, options);\n  }\n\n  dispatchEvent(event: Event): boolean {\n    return this._et.dispatchEvent(event);\n  }\n\n  removeEventListener(\n    type: string,\n    callback: EventListenerOrEventListenerObject | null,\n    options?: boolean | EventListenerOptions,\n  ): void {\n    this._et.removeEventListener(type, callback, options);\n  }\n}\n","/**\n * The main idea and some parts of the code (e.g. drawing variable width Bézier curve) are taken from:\n * http://corner.squareup.com/2012/07/smoother-signatures.html\n *\n * Implementation of interpolation using cubic Bézier curves is taken from:\n * https://web.archive.org/web/20160323213433/http://www.benknowscode.com/2012/09/path-interpolation-using-cubic-bezier_9742.html\n *\n * Algorithm for approximated length of a Bézier curve is taken from:\n * http://www.lemoda.net/maths/bezier-length/index.html\n */\n\nimport { Bezier } from './bezier';\nimport { BasicPoint, Point } from './point';\nimport { SignatureEventTarget } from './signature_event_target';\nimport { throttle } from './throttle';\n\ndeclare global {\n  interface CSSStyleDeclaration {\n    msTouchAction: string | null;\n  }\n}\n\nexport type SignatureEvent = MouseEvent | Touch | PointerEvent;\n\nexport interface FromDataOptions {\n  clear?: boolean;\n}\n\nexport interface ToSVGOptions {\n  includeBackgroundColor?: boolean;\n}\n\nexport interface PointGroupOptions {\n  dotSize: number;\n  minWidth: number;\n  maxWidth: number;\n  penColor: string;\n  velocityFilterWeight: number;\n  /**\n   * This is the globalCompositeOperation for the line.\n   * *default: 'source-over'*\n   * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation\n   */\n  compositeOperation: GlobalCompositeOperation;\n}\n\nexport interface Options extends Partial<PointGroupOptions> {\n  minDistance?: number;\n  backgroundColor?: string;\n  throttle?: number;\n  canvasContextOptions?: CanvasRenderingContext2DSettings;\n}\n\nexport interface PointGroup extends PointGroupOptions {\n  points: BasicPoint[];\n}\n\nexport default class SignaturePad extends SignatureEventTarget {\n  // Public stuff\n  public dotSize: number;\n  public minWidth: number;\n  public maxWidth: number;\n  public penColor: string;\n  public minDistance: number;\n  public velocityFilterWeight: number;\n  public compositeOperation: GlobalCompositeOperation;\n  public backgroundColor: string;\n  public throttle: number;\n  public canvasContextOptions: CanvasRenderingContext2DSettings;\n\n  // Private stuff\n  /* tslint:disable: variable-name */\n  private _ctx: CanvasRenderingContext2D;\n  private _drawingStroke = false;\n  private _isEmpty = true;\n  private _lastPoints: Point[] = []; // Stores up to 4 most recent points; used to generate a new curve\n  private _data: PointGroup[] = []; // Stores all points in groups (one group per line or dot)\n  private _lastVelocity = 0;\n  private _lastWidth = 0;\n  private _strokeMoveUpdate: (event: SignatureEvent) => void;\n  /* tslint:enable: variable-name */\n\n  constructor(\n    private canvas: HTMLCanvasElement,\n    options: Options = {},\n  ) {\n    super();\n    this.velocityFilterWeight = options.velocityFilterWeight || 0.7;\n    this.minWidth = options.minWidth || 0.5;\n    this.maxWidth = options.maxWidth || 2.5;\n    this.throttle = ('throttle' in options ? options.throttle : 16) as number; // in milisecondss\n    this.minDistance = (\n      'minDistance' in options ? options.minDistance : 5\n    ) as number; // in pixels\n    this.dotSize = options.dotSize || 0;\n    this.penColor = options.penColor || 'black';\n    this.backgroundColor = options.backgroundColor || 'rgba(0,0,0,0)';\n    this.compositeOperation = options.compositeOperation || 'source-over';\n    this.canvasContextOptions = (\n      'canvasContextOptions' in options ? options.canvasContextOptions : {}\n    ) as CanvasRenderingContext2DSettings;\n\n    this._strokeMoveUpdate = this.throttle\n      ? throttle(SignaturePad.prototype._strokeUpdate, this.throttle)\n      : SignaturePad.prototype._strokeUpdate;\n    this._ctx = canvas.getContext(\n      '2d',\n      this.canvasContextOptions,\n    ) as CanvasRenderingContext2D;\n\n    this.clear();\n\n    // Enable mouse and touch event handlers\n    this.on();\n  }\n\n  public clear(): void {\n    const { _ctx: ctx, canvas } = this;\n\n    // Clear canvas using background color\n    ctx.fillStyle = this.backgroundColor;\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\n    ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n    this._data = [];\n    this._reset(this._getPointGroupOptions());\n    this._isEmpty = true;\n  }\n\n  public fromDataURL(\n    dataUrl: string,\n    options: {\n      ratio?: number;\n      width?: number;\n      height?: number;\n      xOffset?: number;\n      yOffset?: number;\n    } = {},\n  ): Promise<void> {\n    return new Promise((resolve, reject) => {\n      const image = new Image();\n      const ratio = options.ratio || window.devicePixelRatio || 1;\n      const width = options.width || this.canvas.width / ratio;\n      const height = options.height || this.canvas.height / ratio;\n      const xOffset = options.xOffset || 0;\n      const yOffset = options.yOffset || 0;\n\n      this._reset(this._getPointGroupOptions());\n\n      image.onload = (): void => {\n        this._ctx.drawImage(image, xOffset, yOffset, width, height);\n        resolve();\n      };\n      image.onerror = (error): void => {\n        reject(error);\n      };\n      image.crossOrigin = 'anonymous';\n      image.src = dataUrl;\n\n      this._isEmpty = false;\n    });\n  }\n\n  public toDataURL(\n    type: 'image/svg+xml',\n    encoderOptions?: ToSVGOptions,\n  ): string;\n  public toDataURL(type?: string, encoderOptions?: number): string;\n  public toDataURL(\n    type = 'image/png',\n    encoderOptions?: number | ToSVGOptions | undefined,\n  ): string {\n    switch (type) {\n      case 'image/svg+xml':\n        if (typeof encoderOptions !== 'object') {\n          encoderOptions = undefined;\n        }\n        return `data:image/svg+xml;base64,${btoa(\n          this.toSVG(encoderOptions as ToSVGOptions),\n        )}`;\n      default:\n        if (typeof encoderOptions !== 'number') {\n          encoderOptions = undefined;\n        }\n        return this.canvas.toDataURL(type, encoderOptions);\n    }\n  }\n\n  public on(): void {\n    // Disable panning/zooming when touching canvas element\n    this.canvas.style.touchAction = 'none';\n    this.canvas.style.msTouchAction = 'none';\n    this.canvas.style.userSelect = 'none';\n\n    const isIOS =\n      /Macintosh/.test(navigator.userAgent) && 'ontouchstart' in document;\n\n    // The \"Scribble\" feature of iOS intercepts point events. So that we can lose some of them when tapping rapidly.\n    // Use touch events for iOS platforms to prevent it. See https://developer.apple.com/forums/thread/664108 for more information.\n    if (window.PointerEvent && !isIOS) {\n      this._handlePointerEvents();\n    } else {\n      this._handleMouseEvents();\n\n      if ('ontouchstart' in window) {\n        this._handleTouchEvents();\n      }\n    }\n  }\n\n  public off(): void {\n    // Enable panning/zooming when touching canvas element\n    this.canvas.style.touchAction = 'auto';\n    this.canvas.style.msTouchAction = 'auto';\n    this.canvas.style.userSelect = 'auto';\n\n    this.canvas.removeEventListener('pointerdown', this._handlePointerStart);\n    this.canvas.removeEventListener('pointermove', this._handlePointerMove);\n    this.canvas.ownerDocument.removeEventListener(\n      'pointerup',\n      this._handlePointerEnd,\n    );\n\n    this.canvas.removeEventListener('mousedown', this._handleMouseDown);\n    this.canvas.removeEventListener('mousemove', this._handleMouseMove);\n    this.canvas.ownerDocument.removeEventListener(\n      'mouseup',\n      this._handleMouseUp,\n    );\n\n    this.canvas.removeEventListener('touchstart', this._handleTouchStart);\n    this.canvas.removeEventListener('touchmove', this._handleTouchMove);\n    this.canvas.removeEventListener('touchend', this._handleTouchEnd);\n  }\n\n  public isEmpty(): boolean {\n    return this._isEmpty;\n  }\n\n  public fromData(\n    pointGroups: PointGroup[],\n    { clear = true }: FromDataOptions = {},\n  ): void {\n    if (clear) {\n      this.clear();\n    }\n\n    this._fromData(\n      pointGroups,\n      this._drawCurve.bind(this),\n      this._drawDot.bind(this),\n    );\n\n    this._data = this._data.concat(pointGroups);\n  }\n\n  public toData(): PointGroup[] {\n    return this._data;\n  }\n\n  // Event handlers\n  private _handleMouseDown = (event: MouseEvent): void => {\n    if (event.buttons === 1) {\n      this._strokeBegin(event);\n    }\n  };\n\n  private _handleMouseMove = (event: MouseEvent): void => {\n    this._strokeMoveUpdate(event);\n  };\n\n  private _handleMouseUp = (event: MouseEvent): void => {\n    if (event.buttons === 1) {\n      this._strokeEnd(event);\n    }\n  };\n\n  private _handleTouchStart = (event: TouchEvent): void => {\n    // Prevent scrolling.\n    if (event.cancelable) {\n      event.preventDefault();\n    }\n\n    if (event.targetTouches.length === 1) {\n      const touch = event.changedTouches[0];\n      this._strokeBegin(touch);\n    }\n  };\n\n  private _handleTouchMove = (event: TouchEvent): void => {\n    // Prevent scrolling.\n    if (event.cancelable) {\n      event.preventDefault();\n    }\n\n    const touch = event.targetTouches[0];\n    this._strokeMoveUpdate(touch);\n  };\n\n  private _handleTouchEnd = (event: TouchEvent): void => {\n    const wasCanvasTouched = event.target === this.canvas;\n    if (wasCanvasTouched) {\n      if (event.cancelable) {\n        event.preventDefault();\n      }\n      const touch = event.changedTouches[0];\n      this._strokeEnd(touch);\n    }\n  };\n\n  private _handlePointerStart = (event: PointerEvent): void => {\n    event.preventDefault();\n    this._strokeBegin(event);\n  };\n\n  private _handlePointerMove = (event: PointerEvent): void => {\n    this._strokeMoveUpdate(event);\n  };\n\n  private _handlePointerEnd = (event: PointerEvent): void => {\n    if (this._drawingStroke) {\n      event.preventDefault();\n      this._strokeEnd(event);\n    }\n  };\n\n  private _getPointGroupOptions(group?: PointGroup): PointGroupOptions {\n    return {\n      penColor: group && 'penColor' in group ? group.penColor : this.penColor,\n      dotSize: group && 'dotSize' in group ? group.dotSize : this.dotSize,\n      minWidth: group && 'minWidth' in group ? group.minWidth : this.minWidth,\n      maxWidth: group && 'maxWidth' in group ? group.maxWidth : this.maxWidth,\n      velocityFilterWeight:\n        group && 'velocityFilterWeight' in group\n          ? group.velocityFilterWeight\n          : this.velocityFilterWeight,\n      compositeOperation:\n        group && 'compositeOperation' in group\n          ? group.compositeOperation\n          : this.compositeOperation,\n    };\n  }\n\n  // Private methods\n  private _strokeBegin(event: SignatureEvent): void {\n    const cancelled = !this.dispatchEvent(\n      new CustomEvent('beginStroke', { detail: event, cancelable: true }),\n    );\n    if (cancelled) {\n      return;\n    }\n    this._drawingStroke = true;\n\n    const pointGroupOptions = this._getPointGroupOptions();\n\n    const newPointGroup: PointGroup = {\n      ...pointGroupOptions,\n      points: [],\n    };\n\n    this._data.push(newPointGroup);\n    this._reset(pointGroupOptions);\n    this._strokeUpdate(event);\n  }\n\n  private _strokeUpdate(event: SignatureEvent): void {\n    if (!this._drawingStroke) {\n      return;\n    }\n\n    if (this._data.length === 0) {\n      // This can happen if clear() was called while a signature is still in progress,\n      // or if there is a race condition between start/update events.\n      this._strokeBegin(event);\n      return;\n    }\n\n    this.dispatchEvent(\n      new CustomEvent('beforeUpdateStroke', { detail: event }),\n    );\n\n    const x = event.clientX;\n    const y = event.clientY;\n    const pressure =\n      (event as PointerEvent).pressure !== undefined\n        ? (event as PointerEvent).pressure\n        : (event as Touch).force !== undefined\n          ? (event as Touch).force\n          : 0;\n\n    const point = this._createPoint(x, y, pressure);\n    const lastPointGroup = this._data[this._data.length - 1];\n    const lastPoints = lastPointGroup.points;\n    const lastPoint =\n      lastPoints.length > 0 && lastPoints[lastPoints.length - 1];\n    const isLastPointTooClose = lastPoint\n      ? point.distanceTo(lastPoint) <= this.minDistance\n      : false;\n    const pointGroupOptions = this._getPointGroupOptions(lastPointGroup);\n\n    // Skip this point if it's too close to the previous one\n    if (!lastPoint || !(lastPoint && isLastPointTooClose)) {\n      const curve = this._addPoint(point, pointGroupOptions);\n\n      if (!lastPoint) {\n        this._drawDot(point, pointGroupOptions);\n      } else if (curve) {\n        this._drawCurve(curve, pointGroupOptions);\n      }\n\n      lastPoints.push({\n        time: point.time,\n        x: point.x,\n        y: point.y,\n        pressure: point.pressure,\n      });\n    }\n\n    this.dispatchEvent(new CustomEvent('afterUpdateStroke', { detail: event }));\n  }\n\n  private _strokeEnd(event: SignatureEvent): void {\n    if (!this._drawingStroke) {\n      return;\n    }\n\n    this._strokeUpdate(event);\n\n    this._drawingStroke = false;\n    this.dispatchEvent(new CustomEvent('endStroke', { detail: event }));\n  }\n\n  private _handlePointerEvents(): void {\n    this._drawingStroke = false;\n\n    this.canvas.addEventListener('pointerdown', this._handlePointerStart);\n    this.canvas.addEventListener('pointermove', this._handlePointerMove);\n    this.canvas.ownerDocument.addEventListener(\n      'pointerup',\n      this._handlePointerEnd,\n    );\n  }\n\n  private _handleMouseEvents(): void {\n    this._drawingStroke = false;\n\n    this.canvas.addEventListener('mousedown', this._handleMouseDown);\n    this.canvas.addEventListener('mousemove', this._handleMouseMove);\n    this.canvas.ownerDocument.addEventListener('mouseup', this._handleMouseUp);\n  }\n\n  private _handleTouchEvents(): void {\n    this.canvas.addEventListener('touchstart', this._handleTouchStart);\n    this.canvas.addEventListener('touchmove', this._handleTouchMove);\n    this.canvas.addEventListener('touchend', this._handleTouchEnd);\n  }\n\n  // Called when a new line is started\n  private _reset(options: PointGroupOptions): void {\n    this._lastPoints = [];\n    this._lastVelocity = 0;\n    this._lastWidth = (options.minWidth + options.maxWidth) / 2;\n    this._ctx.fillStyle = options.penColor;\n    this._ctx.globalCompositeOperation = options.compositeOperation;\n  }\n\n  private _createPoint(x: number, y: number, pressure: number): Point {\n    const rect = this.canvas.getBoundingClientRect();\n\n    return new Point(\n      x - rect.left,\n      y - rect.top,\n      pressure,\n      new Date().getTime(),\n    );\n  }\n\n  // Add point to _lastPoints array and generate a new curve if there are enough points (i.e. 3)\n  private _addPoint(point: Point, options: PointGroupOptions): Bezier | null {\n    const { _lastPoints } = this;\n\n    _lastPoints.push(point);\n\n    if (_lastPoints.length > 2) {\n      // To reduce the initial lag make it work with 3 points\n      // by copying the first point to the beginning.\n      if (_lastPoints.length === 3) {\n        _lastPoints.unshift(_lastPoints[0]);\n      }\n\n      // _points array will always have 4 points here.\n      const widths = this._calculateCurveWidths(\n        _lastPoints[1],\n        _lastPoints[2],\n        options,\n      );\n      const curve = Bezier.fromPoints(_lastPoints, widths);\n\n      // Remove the first element from the list, so that there are no more than 4 points at any time.\n      _lastPoints.shift();\n\n      return curve;\n    }\n\n    return null;\n  }\n\n  private _calculateCurveWidths(\n    startPoint: Point,\n    endPoint: Point,\n    options: PointGroupOptions,\n  ): { start: number; end: number } {\n    const velocity =\n      options.velocityFilterWeight * endPoint.velocityFrom(startPoint) +\n      (1 - options.velocityFilterWeight) * this._lastVelocity;\n\n    const newWidth = this._strokeWidth(velocity, options);\n\n    const widths = {\n      end: newWidth,\n      start: this._lastWidth,\n    };\n\n    this._lastVelocity = velocity;\n    this._lastWidth = newWidth;\n\n    return widths;\n  }\n\n  private _strokeWidth(velocity: number, options: PointGroupOptions): number {\n    return Math.max(options.maxWidth / (velocity + 1), options.minWidth);\n  }\n\n  private _drawCurveSegment(x: number, y: number, width: number): void {\n    const ctx = this._ctx;\n\n    ctx.moveTo(x, y);\n    ctx.arc(x, y, width, 0, 2 * Math.PI, false);\n    this._isEmpty = false;\n  }\n\n  private _drawCurve(curve: Bezier, options: PointGroupOptions): void {\n    const ctx = this._ctx;\n    const widthDelta = curve.endWidth - curve.startWidth;\n    // '2' is just an arbitrary number here. If only length is used, then\n    // there are gaps between curve segments :/\n    const drawSteps = Math.ceil(curve.length()) * 2;\n\n    ctx.beginPath();\n    ctx.fillStyle = options.penColor;\n\n    for (let i = 0; i < drawSteps; i += 1) {\n      // Calculate the Bezier (x, y) coordinate for this step.\n      const t = i / drawSteps;\n      const tt = t * t;\n      const ttt = tt * t;\n      const u = 1 - t;\n      const uu = u * u;\n      const uuu = uu * u;\n\n      let x = uuu * curve.startPoint.x;\n      x += 3 * uu * t * curve.control1.x;\n      x += 3 * u * tt * curve.control2.x;\n      x += ttt * curve.endPoint.x;\n\n      let y = uuu * curve.startPoint.y;\n      y += 3 * uu * t * curve.control1.y;\n      y += 3 * u * tt * curve.control2.y;\n      y += ttt * curve.endPoint.y;\n\n      const width = Math.min(\n        curve.startWidth + ttt * widthDelta,\n        options.maxWidth,\n      );\n      this._drawCurveSegment(x, y, width);\n    }\n\n    ctx.closePath();\n    ctx.fill();\n  }\n\n  private _drawDot(point: BasicPoint, options: PointGroupOptions): void {\n    const ctx = this._ctx;\n    const width =\n      options.dotSize > 0\n        ? options.dotSize\n        : (options.minWidth + options.maxWidth) / 2;\n\n    ctx.beginPath();\n    this._drawCurveSegment(point.x, point.y, width);\n    ctx.closePath();\n    ctx.fillStyle = options.penColor;\n    ctx.fill();\n  }\n\n  private _fromData(\n    pointGroups: PointGroup[],\n    drawCurve: SignaturePad['_drawCurve'],\n    drawDot: SignaturePad['_drawDot'],\n  ): void {\n    for (const group of pointGroups) {\n      const { points } = group;\n      const pointGroupOptions = this._getPointGroupOptions(group);\n\n      if (points.length > 1) {\n        for (let j = 0; j < points.length; j += 1) {\n          const basicPoint = points[j];\n          const point = new Point(\n            basicPoint.x,\n            basicPoint.y,\n            basicPoint.pressure,\n            basicPoint.time,\n          );\n\n          if (j === 0) {\n            this._reset(pointGroupOptions);\n          }\n\n          const curve = this._addPoint(point, pointGroupOptions);\n\n          if (curve) {\n            drawCurve(curve, pointGroupOptions);\n          }\n        }\n      } else {\n        this._reset(pointGroupOptions);\n\n        drawDot(points[0], pointGroupOptions);\n      }\n    }\n  }\n\n  public toSVG({ includeBackgroundColor = false }: ToSVGOptions = {}): string {\n    const pointGroups = this._data;\n    const ratio = Math.max(window.devicePixelRatio || 1, 1);\n    const minX = 0;\n    const minY = 0;\n    const maxX = this.canvas.width / ratio;\n    const maxY = this.canvas.height / ratio;\n    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n\n    svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');\n    svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n    svg.setAttribute('viewBox', `${minX} ${minY} ${maxX} ${maxY}`);\n    svg.setAttribute('width', maxX.toString());\n    svg.setAttribute('height', maxY.toString());\n\n    if (includeBackgroundColor && this.backgroundColor) {\n      const rect = document.createElement('rect');\n      rect.setAttribute('width', '100%');\n      rect.setAttribute('height', '100%');\n      rect.setAttribute('fill', this.backgroundColor);\n\n      svg.appendChild(rect);\n    }\n\n    this._fromData(\n      pointGroups,\n\n      (curve, { penColor }) => {\n        const path = document.createElement('path');\n\n        // Need to check curve for NaN values, these pop up when drawing\n        // lines on the canvas that are not continuous. E.g. Sharp corners\n        // or stopping mid-stroke and than continuing without lifting mouse.\n        /* eslint-disable no-restricted-globals */\n        if (\n          !isNaN(curve.control1.x) &&\n          !isNaN(curve.control1.y) &&\n          !isNaN(curve.control2.x) &&\n          !isNaN(curve.control2.y)\n        ) {\n          const attr =\n            `M ${curve.startPoint.x.toFixed(3)},${curve.startPoint.y.toFixed(\n              3,\n            )} ` +\n            `C ${curve.control1.x.toFixed(3)},${curve.control1.y.toFixed(3)} ` +\n            `${curve.control2.x.toFixed(3)},${curve.control2.y.toFixed(3)} ` +\n            `${curve.endPoint.x.toFixed(3)},${curve.endPoint.y.toFixed(3)}`;\n          path.setAttribute('d', attr);\n          path.setAttribute('stroke-width', (curve.endWidth * 2.25).toFixed(3));\n          path.setAttribute('stroke', penColor);\n          path.setAttribute('fill', 'none');\n          path.setAttribute('stroke-linecap', 'round');\n\n          svg.appendChild(path);\n        }\n        /* eslint-enable no-restricted-globals */\n      },\n\n      (point, { penColor, dotSize, minWidth, maxWidth }) => {\n        const circle = document.createElement('circle');\n        const size = dotSize > 0 ? dotSize : (minWidth + maxWidth) / 2;\n        circle.setAttribute('r', size.toString());\n        circle.setAttribute('cx', point.x.toString());\n        circle.setAttribute('cy', point.y.toString());\n        circle.setAttribute('fill', penColor);\n\n        svg.appendChild(circle);\n      },\n    );\n\n    return svg.outerHTML;\n  }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-this-alias */\n// Slightly simplified version of http://stackoverflow.com/a/27078401/815507\n\nexport function throttle(\n  fn: (...args: any[]) => any,\n  wait = 250,\n): (this: any, ...args: any[]) => any {\n  let previous = 0;\n  let timeout: number | null = null;\n  let result: any;\n  let storedContext: any;\n  let storedArgs: any[];\n\n  const later = (): void => {\n    previous = Date.now();\n    timeout = null;\n    result = fn.apply(storedContext, storedArgs);\n\n    if (!timeout) {\n      storedContext = null;\n      storedArgs = [];\n    }\n  };\n\n  return function wrapper(this: any, ...args: any[]): any {\n    const now = Date.now();\n    const remaining = wait - (now - previous);\n\n    storedContext = this;\n    storedArgs = args;\n\n    if (remaining <= 0 || remaining > wait) {\n      if (timeout) {\n        clearTimeout(timeout);\n        timeout = null;\n      }\n\n      previous = now;\n      result = fn.apply(storedContext, storedArgs);\n\n      if (!timeout) {\n        storedContext = null;\n        storedArgs = [];\n      }\n    } else if (!timeout) {\n      timeout = window.setTimeout(later, remaining);\n    }\n\n    return result;\n  };\n}\n"],"names":["Point","constructor","x","y","pressure","time","isNaN","Error","this","Date","now","distanceTo","start","Math","sqrt","pow","equals","other","velocityFrom","Bezier","fromPoints","points","widths","c2","calculateControlPoints","c3","c1","end","s1","s2","s3","dx1","dy1","dx2","dy2","m1","m2","l1","l2","k","cm","tx","ty","startPoint","control2","control1","endPoint","startWidth","endWidth","length","px","py","i","t","cx","point","cy","xdiff","ydiff","SignatureEventTarget","_et","EventTarget","error","document","addEventListener","type","listener","options","dispatchEvent","event","removeEventListener","callback","SignaturePad","canvas","super","_drawingStroke","_isEmpty","_lastPoints","_data","_lastVelocity","_lastWidth","_handleMouseDown","buttons","_strokeBegin","_handleMouseMove","_strokeMoveUpdate","_handleMouseUp","_strokeEnd","_handleTouchStart","cancelable","preventDefault","targetTouches","touch","changedTouches","_handleTouchMove","_handleTouchEnd","target","_handlePointerStart","_handlePointerMove","_handlePointerEnd","velocityFilterWeight","minWidth","maxWidth","throttle","minDistance","dotSize","penColor","backgroundColor","compositeOperation","canvasContextOptions","fn","wait","result","storedContext","storedArgs","previous","timeout","later","apply","args","remaining","clearTimeout","window","setTimeout","prototype","_strokeUpdate","_ctx","getContext","clear","on","ctx","fillStyle","clearRect","width","height","fillRect","_reset","_getPointGroupOptions","fromDataURL","dataUrl","Promise","resolve","reject","image","Image","ratio","devicePixelRatio","xOffset","yOffset","onload","drawImage","onerror","crossOrigin","src","toDataURL","encoderOptions","undefined","btoa","toSVG","style","touchAction","msTouchAction","userSelect","isIOS","test","navigator","userAgent","PointerEvent","_handlePointerEvents","_handleMouseEvents","_handleTouchEvents","off","ownerDocument","isEmpty","fromData","pointGroups","_fromData","_drawCurve","bind","_drawDot","concat","toData","group","CustomEvent","detail","pointGroupOptions","newPointGroup","push","clientX","clientY","force","_createPoint","lastPointGroup","lastPoints","lastPoint","isLastPointTooClose","curve","_addPoint","globalCompositeOperation","rect","getBoundingClientRect","left","top","getTime","unshift","_calculateCurveWidths","shift","velocity","newWidth","_strokeWidth","max","_drawCurveSegment","moveTo","arc","PI","widthDelta","drawSteps","ceil","beginPath","tt","ttt","u","uu","uuu","min","closePath","fill","drawCurve","drawDot","j","basicPoint","includeBackgroundColor","maxX","maxY","svg","createElementNS","setAttribute","toString","createElement","appendChild","path","attr","toFixed","circle","size","outerHTML"],"mappings":"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"}