jianghh-canvas
Version:
canvas画板,支持笔写、手写、鼠标流畅绘图,自动保存,撤销重做
2 lines (1 loc) • 6.26 kB
JavaScript
"use strict";var c=Object.defineProperty;var p=(n,t,e)=>t in n?c(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var i=(n,t,e)=>(p(n,typeof t!="symbol"?t+"":t,e),e);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const u=require("./utils/index.js"),d=require("./stack/index.js"),f=require("./event/index.js");class r{constructor(t){i(this,"options",{currentTool:"Marker",createBufferCanvasStyle:{},allowType:["pen","mouse","touch"],allowButton:[0],eraseSize:16});i(this,"el");i(this,"isRevoke",!1);i(this,"cacheStack");i(this,"beginPoint",{x:0,y:0});i(this,"endPoint");i(this,"points",[]);i(this,"currentTool","Marker");i(this,"bufferCanvas");i(this,"allowType");i(this,"allowButton");i(this,"containerHeightOffset",0);i(this,"dpr",1);i(this,"width");i(this,"height");i(this,"eraseSize");i(this,"$on");i(this,"$emit");i(this,"$off");Object.assign(this.options,t),this.dpr=window.devicePixelRatio,typeof this.options.el=="string"?this.el=document.querySelector(this.options.el):this.el=this.options.el,this.options.containerHeightOffset&&(this.containerHeightOffset=this.options.containerHeightOffset),this.options.width&&(this.el.style.width=this.options.width+"px",this.width=this.ctx.canvas.width=this.options.width*this.dpr),this.options.height&&(this.el.style.height=this.options.height-this.containerHeightOffset+"px",this.height=this.ctx.canvas.height=(this.options.height-this.containerHeightOffset)*this.dpr),this.ctx.scale(this.dpr,this.dpr),this.options.lineWidth&&(this.lineWidth=this.options.lineWidth),this.options.color&&(this.color=this.options.color),this.allowType=this.options.allowType,this.allowButton=this.options.allowButton,this.eraseSize=this.options.eraseSize,this.options.currentTool==="Cursor"?this.el.style.touchAction="auto":this.el.style.touchAction="none",this.currentTool=this.options.currentTool,d.useStack(this,t.cacheSize),f.useEventBus(this),this.init()}get color(){return this.ctx.fillStyle}set color(t){this.ctx.strokeStyle=t,this.ctx.fillStyle=t}get lineWidth(){return this.ctx.lineWidth}set lineWidth(t){this.ctx.lineWidth=t}get tool(){return u[this.currentTool]}set tool(t){this.setCurrentTool(t)}get ctx(){return this.el.getContext("2d")}get bufferCtx(){var t;return(t=this.bufferCanvas)==null?void 0:t.getContext("2d")}init(){this.el.style.touchAction="none",this.pointerdown=this.pointerdown.bind(this),this.pointermove=this.pointermove.bind(this),this.pointerup=this.pointerup.bind(this),this.bindCanvasEventListener(),this.ctx.lineCap="round",this.ctx.lineJoin="round"}fixContent(t,e){this.ctx.lineCap="round",this.ctx.lineJoin="round",this.color=e,this.lineWidth=t}bindCanvasEventListener(){this.el.addEventListener("pointerdown",this.pointerdown)}removeEventListener(t=["pointerdown","pointermove","pointerup"]){t.forEach(e=>{this.el.removeEventListener(e,this[e]),document.removeEventListener(e,this[e])})}updateHeight(t){this.cacheStack.preItem||this.emitStackChange();const e=this.color,s=this.lineWidth;this.ctx.canvas.height=(t-this.containerHeightOffset)*this.dpr,this.ctx.canvas.style.height=t-this.containerHeightOffset+"px",this.reviewImg(this.cacheStack.preItem,!0,()=>{this.fixContent(s,e),this.ctx.scale(this.dpr,this.dpr),this.emitStackChange()})}pointerdown(t){var e,s;t.pointerType==="mouse"&&!this.allowButton.includes(t.button)||t.pressure!==0&&(this.beginPoint={x:t.offsetX,y:t.offsetY},t.preventDefault(),this.tool.buffer&&this.createBufferCanvas(),this.cacheStack.preItem||this.emitStackChange(),this.tool&&((s=(e=this.tool)==null?void 0:e.pointerdown)==null||s.call(this,t)),this.el.addEventListener("pointermove",this.pointermove),document.addEventListener("pointerup",this.pointerup))}pointermove(t){var e,s;t.preventDefault(),(s=(e=this.tool)==null?void 0:e.pointermove)==null||s.call(this,t)}pointerup(t){var e,s,o;t.preventDefault(),(s=(e=this.tool)==null?void 0:e.pointerup)==null||s.call(this,t),this.removeEventListener(["pointermove","pointerup"]),this.emitStackChange(),this.beginPoint={x:0,y:0},this.endPoint=void 0,this.points=[],(o=this.bufferCanvas)==null||o.remove()}revoke(){const t=this.cacheStack.pop();t&&this.reviewImg(t,!1),this.$emit("cacheChange",t,this.cacheStack.revokeSize,this.cacheStack.redoSize)}redo(){const t=this.cacheStack.popRedo();t&&this.reviewImg(t,!1),this.$emit("cacheChange",t,this.cacheStack.revokeSize,this.cacheStack.redoSize)}clear(){this.ctx.clearRect(0,0,this.el.width,this.el.height)}emitStackChange(){const t=this.toDataURL();this.cacheStack.push(t),this.$emit("cacheChange",t,this.cacheStack.revokeSize,this.cacheStack.redoSize)}reviewImg(t,e=!0,s){const o=this;if(!t)return;let h=new Image;h.src=t,h.onload=function(){if(e)o.clear(),o.ctx.drawImage(h,0,0,h.width,h.height),s&&s();else{const l=o.color,a=o.lineWidth;o.ctx.canvas.height=h.height,o.ctx.canvas.style.height=h.height/o.dpr+"px",o.el.parentElement.style.height=h.height/o.dpr+o.containerHeightOffset+"px",o.fixContent(a,l),o.ctx.drawImage(h,0,0,h.width,h.height),o.ctx.scale(o.dpr,o.dpr),s&&s()}h=null}}createBufferCanvas(){const t=this.el.cloneNode();t.style.zIndex+=100,t.style.pointerEvents="none",t.style.position="absolute",t.style.left=this.el.offsetLeft+"px",t.style.top=this.el.offsetTop+"px";const e=this.options.createBufferCanvasStyle;if(e)for(const s in e)t.setAttribute(s,e[s]);this.el.parentElement.appendChild(t),this.bufferCanvas=t,this.bufferCtx.scale(this.dpr,this.dpr),this.bufferCtx.fillStyle=this.color,this.bufferCtx.strokeStyle=this.color,this.bufferCtx.lineWidth=this.lineWidth}destroy(t){this.removeEventListener(),this.cacheStack.clear(),t&&this.el.remove()}toDataURL(t="image/png",e=.92){return this.el.toDataURL(t,e)}toPicFile(t="0.png"){return new Promise(e=>{this.el.toBlob(s=>{s&&e(new File([s],t))})})}setCurrentTool(t){t==="Cursor"?this.el.style.touchAction="auto":this.el.style.touchAction="none",this.currentTool=t}}i(r,"toolList",[{label:"光标",value:"Cursor"},{label:"记号笔",value:"Marker"},{label:"钢笔",value:"Pen"},{label:"直线",value:"Line"},{label:"空心矩形",value:"Rect"},{label:"空心圆",value:"Arc"}]),i(r,"allowTypes",[{label:"鼠标",value:"mouse"},{label:"手写",value:"touch"},{label:"笔写",value:"pen"}]);exports.CanvasGraffiti=r;exports.default=r;