jdebugcanvasjs
Version:
Nice features-rich debugging utility for canvas rendering
1 lines • 4.75 kB
JavaScript
class JDebugCanvas{#t=null;ctx=null;#s=!1;#i={lines:[],visibleLineCount:Math.floor(200/15),lineHeight:15,fontSize:12,stackSize:50};#e="auto";settings={autoshow:!0,width:200,height:200,cpos:null,bg:null,position:["top-left","bottom-left"]};#n=null;#h={src:null,dimensions:{}};constructor(){return this.#t=document.createElement("canvas"),this.#t.classList.add("debugging-canvas"),this.#t.width=200,this.#t.height=200,this.#t.style.position="fixed",this.#t.style.width="200px",this.#t.style.height="200px",this.#t.style.border="1px solid white",this.#t.style.outline="3px solid black",document.body.append(this.#t),this.ctx=this.#t.getContext("2d"),this.ctx.imageSmoothingEnabled=!1,this.#o(),this.setSetting("position","top-right"),this}get opened(){return this.#s}get mode(){return this.#e}#o(){let t=this;this.#t.addEventListener("click",(function(){t.close()})),this.#t.addEventListener("mouseenter",(function(){t.repos()}))}render(t){if("console"==this.#e)return;let s=this.ctx,i=this,e={x:0,y:0,width:s.canvas.width,height:s.canvas.height};return this.settings.autoshow&&this.open(),t&&(this.#h.src===t||(this.#h={src:t,dimensions:this.#a(t)}),e=this.#h.dimensions),s.clearRect(0,0,s.canvas.width,s.canvas.height),"string"==typeof this.settings.bg&&(s.fillStyle=this.settings.bg,s.fillRect(0,0,s.canvas.width,s.canvas.height)),t&&s.drawImage(t.canvas,e.x,e.y,e.width,e.height),this.#n&&clearTimeout(this.#n),!0===this.settings.autoshow&&(this.#n=setTimeout((function(){i.close()}),5e3)),this}#l(){let t=this.ctx,{lines:s,visibleLineCount:i,lineHeight:e,fontSize:n}=this.#i;t.fillStyle="black",t.fillRect(0,0,t.canvas.width,t.canvas.height),t.font=`${n}px consolas`,t.fillStyle="rgb(240,240,240)";let h=Math.floor(.6*n),o=this.#t.height;for(let n=s.length-1;n>s.length-1-i;n--){const i=s[n];if(!i)continue;let a=i.length*h,l=Math.ceil(a/(t.canvas.width-5)),c=o-=e*l,r=0;i.forEach(((s,i)=>{r+5>t.canvas.width&&(r=0,c+=e),t.fillText(s,r,c),r+=h}))}this.#n&&clearTimeout(this.#n),!0===this.settings.autoshow&&(this.#n=setTimeout((function(){_this.close()}),5e3))}log(...t){if(this.#i.lines.push((">> "+this.#c(...t)).split("")),this.#i.lines.length>this.#i.stackSize&&this.#i.lines.splice(1,1),"canvas"!=this.#e)return this.#l(),this}switch(t){return"canvas"==t?this.#e="canvas":"console"==t?this.#e="console":"auto"==t&&(this.#e="auto"),this}#c(...t){let s=[];for(let i=0;i<t.length;i++){const e=t[i];if(["boolean","string","number","bigint"].includes(typeof e))s.push(e);else if(Array.isArray(e))s.push("["),s.push(this.#c(...e).split(" ").join(",")),s.push("]");else if("function"==typeof e)s.push("fn "+e.name+"()");else if(e instanceof Date)s.push(e.toString());else if("[object Object]"==Object.prototype.toString.call(e)){s.push("{");let t=[];for(const s in e){const i=e[s];t.push(` ${s}: ${i.toString()}`)}s.push(t.join(",")),s.push("}")}else s.push(e.constructor.name)}return s.join(" ")}repos(t){switch("number"!=typeof t&&(t=0===this.settings.cpos?1:0),this.settings.position[t]){case"top-left":this.#t.style.left="20px",this.#t.style.top="20px",this.#t.style.right="",this.#t.style.bottom="";break;case"top-right":this.#t.style.left="",this.#t.style.top="20px",this.#t.style.right="20px",this.#t.style.bottom="";break;case"bottom-left":this.#t.style.left="20px",this.#t.style.top="",this.#t.style.right="",this.#t.style.bottom="20px";break;case"bottom-right":this.#t.style.left="",this.#t.style.top="",this.#t.style.right="20px",this.#t.style.bottom="20px"}return this.settings.cpos=t,this}setSetting(t,s){if("position"===t){switch(s){case"top-left":this.settings.position=["top-left","bottom-left"],this.settings.cpos=1;break;case"top-right":this.settings.position=["top-right","bottom-right"],this.settings.cpos=1;break;case"bottom-left":this.settings.position=["bottom-left","top-left"],this.settings.cpos=1;break;case"bottom-right":this.settings.position=["bottom-right","top-right"],this.settings.cpos=1}this.repos()}else"size"==t?(this.#t.style.width=(this.#t.width=this.settings.width=s[0])+"px",this.#t.style.height=(this.#t.height=this.settings.height=s[1])+"px",this.ctx.imageSmoothingEnabled=!1,this.#h.src=null,this.#i.visibleLineCount=Math.floor(s[1]/this.#i.lineHeight)):"autoshow"==t?this.settings.autoshow="boolean"==typeof s?s:this.settings.autoshow:"bg"==t&&(this.settings.bg=s,this.render());return this}open(){return this.#s=!0,this.#t.style.display="inline-block",this}close(){return this.#s=!1,this.#t.style.display="none",this}toggle(){return this.#s?this.close():this.open(),this}#a(t){let s=t.canvas,i=0,e=0,n=0,h=0;const{width:o,height:a}=this.ctx.canvas,{width:l,height:c}=s;if(l>=c){i=o,e=c*(o/l),n=0,h=a/2-e/2}else{e=a,i=l*(a/c),h=0,n=o/2-i/2}return{x:n,y:h,width:i,height:e}}}export default JDebugCanvas;