Spaces:
Sleeping
Sleeping
File size: 4,605 Bytes
1e21006 43a02d9 1e21006 7f0a0f6 8df9f56 f1ef6af f9350de 43a02d9 8df9f56 f1ef6af 1e21006 8df9f56 1e21006 2941c67 1e21006 2941c67 f1ef6af 2941c67 f1ef6af 1e21006 f1ef6af 1e21006 2941c67 1e21006 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
const testerInput = document.getElementById("tester");
const samplerInput = document.getElementById("samplers");
const actionContainer = document.getElementById("action-container");
const resultsSection = document.getElementById("results");
let canvas = document.getElementById("lines-canvas");
let ctx = canvas.getContext("2d");
let generateBtn, loaderDiv;
function resetUI() {
resultsSection.classList.add("hidden");
resultsSection.innerHTML = `
<canvas id="lines-canvas"></canvas>
<div id="result-layout">
<div id="tester-column"></div>
<div id="sampler-column"></div>
</div>
`;
// Re-attach canvas & ctx properly
canvas = document.getElementById("lines-canvas");
ctx = canvas.getContext("2d");
canvas.width = 0;
canvas.height = 0;
// Remove old button & loader if exists
if (loaderDiv) loaderDiv.remove();
if (generateBtn) generateBtn.remove();
}
testerInput.addEventListener("change", handleFileChange);
samplerInput.addEventListener("change", handleFileChange);
function handleFileChange() {
resetUI();
const testerReady = testerInput.files.length === 1;
const samplersReady =
samplerInput.files.length > 0 && samplerInput.files.length <= 5;
if (samplerInput.files.length > 5) {
alert("You can upload a maximum of 5 sampler photos.");
samplerInput.value = "";
return;
}
if (testerReady && samplersReady) {
generateBtn = document.createElement("button");
generateBtn.textContent = "Generate Comparison";
generateBtn.className = "generate-btn";
generateBtn.onclick = sendComparison;
actionContainer.appendChild(generateBtn);
}
}
function showLoader() {
loaderDiv = document.createElement("div");
loaderDiv.className = "loader";
actionContainer.appendChild(loaderDiv);
}
async function sendComparison() {
generateBtn.disabled = true;
showLoader();
const formData = new FormData();
formData.append("tester", testerInput.files[0]);
for (let file of samplerInput.files) formData.append("samplers", file);
try {
const res = await fetch("/compare", { method: "POST", body: formData });
if (!res.ok) throw new Error(await res.text());
const data = await res.json();
renderResults(data);
} catch (err) {
alert("Error: " + err.message);
} finally {
generateBtn.disabled = false;
loaderDiv.remove();
}
}
function getBorderColor(percent) {
if (percent < 30) return "#ef4444"; // red
if (percent <= 50) return "#fb923c"; // orange
if (percent <= 80) return "#22c55e"; // green
return "#a855f7"; // purple
}
function renderResults({ tester, results }) {
resultsSection.classList.remove("hidden");
const testerColumn = document.getElementById("tester-column");
const samplerColumn = document.getElementById("sampler-column");
const testerSquare = createSquare(testerInput.files[0], "#3b82f6");
testerSquare.classList.add("tester-node");
testerColumn.appendChild(testerSquare);
// Append results
results.forEach((r,idx)=>{
const square = createSquare(
samplerInput.files[idx],
getBorderColor(r.similarity)
);
samplerColumn.appendChild(square);
/* Wait for browser calculate layout then draw line */
requestAnimationFrame(()=>drawLineBetween(testerSquare,square,r.similarity));
});
}
function createSquare(file, borderColor) {
const url = URL.createObjectURL(file);
const div = document.createElement("div");
div.className = "square";
div.style.border = `4px solid ${borderColor}`;
const img = document.createElement("img");
img.src = url;
div.appendChild(img);
return div;
}
function drawLineBetween(el1, el2, similarity) {
const rect1 = el1.getBoundingClientRect();
const rect2 = el2.getBoundingClientRect();
const offset = resultsSection.getBoundingClientRect();
// Compute canvas size on first call
if (canvas.width === 0) {
canvas.width = resultsSection.scrollWidth;
canvas.height = resultsSection.getBoundingClientRect().height;
}
const x1 = rect1.right - offset.left;
const y1 = rect1.top + rect1.height / 2 - offset.top;
const x2 = rect2.left - offset.left;
const y2 = rect2.top + rect2.height / 2 - offset.top;
ctx.strokeStyle = getBorderColor(similarity);
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
// Label
const label = document.createElement("div");
label.className = "label";
label.textContent = similarity.toFixed(0) + "%";
label.style.left = (x1 + x2) / 2 + "px";
label.style.top = (y1 + y2) / 2 + "px";
resultsSection.appendChild(label);
} |