diff options
| author | Fuwn <[email protected]> | 2025-12-02 00:25:35 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-12-02 00:25:35 -0800 |
| commit | 7eeefae01354be643b57ad313f34597457e37376 (patch) | |
| tree | ec72a0231938de92b6b63acfda536da9c1b164de | |
| parent | feat(index.html): Update feature casing (diff) | |
| download | rysk-7eeefae01354be643b57ad313f34597457e37376.tar.xz rysk-7eeefae01354be643b57ad313f34597457e37376.zip | |
feat(index.html): Clean up canvas and analysis loading visuals
| -rw-r--r-- | index.html | 43 | ||||
| -rw-r--r-- | js/index.js | 34 |
2 files changed, 69 insertions, 8 deletions
@@ -156,6 +156,12 @@ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); } + .input-field input:disabled { + opacity: 0.5; + cursor: not-allowed; + background: var(--surface); + } + .input-field input:hover { border-color: rgba(255, 255, 255, 0.12); } @@ -376,6 +382,7 @@ justify-content: center; margin-top: var(--spacing-xl); padding: 0 var(--spacing-md); + position: relative; } #canvas { @@ -385,6 +392,34 @@ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); background: var(--surface-elevated); display: block; + transition: opacity 0.3s ease; + } + + .canvas-loading-overlay { + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); + width: 100%; + max-width: 600px; + min-height: 400px; + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius); + display: none; + flex-direction: column; + align-items: center; + justify-content: center; + gap: var(--spacing-lg); + z-index: 10; + } + + .canvas-container.loading .canvas-loading-overlay { + display: flex; + } + + .canvas-container.loading #canvas { + opacity: 0; } /* Sections */ @@ -522,7 +557,7 @@ <div class="app"> <div id="loading" class="loading-container" style="display: none"> <div class="spinner"> - <span class="visually-hidden">Loading...</span> + <span class="visually-hidden">Loading ...</span> </div> </div> @@ -776,7 +811,11 @@ <div id="analyzing-status" class="loading-text"></div> </div> - <div class="canvas-container" id="render"> + <div class="canvas-container d-none" id="render"> + <div class="canvas-loading-overlay" id="canvas-loading"> + <div class="spinner"></div> + <div class="loading-text">Analysing image ...</div> + </div> <canvas id="canvas"></canvas> </div> </main> diff --git a/js/index.js b/js/index.js index f1d4210..13c8520 100644 --- a/js/index.js +++ b/js/index.js @@ -152,12 +152,23 @@ resultCell.innerHTML = ` } async function main() { + const imageInputFile = document.getElementById("image-file"); + const imageInputUrl = document.getElementById("image-url"); + const renderContainer = document.getElementById("render"); + + // Disable inputs until database loads + imageInputFile.disabled = true; + imageInputUrl.disabled = true; + const _model = await faceLandmarksDetection.load(faceLandmarksDetection.SupportedPackages.mediapipeFacemesh, { maxFaces: 1 }); window.database = await setupDatabase(); - const imageInputFile = document.getElementById("image-file"); - const imageInputUrl = document.getElementById("image-url"); + + // Enable inputs after database loads + imageInputFile.disabled = false; + imageInputUrl.disabled = false; + const introductionElement = document.getElementById("introduction"); const analyzingElement = document.getElementById("analyzing"); const canvas = document.getElementById("canvas"); @@ -206,6 +217,10 @@ if (gradingToggle) { async function onChange(url) { setStatus("Analysing"); + + // Show canvas container with loading overlay + renderContainer.classList.remove("d-none"); + renderContainer.classList.add("loading"); let analysis = await analyze(canvas, ctx, url); @@ -336,6 +351,9 @@ if (gradingToggle) { } analyzingElement.classList.add("d-none"); + + // Remove loading overlay and show canvas + renderContainer.classList.remove("loading"); calculate(); render(); @@ -344,10 +362,14 @@ if (gradingToggle) { function clearData() { canvas.width = 0; canvas.height = 0; - for (let i of Object.values(data)) { - i.render.innerHTML = ""; - i.ideal.innerHTML = ""; - i.assessment.innerHTML = ""; + renderContainer.classList.add("d-none"); + renderContainer.classList.remove("loading"); + if (data) { + for (let i of Object.values(data)) { + i.render.innerHTML = ""; + i.ideal.innerHTML = ""; + i.assessment.innerHTML = ""; + } } } |