LiamKhoaLe commited on
Commit
f1ef6af
·
1 Parent(s): 8df9f56
Files changed (2) hide show
  1. static/script.js +13 -10
  2. static/styles.css +46 -70
static/script.js CHANGED
@@ -17,13 +17,11 @@ function resetUI() {
17
  </div>
18
  `;
19
 
20
- // Update canvas & ctx properly
21
- const newCanvas = document.getElementById("lines-canvas");
22
- canvas.width = newCanvas.width = 0;
23
- canvas.height = newCanvas.height = 0;
24
- ctx.clearRect?.(0, 0, canvas.width, canvas.height);
25
 
26
- // 🧼 Remove old button & loader if exists
27
  if (loaderDiv) loaderDiv.remove();
28
  if (generateBtn) generateBtn.remove();
29
  }
@@ -96,12 +94,17 @@ function renderResults({ tester, results }) {
96
  const testerSquare = createSquare(testerInput.files[0], "#3b82f6");
97
  testerSquare.classList.add("tester-node");
98
  testerColumn.appendChild(testerSquare);
99
-
100
- results.forEach((r, idx) => {
101
- const square = createSquare(samplerInput.files[idx], getBorderColor(r.similarity));
 
 
 
102
  samplerColumn.appendChild(square);
103
- drawLineBetween(testerSquare, square, r.similarity);
 
104
  });
 
105
  }
106
 
107
 
 
17
  </div>
18
  `;
19
 
20
+ // Re-attach canvas & ctx properly
21
+ canvas = document.getElementById("lines-canvas");
22
+ ctx = canvas.getContext("2d");
 
 
23
 
24
+ // Remove old button & loader if exists
25
  if (loaderDiv) loaderDiv.remove();
26
  if (generateBtn) generateBtn.remove();
27
  }
 
94
  const testerSquare = createSquare(testerInput.files[0], "#3b82f6");
95
  testerSquare.classList.add("tester-node");
96
  testerColumn.appendChild(testerSquare);
97
+ // Append results
98
+ results.forEach((r,idx)=>{
99
+ const square = createSquare(
100
+ samplerInput.files[idx],
101
+ getBorderColor(r.similarity)
102
+ );
103
  samplerColumn.appendChild(square);
104
+ /* Wait for browser calculate layout then draw line */
105
+ requestAnimationFrame(()=>drawLineBetween(testerSquare,square,r.similarity));
106
  });
107
+
108
  }
109
 
110
 
static/styles.css CHANGED
@@ -90,78 +90,54 @@
90
  overflow-x: auto;
91
  }
92
 
93
- #result-layout {
94
- display: flex;
95
- justify-content: center;
96
- align-items: center;
97
- position: relative;
98
- width: 100%;
99
- padding: 2rem 0;
100
- gap: 3rem;
101
- flex-wrap: wrap;
102
- }
103
-
104
- #tester-column {
105
- display: flex;
106
- justify-content: center;
107
- align-items: center;
108
- }
109
- .tester-node {
110
- box-shadow: 0 0 10px rgba(59,130,246,0.5);
111
- }
112
-
113
- #sampler-column {
114
- display: flex;
115
- flex-direction: column;
116
- gap: 2rem;
117
- align-items: center;
118
- }
119
-
120
- .square {
121
- width: 120px;
122
- height: 120px;
123
- border-radius: 0.5rem;
124
- overflow: hidden;
125
- position: relative;
126
- flex-shrink: 0;
127
  }
128
- .square img {
129
- width: 100%;
130
- height: 100%;
131
- object-fit: cover;
 
 
132
  }
133
-
134
- #lines-canvas {
135
- position: absolute;
136
- top: 0;
137
- left: 0;
138
- pointer-events: none;
 
139
  }
140
-
141
- .label {
142
- position: absolute;
143
- background: rgba(0, 0, 0, 0.7);
144
- color: #fff;
145
- padding: 2px 6px;
146
- border-radius: 4px;
147
- font-size: 0.8rem;
148
- transform: translate(-50%, -50%);
 
 
 
 
 
 
 
 
 
 
149
  }
150
 
151
- @media (max-width: 600px) {
152
- #result-layout {
153
- flex-direction: column;
154
- gap: 2rem;
155
- }
156
-
157
- #sampler-column {
158
- flex-direction: row;
159
- flex-wrap: wrap;
160
- justify-content: center;
161
- }
162
-
163
- .square {
164
- width: 80px;
165
- height: 80px;
166
- }
167
- }
 
90
  overflow-x: auto;
91
  }
92
 
93
+ /* ─── RESULT LAYOUT ───────────────────────────────── */
94
+ #result-layout{
95
+ display:flex;
96
+ justify-content:center;
97
+ align-items:center;
98
+ position:relative;
99
+ width:100%;
100
+ padding:2rem 0;
101
+ gap:clamp(3rem,8vw,6rem); /* ⬅︎ lớn hơn ⇒ label + line không bị chạm */
102
+ overflow-x:auto; /* nếu màn nhỏ sẽ scroll ngang */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
+
105
+ /* Tester đứng giữa cột trái */
106
+ #tester-column{
107
+ display:flex;
108
+ justify-content:center;
109
+ align-items:center;
110
  }
111
+
112
+ /* Sampler xếp cột phải */
113
+ #sampler-column{
114
+ display:flex;
115
+ flex-direction:column;
116
+ gap:2.5rem; /* giãn từng ảnh */
117
+ align-items:center;
118
  }
119
+
120
+ /* Ảnh vuông */
121
+ .square{
122
+ width:120px;
123
+ height:120px;
124
+ border-radius:0.5rem;
125
+ overflow:hidden;
126
+ flex-shrink:0;
127
+ }
128
+ .square img{width:100%;height:100%;object-fit:cover}
129
+
130
+ /* Canvas + nhãn */
131
+ #lines-canvas{position:absolute;top:0;left:0;pointer-events:none;z-index:0}
132
+ .label{position:absolute;transform:translate(-50%,-50%);z-index:1}
133
+
134
+ /* ─── MOBILE ≤600 px: giữ hai cột nhưng thu nhỏ ảnh ─── */
135
+ @media (max-width:600px){
136
+ #result-layout{gap:2rem} /* hẹp lại */
137
+ .square{width:72px;height:72px;} /* nhỏ hơn */
138
  }
139
 
140
+ .tester-node {
141
+ box-shadow: 0 0 10px rgba(59,130,246,0.5);
142
+ }
143
+