diff --git a/css/index.css b/css/index.css index 0797745..679771f 100644 --- a/css/index.css +++ b/css/index.css @@ -146,8 +146,25 @@ body { position: absolute; } +/* Mask colors for mask inversion */ +/* Filters are some magic acquired at https://codepen.io/sosuke/pen/Pjoqqp */ .maskPaintCanvas { - filter: opacity(40%); + opacity: 0%; +} + +.maskPaintCanvas.display { + opacity: 40%; + filter: invert(100%); +} + +.maskPaintCanvas.display.clear { + filter: invert(71%) sepia(46%) saturate(6615%) hue-rotate(321deg) + brightness(106%) contrast(100%); +} + +.maskPaintCanvas.display.hold { + filter: invert(41%) sepia(16%) saturate(5181%) hue-rotate(218deg) + brightness(103%) contrast(108%); } .strokeText { diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js index 97875b2..8c40d88 100644 --- a/js/ui/tool/dream.js +++ b/js/ui/tool/dream.js @@ -253,12 +253,18 @@ const dreamTool = () => mouse.listen.canvas.onmousemove.on(state.mousemovecb); mouse.listen.canvas.left.onclick.on(state.dreamcb); mouse.listen.canvas.right.onclick.on(state.erasecb); + + // Display Mask + setMask(state.invertMask ? "hold" : "clear"); }, (state, opt) => { // Clear Listeners mouse.listen.canvas.onmousemove.clear(state.mousemovecb); mouse.listen.canvas.left.onclick.clear(state.dreamcb); mouse.listen.canvas.right.onclick.clear(state.erasecb); + + // Hide Mask + setMask("none"); }, { init: (state) => { @@ -286,7 +292,10 @@ const dreamTool = () => state.ctxmenu.invertMaskLabel = _toolbar_input.checkbox( state, "invertMask", - "Invert Mask" + "Invert Mask", + () => { + setMask(state.invertMask ? "hold" : "clear"); + } ).label; // Overmasking Slider @@ -326,12 +335,18 @@ const img2imgTool = () => mouse.listen.canvas.onmousemove.on(state.mousemovecb); mouse.listen.canvas.left.onclick.on(state.dreamcb); mouse.listen.canvas.right.onclick.on(state.erasecb); + + // Display Mask + setMask(state.invertMask ? "hold" : "clear"); }, (state, opt) => { // Clear Listeners mouse.listen.canvas.onmousemove.clear(state.mousemovecb); mouse.listen.canvas.left.onclick.clear(state.dreamcb); mouse.listen.canvas.right.onclick.clear(state.erasecb); + + // Hide mask + setMask("none"); }, { init: (state) => { @@ -361,7 +376,7 @@ const img2imgTool = () => const auxCtx = auxCanvas.getContext("2d"); if (state.keepBorderSize > 0) { - auxCtx.fillStyle = "#6A6AFF50"; + auxCtx.fillStyle = "#6A6AFF7F"; auxCtx.fillRect(0, 0, state.keepBorderSize, bb.h); auxCtx.fillRect(0, 0, bb.w, state.keepBorderSize); auxCtx.fillRect( @@ -403,7 +418,10 @@ const img2imgTool = () => state.ctxmenu.invertMaskLabel = _toolbar_input.checkbox( state, "invertMask", - "Invert Mask" + "Invert Mask", + () => { + setMask(state.invertMask ? "hold" : "clear"); + } ).label; // Inpaint Full Resolution Checkbox diff --git a/js/ui/tool/maskbrush.js b/js/ui/tool/maskbrush.js index ca84d47..169f502 100644 --- a/js/ui/tool/maskbrush.js +++ b/js/ui/tool/maskbrush.js @@ -1,10 +1,34 @@ +const setMask = (state) => { + const canvas = document.querySelector("#maskPaintCanvas"); + switch (state) { + case "clear": + canvas.classList.remove("hold"); + canvas.classList.add("display", "clear"); + break; + case "hold": + canvas.classList.remove("clear"); + canvas.classList.add("display", "hold"); + break; + case "neutral": + canvas.classList.remove("clear", "hold"); + canvas.classList.add("display"); + break; + case "none": + canvas.classList.remove("display", "hold", "clear"); + break; + default: + console.debug(`Invalid mask type: ${state}`); + break; + } +}; + const _mask_brush_draw_callback = (evn, state) => { if ( (evn.initialTarget && evn.initialTarget.id === "overlayCanvas") || (!evn.initialTarget && evn.target.id === "overlayCanvas") ) { maskPaintCtx.globalCompositeOperation = "source-over"; - maskPaintCtx.strokeStyle = "#FF6A6A"; + maskPaintCtx.strokeStyle = "black"; maskPaintCtx.lineWidth = state.brushSize; maskPaintCtx.beginPath(); @@ -24,7 +48,7 @@ const _mask_brush_erase_callback = (evn, state) => { (!evn.initialTarget && evn.target.id === "overlayCanvas") ) { maskPaintCtx.globalCompositeOperation = "destination-out"; - maskPaintCtx.strokeStyle = "#FFFFFFFF"; + maskPaintCtx.strokeStyle = "black"; maskPaintCtx.lineWidth = state.brushSize; maskPaintCtx.beginPath(); @@ -54,6 +78,9 @@ const maskBrushTool = () => mouse.listen.canvas.left.onpaint.on(state.drawcb); mouse.listen.canvas.right.onpaintstart.on(state.erasecb); mouse.listen.canvas.right.onpaint.on(state.erasecb); + + // Display Mask + setMask("neutral"); }, (state, opt) => { // Clear Listeners @@ -63,6 +90,9 @@ const maskBrushTool = () => mouse.listen.canvas.left.onpaint.clear(state.drawcb); mouse.listen.canvas.right.onpaintstart.clear(state.erasecb); mouse.listen.canvas.right.onpaint.clear(state.erasecb); + + // Hide Mask + setMask("none"); }, { init: (state) => { @@ -81,10 +111,10 @@ const maskBrushTool = () => state.movecb = (evn) => { if (evn.target.id === "overlayCanvas") { - // draw big translucent red blob cursor + // draw big translucent white blob cursor 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 = "#FF6A6A50"; + ovCtx.fillStyle = "#FFFFFF50"; ovCtx.fill(); } }; diff --git a/js/ui/toolbar.js b/js/ui/toolbar.js index eb56ac9..955f6df 100644 --- a/js/ui/toolbar.js +++ b/js/ui/toolbar.js @@ -132,13 +132,16 @@ const toolbar = { * Premade inputs for populating the context menus */ const _toolbar_input = { - checkbox: (state, dataKey, text) => { + checkbox: (state, dataKey, text, cb = null) => { if (state[dataKey] === undefined) state[dataKey] = false; const checkbox = document.createElement("input"); checkbox.type = "checkbox"; checkbox.checked = state[dataKey]; - checkbox.onchange = () => (state[dataKey] = checkbox.checked); + checkbox.onchange = () => { + state[dataKey] = checkbox.checked; + cb && cb(); + }; const label = document.createElement("label"); label.appendChild(checkbox); diff --git a/js/util.js b/js/util.js index f99d46f..0069c7a 100644 --- a/js/util.js +++ b/js/util.js @@ -35,7 +35,7 @@ const guid = (size = 3) => { .toString(16) .substring(1); }; - // returns id of format 'aaaaaaaa'-'aaaa'-'aaaa'-'aaaa'-'aaaaaaaaaaaa' + // returns id of format 'aaaa'-'aaaa'-'aaaa' by default let id = ""; for (var i = 0; i < size - 1; i++) id += s4() + "-"; id += s4();