web-handwriting-board
Version:
一个简单易用的web手写板,适合在有手写签名需求的场景使用
2 lines (1 loc) • 3.16 kB
JavaScript
(function(d,c){typeof exports=="object"&&typeof module!="undefined"?c(exports):typeof define=="function"&&define.amd?define(["exports"],c):(d=typeof globalThis!="undefined"?globalThis:d||self,c(d["handwriting-board"]={}))})(this,function(d){"use strict";function c(h,t,e){const o=document.createElement("canvas");e&&o.classList.add(e);const s=o.getContext("2d"),n=window.devicePixelRatio;return o.style.cssText=`width:${h}px;height:${t}px;`,o.width=h*n,o.height=t*n,s.scale(n,n),{canvas:o,ctx:s}}function l(h){const t={top:0,left:0};let e=h;for(;e!==document.body;){if(t.top+=e.offsetTop,t.left+=e.offsetLeft,!e.offsetParent)return t;e=e.offsetParent}return t}const p={width:500,height:300,lineWidth:5,lineColor:"#000000",lineCap:"round",eraserSize:20},g=function(){return/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)}();class m{constructor(t){this.isMousedown=!1,this.undoStack=[],this.redoStack=[],this.option=Object.assign(p,t);const{canvas:e,ctx:o}=c(this.option.width,this.option.height,this.option.canvasClass);this.canvas=e,this.ctx=o,this._initEvent(this.canvas),this.option.el&&this.mount(this.option.el)}_initEvent(t){let e;const o=i=>{if(i.offsetX>=0&&i.offsetY>=0)return{offsetX:i.offsetX,offsetY:i.offsetY};const{top:a,left:r}=l(this.canvas),f=i.changedTouches[0];return{offsetX:f.pageX-r,offsetY:f.pageY-a}},s=i=>{this.isMousedown=!0;const{offsetX:a,offsetY:r}=o(i);this.undoStack.push([[a,r]]),e=[a,r]},n=i=>{if(!this.isMousedown)return;const{offsetX:a,offsetY:r}=o(i);this.undoStack[this.undoStack.length-1].push([a,r]),this._renderLine(e,[a,r]),e=[a,r]},u=()=>{this.isMousedown=!1};g?(t.addEventListener("touchstart",s,!1),t.addEventListener("touchmove",n,!1),t.addEventListener("touchend",u,!1)):(t.addEventListener("mousedown",s,!1),t.addEventListener("mousemove",n,!1),t.addEventListener("mouseup",u,!1),t.addEventListener("mouseleave",()=>{this.isMousedown=!1},!1))}_renderLine(t,e){const{ctx:o}=this;o.save(),o.beginPath(),o.lineCap=this.option.lineCap,o.moveTo(t[0],t[1]),o.lineTo(e[0],e[1]),o.strokeStyle=this.option.lineColor,o.lineWidth=this.option.lineWidth,o.stroke(),o.restore()}_clearCanvas(){this.ctx.clearRect(0,0,this.option.width,this.option.height)}_render(t){this._clearCanvas();for(let e=0;e<t.length;e++){const o=t[e];for(let s=1;s<o.length;s++)this._renderLine(o[s-1],o[s])}}mount(t){if(typeof t=="string"&&(t=document.querySelector(t)),!t)throw new Error("Please provide the mount point");t.appendChild(this.canvas)}undo(){this.undoStack.length!==0&&(this.redoStack.push(this.undoStack.pop()),this._render(this.undoStack))}redo(){this.redoStack.length!==0&&(this.undoStack.push(this.redoStack.pop()),this._render(this.undoStack))}reset(){this._clearCanvas(),this.undoStack=[],this.redoStack=[]}getImage(t="image/png",e=.92){return this.canvas.toDataURL(t,e)}getImageBlob(t="image/png",e=.92){return new Promise((o,s)=>{this.canvas.toBlob(n=>{n?o(n):s(n)},t,e)})}download(t=""){const e=document.createElement("a");e.download=t,e.href=this.getImage(),e.click()}}d.HandwritingBoard=m,Object.defineProperties(d,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});