From 9dcef66c215c9dbe115946bee5bbe298d249acbc Mon Sep 17 00:00:00 2001 From: Victor Seiji Hariki Date: Thu, 1 Dec 2022 18:05:14 -0300 Subject: [PATCH] some optimization Signed-off-by: Victor Seiji Hariki --- js/lib/toolbar.js | 21 ++---------- js/ui/tool/dream.js | 45 +++++++++++++++++++------ js/ui/tool/maskbrush.js | 74 +++++++++++++++++++++++++++++++++-------- 3 files changed, 97 insertions(+), 43 deletions(-) diff --git a/js/lib/toolbar.js b/js/lib/toolbar.js index d6ae9d9..bcbf3f6 100644 --- a/js/lib/toolbar.js +++ b/js/lib/toolbar.js @@ -150,7 +150,7 @@ const _toolbar_input = { return {checkbox, label}; }, - slider: (state, dataKey, text, min = 0, max = 1, step = 0.1) => { + slider: (state, dataKey, text, min = 0, max = 1, step = 0.1, cb = null) => { const slider = document.createElement("div"); const value = createSlider(text, slider, { @@ -159,6 +159,7 @@ const _toolbar_input = { step, valuecb: (v) => { state[dataKey] = v; + cb && cb(v); }, defaultValue: state[dataKey], }); @@ -172,21 +173,3 @@ const _toolbar_input = { }; }, }; - -/** - * Dream and img2img tools - */ -const _reticle_draw = (evn, snapToGrid = true) => { - const bb = getBoundingBox( - evn.x, - evn.y, - basePixelCount * scaleFactor, - basePixelCount * scaleFactor, - snapToGrid && basePixelCount - ); - - // draw targeting square reticle thingy cursor - ovCtx.lineWidth = 1; - ovCtx.strokeStyle = "#FFF"; - ovCtx.strokeRect(bb.x, bb.y, bb.w, bb.h); //origin is middle of the frame -}; diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index d980cef..5dccd6b 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -544,6 +544,28 @@ const dream_img2img_callback = (evn, state) => { } }; +/** + * Dream and img2img tools + */ +const _reticle_draw = (evn, snapToGrid = true) => { + const bb = getBoundingBox( + evn.x, + evn.y, + basePixelCount * scaleFactor, + basePixelCount * scaleFactor, + snapToGrid && basePixelCount + ); + + // draw targeting square reticle thingy cursor + ovCtx.lineWidth = 1; + ovCtx.strokeStyle = "#FFF"; + ovCtx.strokeRect(bb.x, bb.y, bb.w, bb.h); //origin is middle of the frame + + return () => { + ovCtx.clearRect(bb.x - 10, bb.y - 10, bb.w + 20, bb.h + 20); + }; +}; + /** * Registers Tools */ @@ -580,9 +602,13 @@ const dreamTool = () => state.snapToGrid = true; state.invertMask = false; state.overMaskPx = 0; - state.mousemovecb = (evn) => { + + state.erasePrevReticle = () => ovCtx.clearRect(0, 0, ovCanvas.width, ovCanvas.height); - _reticle_draw(evn, state.snapToGrid); + + state.mousemovecb = (evn) => { + state.erasePrevReticle(); + state.erasePrevReticle = _reticle_draw(evn, state.snapToGrid); }; state.dreamcb = (evn) => { dream_generate_callback(evn, state); @@ -669,9 +695,12 @@ const img2imgTool = () => state.keepBorderSize = 64; - state.mousemovecb = (evn) => { + state.erasePrevReticle = () => ovCtx.clearRect(0, 0, ovCanvas.width, ovCanvas.height); - _reticle_draw(evn, state.snapToGrid); + + state.mousemovecb = (evn) => { + state.erasePrevReticle(); + state.erasePrevReticle = _reticle_draw(evn, state.snapToGrid); const bb = getBoundingBox( evn.x, evn.y, @@ -687,7 +716,7 @@ const img2imgTool = () => const auxCtx = auxCanvas.getContext("2d"); if (state.keepBorderSize > 0) { - auxCtx.fillStyle = "#6A6AFF7F"; + auxCtx.fillStyle = "#6A6AFF30"; auxCtx.fillRect(0, 0, state.keepBorderSize, bb.h); auxCtx.fillRect(0, 0, bb.w, state.keepBorderSize); auxCtx.fillRect( @@ -702,12 +731,8 @@ const img2imgTool = () => bb.w, state.keepBorderSize ); + ovCtx.drawImage(auxCanvas, bb.x, bb.y); } - - const tmp = ovCtx.globalAlpha; - ovCtx.globalAlpha = 0.4; - ovCtx.drawImage(auxCanvas, bb.x, bb.y); - ovCtx.globalAlpha = tmp; }; state.dreamcb = (evn) => { dream_img2img_callback(evn, state); diff --git a/js/ui/tool/maskbrush.js b/js/ui/tool/maskbrush.js index 38a926c..0f7410f 100644 --- a/js/ui/tool/maskbrush.js +++ b/js/ui/tool/maskbrush.js @@ -52,11 +52,47 @@ const _mask_brush_erase_callback = (evn, state) => { maskPaintCtx.stroke(); }; +const _paint_mb_cursor = (state) => { + const v = state.brushSize; + state.cursorLayer.resize(v + 20, v + 20); + + const ctx = state.cursorLayer.ctx; + + ctx.clearRect(0, 0, v + 20, v + 20); + ctx.beginPath(); + ctx.arc( + (v + 20) / 2, + (v + 20) / 2, + state.brushSize / 2, + 0, + 2 * Math.PI, + true + ); + ctx.fillStyle = "#FFFFFF50"; + + ctx.fill(); + + if (state.preview) { + ctx.strokeStyle = "#000F"; + ctx.setLineDash([4, 2]); + ctx.stroke(); + ctx.setLineDash([]); + } +}; + const maskBrushTool = () => toolbar.registerTool( "res/icons/paintbrush.svg", "Mask Brush", (state, opt) => { + // New layer for the cursor + state.cursorLayer = imageCollection.registerLayer(null, { + after: maskPaintLayer, + bb: {x: 0, y: 0, w: state.brushSize + 20, h: state.brushSize + 20}, + }); + + _paint_mb_cursor(state); + // Draw new cursor immediately ovCtx.clearRect(0, 0, ovCanvas.width, ovCanvas.height); state.movecb({...mouse.coords.world.pos}); @@ -73,6 +109,10 @@ const maskBrushTool = () => setMask("neutral"); }, (state, opt) => { + // Don't want to keep hogging resources + imageCollection.deleteLayer(state.cursorLayer); + state.cursorLayer = null; + // Clear Listeners mouse.listen.world.onmousemove.clear(state.movecb); mouse.listen.world.onwheel.clear(state.wheelcb); @@ -104,21 +144,22 @@ const maskBrushTool = () => state.preview = false; - state.movecb = (evn) => { - // draw big translucent white blob cursor + state.clearPrevCursor = () => ovCtx.clearRect(0, 0, ovCanvas.width, ovCanvas.height); - ovCtx.beginPath(); - ovCtx.arc(evn.x, evn.y, state.brushSize / 2, 0, 2 * Math.PI, true); // for some reason 4x on an arc is === to 8x on a line??? - ovCtx.fillStyle = "#FFFFFF50"; - ovCtx.fill(); + state.movecb = (evn) => { + state.cursorLayer.moveTo( + evn.x - state.brushSize / 2 - 10, + evn.y - state.brushSize / 2 - 10 + ); - if (state.preview) { - ovCtx.strokeStyle = "#000F"; - ovCtx.setLineDash([4, 2]); - ovCtx.stroke(); - ovCtx.setLineDash([]); - } + state.clearPrevCursor = () => + ovCtx.clearRect( + evn.x - state.brushSize / 2 - 10, + evn.y - state.brushSize / 2 - 10, + evn.x + state.brushSize / 2 + 10, + evn.y + state.brushSize / 2 + 10 + ); }; state.wheelcb = (evn) => { @@ -127,7 +168,6 @@ const maskBrushTool = () => state.brushSize - Math.floor(state.config.brushScrollSpeed * evn.delta) ); - ovCtx.clearRect(0, 0, ovCanvas.width, ovCanvas.height); state.movecb(evn); } }; @@ -144,7 +184,11 @@ const maskBrushTool = () => "Brush Size", state.config.minBrushSize, state.config.maxBrushSize, - 1 + 1, + (v) => { + if (!state.cursorLayer) return; + _paint_mb_cursor(state); + } ); state.ctxmenu.brushSizeSlider = brushSizeSlider.slider; state.setBrushSize = brushSizeSlider.setValue; @@ -174,9 +218,11 @@ const maskBrushTool = () => if (previewMaskButton.classList.contains("active")) { maskPaintCanvas.classList.remove("opaque"); state.preview = false; + _paint_mb_cursor(state); } else { maskPaintCanvas.classList.add("opaque"); state.preview = true; + _paint_mb_cursor(state); } previewMaskButton.classList.toggle("active"); };