diff --git a/src/main/resources/static/css/dark-mode.css b/src/main/resources/static/css/dark-mode.css index 78df6386..13d32b47 100644 --- a/src/main/resources/static/css/dark-mode.css +++ b/src/main/resources/static/css/dark-mode.css @@ -1,25 +1,27 @@ /* Dark Mode Styles */ body { - background-color: #333 !important; - color: #fff !important; + --body-background-color: 51, 51, 51; + --base-font-color: 255, 255, 255; + background-color: rgb(var(--body-background-color)) !important; + color: rgb(var(--base-font-color)) !important; } .dark-card { - background-color: #333 !important; - color: white !important; + background-color: rgb(var(--body-background-color)) !important; + color: rgb(var(--base-font-color)) !important; } .jumbotron { background-color: #222; /* or any other dark color */ - color: #fff !important; /* or any other light color */ + color: rgb(var(--base-font-color)) !important; /* or any other light color */ } .list-group { background-color: #222 !important; - color: fff !important; + color: rgb(var(--base-font-color)) !important; } .list-group-item { background-color: #222 !important; - color: fff !important; + color: rgb(var(--base-font-color)) !important; } #support-section { background-color: #444 !important; @@ -30,5 +32,5 @@ body { --background-color: rgba(255, 255, 255, 0.046) !important; --scroll-bar-color: #4c4c4c !important; --scroll-bar-thumb: #d3d3d3 !important; - --scroll-bar-thumb-hover: #ffffff !important; + --scroll-bar-thumb-hover: rgb(var(--base-font-color)) !important; } \ No newline at end of file diff --git a/src/main/resources/static/css/light-mode.css b/src/main/resources/static/css/light-mode.css new file mode 100644 index 00000000..b696c036 --- /dev/null +++ b/src/main/resources/static/css/light-mode.css @@ -0,0 +1,5 @@ +/* Dark Mode Styles */ +body { + --body-background-color: 255, 255, 255; + --base-font-color: 33, 37, 41; +} \ No newline at end of file diff --git a/src/main/resources/static/css/tab-container.css b/src/main/resources/static/css/tab-container.css index d8bcf5ff..d1f0771b 100644 --- a/src/main/resources/static/css/tab-container.css +++ b/src/main/resources/static/css/tab-container.css @@ -8,24 +8,19 @@ } .tab-container.active { display: block; - border: 1px solid #dee2e6; + border: 1px solid rgba(var(--base-font-color), 0.25); padding: 15px; } -/* -.tab-buttons { - border-bottom: 1px solid #dee2e6; -} -*/ .tab-buttons > button { margin-bottom: -1px; background: 0 0; border: 1px solid transparent; + color: rgb(var(--base-font-color)); border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; } .tab-buttons > button.active { - color: #495057; - background-color: #fff; - border-color: #dee2e6 #dee2e6 #fff; + background-color: rgb(var(--body-background-color)); + border-color: rgba(var(--base-font-color), 0.25) rgba(var(--base-font-color), 0.25) rgb(var(--body-background-color)); } \ No newline at end of file diff --git a/src/main/resources/static/js/draggable-utils.js b/src/main/resources/static/js/draggable-utils.js index 77f35d0b..07437f7b 100644 --- a/src/main/resources/static/js/draggable-utils.js +++ b/src/main/resources/static/js/draggable-utils.js @@ -66,7 +66,7 @@ const DraggableUtils = { createdCanvas.classList.add("draggable-canvas"); const x = 0; - const y = 0; + const y = 20; createdCanvas.style.transform = `translate(${x}px, ${y}px)`; createdCanvas.setAttribute('data-x', x); createdCanvas.setAttribute('data-y', y); diff --git a/src/main/resources/templates/fragments/common.html b/src/main/resources/templates/fragments/common.html index 8b056ade..06ac8895 100644 --- a/src/main/resources/templates/fragments/common.html +++ b/src/main/resources/templates/fragments/common.html @@ -27,6 +27,7 @@ + @@ -46,22 +47,26 @@ function toggleDarkMode() { } lastToggleTime = currentTime; + var lightModeStyles = document.getElementById("light-mode-styles"); var darkModeStyles = document.getElementById("dark-mode-styles"); var rainbowModeStyles = document.getElementById("rainbow-mode-styles"); var darkModeIcon = document.getElementById("dark-mode-icon"); if (toggleCount >= 18) { localStorage.setItem("dark-mode", "rainbow"); + lightModeStyles.disabled = true; darkModeStyles.disabled = true; rainbowModeStyles.disabled = false; darkModeIcon.src = "rainbow.svg"; } else if (localStorage.getItem("dark-mode") == "on") { localStorage.setItem("dark-mode", "off"); + lightModeStyles.disabled = false; darkModeStyles.disabled = true; rainbowModeStyles.disabled = true; darkModeIcon.src = "sun.svg"; } else { localStorage.setItem("dark-mode", "on"); + lightModeStyles.disabled = true; darkModeStyles.disabled = false; rainbowModeStyles.disabled = true; darkModeIcon.src = "moon.svg"; @@ -69,19 +74,23 @@ function toggleDarkMode() { } document.addEventListener("DOMContentLoaded", function () { + var lightModeStyles = document.getElementById("light-mode-styles"); var darkModeStyles = document.getElementById("dark-mode-styles"); var rainbowModeStyles = document.getElementById("rainbow-mode-styles"); var darkModeIcon = document.getElementById("dark-mode-icon"); if (localStorage.getItem("dark-mode") == "on") { + lightModeStyles.disabled = true; darkModeStyles.disabled = false; rainbowModeStyles.disabled = true; darkModeIcon.src = "moon.svg"; } else if (localStorage.getItem("dark-mode") == "off") { + lightModeStyles.disabled = false; darkModeStyles.disabled = true; rainbowModeStyles.disabled = true; darkModeIcon.src = "sun.svg"; } else if (localStorage.getItem("dark-mode") == "rainbow") { + lightModeStyles.disabled = true; darkModeStyles.disabled = true; rainbowModeStyles.disabled = false; darkModeIcon.src = "rainbow.svg"; diff --git a/src/main/resources/templates/multi-tool.html b/src/main/resources/templates/multi-tool.html index 2c6944b0..030b44ba 100644 --- a/src/main/resources/templates/multi-tool.html +++ b/src/main/resources/templates/multi-tool.html @@ -99,7 +99,7 @@ gap: 10px; align-items: start; - background: rgba(13, 110, 253, 0.1); + background-color: rgba(13, 110, 253, 0.1); border: 1px solid rgba(0, 0, 0, .25); backdrop-filter: blur(2px); diff --git a/src/main/resources/templates/sign.html b/src/main/resources/templates/sign.html index 3d0af099..382ce8e2 100644 --- a/src/main/resources/templates/sign.html +++ b/src/main/resources/templates/sign.html @@ -81,9 +81,72 @@ }); function addDraggableFromPad() { if (signaturePad.isEmpty()) return; - const dataURL = signaturePad.toDataURL(); - DraggableUtils.createDraggableCanvasFromUrl(dataURL); + const startTime = Date.now(); + const croppedDataUrl = getCroppedCanvasDataUrl(signaturePadCanvas) + console.log(Date.now() - startTime); + DraggableUtils.createDraggableCanvasFromUrl(croppedDataUrl); } + function getCroppedCanvasDataUrl(canvas) { + // code is from: https://github.com/szimek/signature_pad/issues/49#issuecomment-1104035775 + let originalCtx = canvas.getContext('2d'); + + let originalWidth = canvas.width; + let originalHeight = canvas.height; + let imageData = originalCtx.getImageData(0,0, originalWidth, originalHeight); + + let minX = originalWidth + 1, maxX = -1, minY = originalHeight + 1, maxY = -1, x = 0, y = 0, currentPixelColorValueIndex; + + for (y = 0; y < originalHeight; y++) { + for (x = 0; x < originalWidth; x++) { + currentPixelColorValueIndex = (y * originalWidth + x) * 4; + let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3]; + if (currentPixelAlphaValue > 0) { + if (minX > x) minX = x; + if (maxX < x) maxX = x; + if (minY > y) minY = y; + if (maxY < y) maxY = y; + } + } + } + + let croppedWidth = maxX - minX; + let croppedHeight = maxY - minY; + if (croppedWidth < 0 || croppedHeight < 0) return null; + let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight); + + let croppedCanvas = document.createElement('canvas'), + croppedCtx = croppedCanvas.getContext('2d'); + + croppedCanvas.width = croppedWidth; + croppedCanvas.height = croppedHeight; + croppedCtx.putImageData(cuttedImageData, 0, 0); + + return croppedCanvas.toDataURL(); + } + function resizeCanvas() { + // When zoomed out to less than 100%, for some very strange reason, + // some browsers report devicePixelRatio as less than 1 + // and only part of the canvas is cleared then. + var ratio = Math.max(window.devicePixelRatio || 1, 1); + + // This part causes the canvas to be cleared + signaturePadCanvas.width = signaturePadCanvas.offsetWidth * ratio; + signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio; + signaturePadCanvas.getContext("2d").scale(ratio, ratio); + + // This library does not listen for canvas changes, so after the canvas is automatically + // cleared by the browser, SignaturePad#isEmpty might still return false, even though the + // canvas looks empty, because the internal data of this library wasn't cleared. To make sure + // that the state of this library is consistent with visual state of the canvas, you + // have to clear it manually. + signaturePad.clear(); + } + new IntersectionObserver((entries, observer) => { + if (entries.some(entry => entry.intersectionRatio > 0)) { + resizeCanvas(); + } + }).observe(signaturePadCanvas); + new ResizeObserver(resizeCanvas).observe(signaturePadCanvas); @@ -186,7 +251,7 @@ } .draggable-buttons-box > button { z-index: 10; - background: rgba(13, 110, 253, 0.1); + background-color: rgba(13, 110, 253, 0.1); } .draggable-canvas { border: 1px solid red;