1
0
mirror of https://github.com/vichan-devel/vichan.git synced 2025-02-02 21:07:20 +01:00
vichan/js/tegaki/tegaki.min.js

5 lines
108 KiB
JavaScript
Raw Normal View History

2024-12-25 15:25:11 -03:00
/*! tegaki.js, MIT License */"use strict";var TegakiStrings={badDimensions:"Invalid dimensions.",promptWidth:"Canvas width in pixels",promptHeight:"Canvas height in pixels",confirmDelLayers:"Delete selected layers?",confirmMergeLayers:"Merge selected layers?",tooManyLayers:"Layer limit reached.",errorLoadImage:"Could not load the image.",noActiveLayer:"No active layer.",hiddenActiveLayer:"The active layer is not visible.",confirmCancel:"Are you sure? Your work will be lost.",confirmChangeCanvas:"Are you sure? Changing the canvas will clear all layers and history and disable replay recording.",color:"Color",size:"Size",alpha:"Opacity",flow:"Flow",zoom:"Zoom",layers:"Layers",switchPalette:"Switch color palette",paletteSlotReplace:"Right click to replace with the current color",layer:"Layer",addLayer:"Add layer",delLayers:"Delete layers",mergeLayers:"Merge layers",moveLayerUp:"Move up",moveLayerDown:"Move down",toggleVisibility:"Toggle visibility",newCanvas:"New",open:"Open",save:"Save",saveAs:"Save As","export":"Export",undo:"Undo",redo:"Redo",close:"Close",finish:"Finish",tip:"Tip",pressure:"Pressure",preserveAlpha:"Preserve Alpha",pen:"Pen",pencil:"Pencil",airbrush:"Airbrush",pipette:"Pipette",blur:"Blur",eraser:"Eraser",bucket:"Bucket",tone:"Tone",gapless:"Gapless",play:"Play",pause:"Pause",rewind:"Rewind",slower:"Slower",faster:"Faster",recordingEnabled:"Recording replay",errorLoadReplay:"Could not load the replay: ",loadingReplay:"Loading replay\u2026"};class TegakiTool{constructor(){this.id=0,this.name=null,this.keybind=null,this.useFlow=!1,this.useSizeDynamics=!1,this.useAlphaDynamics=!1,this.useFlowDynamics=!1,this.usePreserveAlpha=!1,this.step=0,this.size=1,this.alpha=1,this.flow=1,this.useSize=!0,this.useAlpha=!0,this.useFlow=!0,this.noCursor=!1,this.color="#000000",this.rgb=[0,0,0],this.brushSize=0,this.brushAlpha=0,this.brushFlow=0,this.stepSize=0,this.center=0,this.sizeDynamicsEnabled=!1,this.alphaDynamicsEnabled=!1,this.flowDynamicsEnabled=!1,this.preserveAlphaEnabled=!1,this.tip=-1,this.tipList=null,this.stepAcc=0,this.shapeCache=null,this.kernel=null}brushFn(e,t,a,i){}start(e,t){}commit(){}draw(e,t){}usesDynamics(){return this.useSizeDynamics||this.useAlphaDynamics||this.useFlowDynamics}enabledDynamics(){return this.sizeDynamicsEnabled||this.alphaDynamicsEnabled||this.flowDynamicsEnabled}setSize(e){this.size=e}setAlpha(e){this.alpha=e,this.brushAlpha=e}setFlow(e){this.flow=e,this.brushFlow=this.easeFlow(e)}easeFlow(e){return e}setColor(e){this.rgb=$T.hexToRgb(e)}setSizeDynamics(e){this.useSizeDynamics&&(e||this.setSize(this.size),this.sizeDynamicsEnabled=e)}setAlphaDynamics(e){this.useAlphaDynamics&&(e||this.setAlpha(this.alpha),this.alphaDynamicsEnabled=e)}setFlowDynamics(e){this.useFlowDynamics&&(e||this.setFlow(this.flow),this.flowDynamicsEnabled=e)}setPreserveAlpha(e){this.preserveAlphaEnabled=e}set(){this.setAlpha(this.alpha),this.setFlow(this.flow),this.setSize(this.size),this.setColor(Tegaki.toolColor),Tegaki.onToolChanged(this)}}class TegakiBrush extends TegakiTool{constructor(){super()}generateShape(e){}brushFn(e,t,a,i){var s,r,n,o,l,g,d,c,h,p,k,T,u,y,f,v,m,b,L,C,w,S,I,U,P,A,D,E,$;for($=this.preserveAlphaEnabled,g=this.kernel,D=this.brushAlpha,E=this.brushFlow,A=this.brushSize,s=Tegaki.activeLayer.imageData.data,r=Tegaki.ghostBuffer.data,n=Tegaki.blendBuffer.data,o=Tegaki.baseWidth,l=Tegaki.baseHeight,o,f=this.rgb[0],v=this.rgb[1],m=this.rgb[2],c=0;c<A;++c)if(!((p=t+c+i)<0||p>=l))for(d=0;d<A;++d)(h=e+d+a)<0||h>=o||(T=g[4*(c*A+d)+3]/255)<=0||(y=n[(U=4*(p*o+h))+3]/255,y+=T*E*(D-y),(P=Math.ceil(255*y))>n[U+3]&&(0===n[U]&&(r[U]=s[U],r[U+1]=s[U+1],r[U+2]=s[U+2],r[U+3]=s[U+3]),n[U]=1,n[U+3]=P,w=r[U],S=r[U+1],I=r[U+2],b=(f*y+w*(k=r[U+3]/255)*(1-y))/(u=k+y-k*y),L=(v*y+S*k*(1-y))/u,C=(m*y+I*k*(1-y))/u,s[U]=f>w?Math.ceil(b):Math.floor(b),s[U+1]=v>S?Math.ceil(L):Math.floor(L),s[U+2]=m>I?Math.ceil(C):Math.floor(C),$||(s[U+3]=Math.ceil(255*u))))}generateShapeCache(e){var t,a;if(this.shapeCache||(this.shapeCache=new Array(Tegaki.maxSize)),!this.shapeCache[0]||e)for(t=0;t<Tegaki.maxSize;++t)a=this.generateShape(
e.bgColor=$T.RgbToHex(...t.bgColor),e.toolColor=$T.RgbToHex(...t.toolColor)},initToolsFromReplay:function(){var e,t,a,i,s,r,n;t=(e=Tegaki).replayViewer;for(a in e.tools){(i=e.tools[a]).id===t.toolId&&(e.defaultTool=a),s=t.toolMap[i.id],n=["step","size","alpha","flow","tipId"];for(r of n)s[r]!==undefined&&(i[r]=s[r]);n=["sizeDynamicsEnabled","alphaDynamicsEnabled","flowDynamicsEnabled","usePreserveAlpha"];for(r of n)s[r]!==undefined&&(i[r]=!!s[r])}},resetLayers:function(){var e,t;if(Tegaki.layers.length){for(e=0,t=Tegaki.layers.length;e<t;++e)Tegaki.layersCnt.removeChild(Tegaki.layers[e].canvas);Tegaki.layers=[],Tegaki.layerCounter=0,TegakiUI.updateLayersGridClear()}TegakiLayers.addLayer(),TegakiLayers.setActiveLayer(0)},createCanvas:function(){var e,t=Tegaki;(e=$T.el("canvas")).id="tegaki-canvas",e.width=t.baseWidth,e.height=t.baseHeight,t.canvas=e,t.ctx=e.getContext("2d"),t.ctx.fillStyle=t.bgColor,t.ctx.fillRect(0,0,t.baseWidth,t.baseHeight),t.layersCnt.appendChild(e)},createTools:function(){var e,t;for(e of Tegaki.toolList)t=new e,Tegaki.tools[t.name]=t},bindGlobalEvents:function(){var e=Tegaki;if(e.replayMode)$T.on(document,"visibilitychange",Tegaki.onVisibilityChange);else{let t=TegakiCursor.getCanvas();$T.on(t,"pointermove",e.onPointerMove),$T.on(t,"pointerdown",e.onPointerDown),$T.on(t,"pointerout",e.onPointerOut),$T.on(document,"pointerup",e.onPointerUp),$T.on(document,"pointercancel",e.onPointerUp),$T.on(document,"keydown",TegakiKeybinds.resolve),$T.on(window,"beforeunload",Tegaki.onTabClose)}$T.on(e.bg,"contextmenu",e.onDummy),$T.on(window,"resize",e.onWindowResized),$T.on(window,"scroll",e.updatePosOffset)},unBindGlobalEvents:function(){var e=Tegaki;if(e.replayMode)$T.off(document,"visibilitychange",Tegaki.onVisibilityChange);else{let t=TegakiCursor.getCanvas();$T.off(t,"pointermove",e.onPointerMove),$T.off(t,"pointerdown",e.onPointerDown),$T.off(t,"pointerout",e.onPointerOut),$T.off(document,"pointerup",e.onPointerUp),$T.off(document,"pointercancel",e.onPointerUp),$T.off(document,"keydown",TegakiKeybinds.resolve),$T.off(window,"beforeunload",Tegaki.onTabClose)}$T.off(e.bg,"contextmenu",e.onDummy),$T.off(window,"resize",e.onWindowResized),$T.off(window,"scroll",e.updatePosOffset)},createBuffers(){Tegaki.ghostBuffer=new ImageData(Tegaki.baseWidth,Tegaki.baseHeight),Tegaki.blendBuffer=new ImageData(Tegaki.baseWidth,Tegaki.baseHeight),Tegaki.ghostBuffer32=new Uint32Array(Tegaki.ghostBuffer.data.buffer),Tegaki.blendBuffer32=new Uint32Array(Tegaki.blendBuffer.data.buffer)},clearBuffers(){Tegaki.ghostBuffer32.fill(0),Tegaki.blendBuffer32.fill(0)},destroyBuffers(){Tegaki.ghostBuffer=null,Tegaki.blendBuffer=null,Tegaki.ghostBuffer32=null,Tegaki.blendBuffer32=null},disableSmoothing:function(e){e.mozImageSmoothingEnabled=!1,e.webkitImageSmoothingEnabled=!1,e.msImageSmoothingEnabled=!1,e.imageSmoothingEnabled=!1},updateLayersCntSize:function(){var e=Tegaki.layersCnt.style;e.width=Tegaki.baseWidth+"px",e.height=Tegaki.baseHeight+"px"},onTabClose:function(e){e.preventDefault(),e.returnValue=""},onVisibilityChange:function(){Tegaki.replayMode&&("visible"===document.visibilityState?Tegaki.replayViewer.autoPaused&&Tegaki.replayViewer.play():Tegaki.replayViewer.playing&&Tegaki.replayViewer.autoPause())},onWindowResized:function(){Tegaki.updatePosOffset(),TegakiCursor.updateCanvasSize()},initKeybinds:function(){var e,t;if(!Tegaki.replayMode){TegakiKeybinds.bind("ctrl+z",TegakiHistory,"undo","undo","Ctrl+Z"),TegakiKeybinds.bind("ctrl+y",TegakiHistory,"redo","redo","Ctrl+Y"),TegakiKeybinds.bind("+",Tegaki,"setToolSizeUp","toolSize","Numpad +/-"),TegakiKeybinds.bind("-",Tegaki,"setToolSizeDown");for(t in Tegaki.tools)(e=Tegaki.tools[t]).keybind&&TegakiKeybinds.bind(e.keybind,e,"set")}},getPointerPos:function(e,t){return 0===t?0|(e.clientX+window.pageXOffset+Tegaki.canvasCnt.scrollLeft-Tegaki.offsetX)/Tegaki.zoomFactor:0|(e.clientY+window.pageYOffset+Tegaki.canvasCnt.scrollTop-Tegaki.offsetY)/Tegaki.zoomFactor},resume:function(){Tegaki.saveReplay&&Tegaki.replayRecorder.start(),Tegaki.bg.classList.remove("tegaki-hidden"),document.bo
0!==this.startTimeStamp&&this.recording&&(this.events.push(new TegakiEventConclusion(performance.now())),this.endTimeStamp=Date.now(),this.recording=!1)}push(e){this.recording&&(e.coalesce&&this.events[this.events.length-1].type===e.type?this.events[this.events.length-1]=e:this.events.push(e))}getEventStackSize(){var e,t;t=4;for(e of this.events)t+=e.size;return t}getHeaderSize(){return 12}getMetaSize(){return 21}getToolSize(){return 19}getToolListSize(){return 2+this.toolList.length*this.getToolSize()}writeToolList(e){var t,a,i;i=[["id","Uint8"],["size","Uint8"],["alpha","Float32"],["step","Float32"],["sizeDynamicsEnabled","Uint8"],["alphaDynamicsEnabled","Uint8"],["usePreserveAlpha","Uint8"],["tipId","Int8"],["flow","Float32"],["flowDynamicsEnabled","Uint8"]],e.writeUint8(this.toolList.length),e.writeUint8(this.getToolSize());for(t of this.toolList)for(a of i)e["write"+a[1]](t[a[0]])}writeMeta(e){e.writeUint16(this.getMetaSize()),e.writeUint32(Math.ceil(this.startTimeStamp/1e3)),e.writeUint32(Math.ceil(this.endTimeStamp/1e3)),e.writeUint16(this.canvasWidth),e.writeUint16(this.canvasHeight),e.writeUint8(this.bgColor[0]),e.writeUint8(this.bgColor[1]),e.writeUint8(this.bgColor[2]),e.writeUint8(this.toolColor[0]),e.writeUint8(this.toolColor[1]),e.writeUint8(this.toolColor[2]),e.writeUint8(this.toolId)}writeEventStack(e){var t;e.writeUint32(this.events.length);for(t of this.events)t.pack(e)}writeHeader(e,t){e.writeUint8(84),e.writeUint8(71),e.writeUint8(75),e.writeUint8(+this.compressed),e.writeUint32(t),e.writeUint8(this.tegakiVersion[0]),e.writeUint8(this.tegakiVersion[1]),e.writeUint8(this.tegakiVersion[2]),e.writeUint8(this.formatVersion)}compressData(e){return UZIP.deflateRaw(new Uint8Array(e.buf),{level:9})}toUint8Array(){var e,t,a,i,s,r;return this.startTimeStamp&&this.endTimeStamp?(e=this.getHeaderSize(),t=this.getMetaSize()+this.getToolListSize()+this.getEventStackSize(),a=new ArrayBuffer(t),i=new TegakiBinWriter(a),this.writeMeta(i),this.writeToolList(i),this.writeEventStack(i),s=this.compressData(i),i=new TegakiBinWriter(new ArrayBuffer(e+s.length)),this.writeHeader(i,t),(r=new Uint8Array(i.buf)).set(s,e),r):null}toBlob(){var e=this.toUint8Array();return e?new Blob([e.buffer],{type:this.mimeType}):null}}class TegakiReplayViewer{constructor(){this.formatVersion=1,this.compressed=!0,this.tegakiVersion=[0,0,0],this.dataSize=0,this.canvasWidth=0,this.canvasHeight=0,this.bgColor=[0,0,0],this.toolColor=[0,0,0],this.toolId=1,this.toolMap={},this.startTimeStamp=0,this.endTimeStamp=0,this.loaded=!1,this.playing=!1,this.gapless=!0,this.autoPaused=!1,this.destroyed=!1,this.speedIndex=1,this.speedList=[.5,1,2,5,10,25],this.speed=this.speedList[this.speedIndex],this.maxEventsPerFrame=50,this.maxEventCount=864e4,this.events=[],this.preludePos=0,this.currentPos=0,this.conclusionPos=0,this.duration=0,this.playTimeStart=0,this.playTimeCurrent=0,this.eventIndex=0,this.maxCanvasWH=8192,this.maxGapTime=3e3,this.uiAccTime=0,this.onFrameThis=this.onFrame.bind(this)}destroy(){this.destroyed=!0,this.pause(),this.events=null}speedUp(){this.speedIndex+1<this.speedList.length&&(this.speed=this.speedList[++this.speedIndex])}slowDown(){this.speedIndex-1>=0&&(this.speed=this.speedList[--this.speedIndex])}toggleGapless(){this.gapless=!this.gapless}getCurrentPos(){return this.currentPos}getDuration(){return this.duration}loadFromURL(e){fetch(e).then(e=>this.onResponseReady(e))["catch"](e=>this.onLoadError(e))}onResponseReady(e){e.ok?e.arrayBuffer().then(e=>this.onResponseBodyReady(e))["catch"](e=>this.onLoadError(e)):this.onLoadError(e.statusText)}onResponseBodyReady(e){this.loadFromBuffer(e),Tegaki.onReplayLoaded()}onLoadError(e){TegakiUI.printMsg(TegakiStrings.errorLoadReplay+e,0)}autoPause(){this.autoPaused=!0,this.pause()}pause(e){window.cancelAnimationFrame(this.onFrameThis),this.playing=!1,e&&(this.currentPos=0,this.eventIndex=0),Tegaki.onReplayTimeChanged(),Tegaki.onReplayPlayPauseChanged()}rewind(){this.autoPaused=!1,this.pause(!0),Tegaki.onReplayReset()}play(){this.playTimeStart=performance.now(),this.playTimeCurrent=this.playTimeStar
enableReplayControls:function(e){e?$T.id("tegaki-replay-controls").classList.remove("tegaki-hidden"):$T.id("tegaki-replay-controls").classList.add("tegaki-hidden")},setRecordingStatus:function(e){var t=$T.id("tegaki-status-replay");e?t.classList.remove("tegaki-hidden"):t.classList.add("tegaki-hidden")}},UZIP={};
/*! UZIP.js, © 2018 Photopea, MIT License */"object"==typeof module&&(module.exports=UZIP),UZIP.inflateRaw=function(e,t){return UZIP.F.inflate(e,t)},UZIP.deflateRaw=function(e,t){null==t&&(t={level:6});var a=new Uint8Array(50+Math.floor(1.1*e.length)),i=UZIP.F.deflateRaw(e,a,i,t.level);return new Uint8Array(a.buffer,0,i)},UZIP.bin={readUshort:function(e,t){return e[t]|e[t+1]<<8},writeUshort:function(e,t,a){e[t]=255&a,e[t+1]=a>>8&255},readUint:function(e,t){return 16777216*e[t+3]+(e[t+2]<<16|e[t+1]<<8|e[t])},writeUint:function(e,t,a){e[t]=255&a,e[t+1]=a>>8&255,e[t+2]=a>>16&255,e[t+3]=a>>24&255},readASCII:function(e,t,a){for(var i="",s=0;s<a;s++)i+=String.fromCharCode(e[t+s]);return i},writeASCII:function(e,t,a){for(var i=0;i<a.length;i++)e[t+i]=a.charCodeAt(i)},pad:function(e){return e.length<2?"0"+e:e},readUTF8:function(e,t,a){for(var i,s="",r=0;r<a;r++)s+="%"+UZIP.bin.pad(e[t+r].toString(16));try{i=decodeURIComponent(s)}catch(n){return UZIP.bin.readASCII(e,t,a)}return i},writeUTF8:function(e,t,a){for(var i=a.length,s=0,r=0;r<i;r++){var n=a.charCodeAt(r);if(0==(4294967168&n))e[t+s]=n,s++;else if(0==(4294965248&n))e[t+s]=192|n>>6,e[t+s+1]=128|n>>0&63,s+=2;else if(0==(4294901760&n))e[t+s]=224|n>>12,e[t+s+1]=128|n>>6&63,e[t+s+2]=128|n>>0&63,s+=3;else{if(0!=(4292870144&n))throw"e";e[t+s]=240|n>>18,e[t+s+1]=128|n>>12&63,e[t+s+2]=128|n>>6&63,e[t+s+3]=128|n>>0&63,s+=4}}return s},sizeUTF8:function(e){for(var t=e.length,a=0,i=0;i<t;i++){var s=e.charCodeAt(i);if(0==(4294967168&s))a++;else if(0==(4294965248&s))a+=2;else if(0==(4294901760&s))a+=3;else{if(0!=(4292870144&s))throw"e";a+=4}}return a}},UZIP.F={},UZIP.F.deflateRaw=function(e,t,a,i){var s=[[0,0,0,0,0],[4,4,8,4,0],[4,5,16,8,0],[4,6,16,16,0],[4,10,16,32,0],[8,16,32,32,0],[8,16,128,128,0],[8,32,128,256,0],[32,128,258,1024,1],[32,258,258,4096,1]][i],r=UZIP.F.U,n=UZIP.F._goodIndex,o=(UZIP.F._hash,UZIP.F._putsE),l=0,g=a<<3,d=0,c=e.length;if(0==i){for(;l<c;){o(t,g,l+(C=Math.min(65535,c-l))==c?1:0),g=UZIP.F._copyExact(e,l,C,t,g+8),l+=C}return g>>>3}var h=r.lits,p=r.strt,k=r.prev,T=0,u=0,y=0,f=0,v=0,m=0;c>2&&(p[m=UZIP.F._hash(e,0)]=0);for(l=0;l<c;l++){if(v=m,l+1<c-2){m=UZIP.F._hash(e,l+1);var b=l+1&32767;k[b]=p[m],p[m]=b}if(d<=l){(T>14e3||u>26697)&&c-l>100&&(d<l&&(h[T]=l-d,T+=2,d=l),g=UZIP.F._writeBlock(l==c-1||d==c?1:0,h,T,f,e,y,l-y,t,g),T=u=f=0,y=l);var L=0;l<c-2&&(L=UZIP.F._bestMatch(e,l,k,v,Math.min(s[2],c-l),s[3]));var C=L>>>16,w=65535&L;if(0!=L){w=65535&L;var S=n(C=L>>>16,r.of0);r.lhst[257+S]++;var I=n(w,r.df0);r.dhst[I]++,f+=r.exb[S]+r.dxb[I],h[T]=C<<23|l-d,h[T+1]=w<<16|S<<8|I,T+=2,d=l+C}else r.lhst[e[l]]++;u++}}for(y==l&&0!=e.length||(d<l&&(h[T]=l-d,T+=2,d=l),g=UZIP.F._writeBlock(1,h,T,f,e,y,l-y,t,g),T=0,u=0,T=u=f=0,y=l);0!=(7&g);)g++;return g>>>3},UZIP.F._bestMatch=function(e,t,a,i,s,r){var n=32767&t,o=a[n],l=n-o+32768&32767;if(o==n||i!=UZIP.F._hash(e,t-l))return 0;for(var g=0,d=0,c=Math.min(32767,t);l<=c&&0!=--r&&o!=n;){if(0==g||e[t+g]==e[t+g-l]){var h=UZIP.F._howLong(e,t,l);if(h>g){if(d=l,(g=h)>=s)break;l+2<h&&(h=l+2);for(var p=0,k=0;k<h-2;k++){var T=t-l+k+32768&32767,u=T-a[T]+32768&32767;u>p&&(p=u,o=T)}}}l+=(n=o)-(o=a[n])+32768&32767}return g<<16|d},UZIP.F._howLong=function(e,t,a){if(e[t]!=e[t-a]||e[t+1]!=e[t+1-a]||e[t+2]!=e[t+2-a])return 0;var i=t,s=Math.min(e.length,t+258);for(t+=3;t<s&&e[t]==e[t-a];)t++;return t-i},UZIP.F._hash=function(e,t){return(e[t]<<8|e[t+1])+(e[t+2]<<4)&65535},UZIP.saved=0,UZIP.F._writeBlock=function(e,t,a,i,s,r,n,o,l){var g,d,c,h,p,k,T,u,y,f=UZIP.F.U,v=UZIP.F._putsF,m=UZIP.F._putsE;f.lhst[256]++,d=(g=UZIP.F.getTrees())[0],c=g[1],h=g[2],p=g[3],k=g[4],T=g[5],u=g[6],y=g[7];var b=32+(0==(l+3&7)?0:8-(l+3&7))+(n<<3),L=i+UZIP.F.contSize(f.fltree,f.lhst)+UZIP.F.contSize(f.fdtree,f.dhst),C=i+UZIP.F.contSize(f.ltree,f.lhst)+UZIP.F.contSize(f.dtree,f.dhst);C+=14+3*T+UZIP.F.contSize(f.itree,f.ihst)+(2*f.ihst[16]+3*f.ihst[17]+7*f.ihst[18]);for(var w=0;w<286;w++)f.lhst[w]=0;for(w=0;w<30;w++)f.dhst[w]=0;for(w=0;w<19;w++)f.ihst[w]=0;var S=b<L&&b<C?0:L<C?1:2;v(o,l,e),v(o,l+1,S);l+=3;if(0==S){for(;0!=(7&l);)l++;l=UZIP.F._copyExact(s,r,n,o,l)}else{var I,U;if(1