signature.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import SignaturePad from "https://cdn.skypack.dev/pin/signature_pad@v4.1.3-nYxPKR50YjQN4V2vbxta/mode=imports,min/optimized/signature_pad.js"
  2. // 📙 Package Documentation: https://www.skypack.dev/view/signature_pad
  3. export default function signature(selector) {
  4. const signatureFile = "data/signature.png"
  5. const signatureFileEmpty = "data/more-data/signature-empty.png"
  6. const canvas = document.querySelector(selector)
  7. // https://github.com/szimek/signature_pad#options
  8. const signaturePad = new SignaturePad(canvas, {
  9. penColor: "hsl(200, 100%, 30%)",
  10. minDistance: 2,
  11. })
  12. /**
  13. if (signaturePad.isEmpty()) {
  14. document.querySelector("#clear-signature").disabled = true
  15. }
  16. else {
  17. document.querySelector("#clear-signature").disabled = false
  18. }
  19. /**/
  20. resizeCanvas()
  21. // event listeners
  22. // save signature to localStorage on change
  23. signaturePad.addEventListener("afterUpdateStroke", () => {
  24. // console.log(signaturePad.toData())
  25. setSignatureToLocalStorage()
  26. document.querySelector("#clear-signature").disabled = false
  27. })
  28. // button to reset signature
  29. document.querySelector("#clear-signature")?.addEventListener("click", () => {
  30. signaturePad.clear()
  31. // setSignatureToLocalStorage()
  32. localStorage.removeItem("dev_signature")
  33. document.querySelector("#clear-signature").disabled = true
  34. })
  35. window.onresize = resizeCanvas
  36. function setSignatureToLocalStorage() {
  37. let data = signaturePad.toDataURL("image/png")
  38. localStorage.setItem("dev_signature", data)
  39. }
  40. function getSignatureFromLocalStorageOrFile() {
  41. let data = localStorage.getItem("dev_signature");
  42. if (data) {
  43. // console.log(data)
  44. signaturePad.fromDataURL(data)
  45. disableResetButtonIfSignatureIsEmpty(data)
  46. }
  47. else {
  48. toDataURL(signatureFile).then(data => {
  49. // console.log(data)
  50. localStorage.setItem("dev_signature", data)
  51. signaturePad.fromDataURL(data)
  52. disableResetButtonIfSignatureIsEmpty(data)
  53. })
  54. }
  55. // console.log(data)
  56. }
  57. // needed for retina displays
  58. function resizeCanvas() {
  59. const ratio = Math.max(window.devicePixelRatio || 1, 1)
  60. canvas.width = canvas.offsetWidth * ratio
  61. canvas.height = canvas.offsetHeight * ratio
  62. canvas.getContext("2d").scale(ratio, ratio)
  63. getSignatureFromLocalStorageOrFile()
  64. }
  65. function disableResetButtonIfSignatureIsEmpty(testData) {
  66. toDataURL(signatureFileEmpty).then(data => {
  67. // console.log(data)
  68. // localStorage.setItem("dev_signature", data)
  69. // signaturePad.fromDataURL(data)
  70. if (testData === data) {
  71. document.querySelector("#clear-signature").disabled = true
  72. }
  73. else {
  74. document.querySelector("#clear-signature").disabled = false
  75. }
  76. })
  77. }
  78. }
  79. const toDataURL = url => fetch(url)
  80. .then(response => response.blob())
  81. .then(blob => new Promise((resolve, reject) => {
  82. const reader = new FileReader()
  83. reader.onloadend = () => resolve(reader.result)
  84. reader.onerror = reject
  85. reader.readAsDataURL(blob)
  86. }))
  87. // from https://stackoverflow.com/a/20285053