Skip to content

Commit 70bf913

Browse files
authored
Merge pull request #180 from oss-slu/178-captions
Bone Image captions showing in correct view of bone display feature implemented and approved.
2 parents e6e2063 + 2be56b4 commit 70bf913

7 files changed

Lines changed: 476 additions & 246 deletions

File tree

.DS_Store

-2 KB
Binary file not shown.

templates/boneset.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ <h2 style="color: #003366; text-align: center; margin-bottom: 25px; border-botto
247247
<script type="module" src="js/main.js"></script>
248248
<script type="module" src="js/imageDisplay.js"></script>
249249
<script type="module" src="js/annotationOverlay.js"></script>
250+
<script type="module" src="js/imageCaptions.js"></script>
250251

251252
<!-- Simple Escape Key Handler -->
252253
<script>
@@ -268,4 +269,4 @@ <h2 style="color: #003366; text-align: center; margin-bottom: 25px; border-botto
268269
</script>
269270
</body>
270271

271-
</html>
272+
</html>

templates/js/coloredRegionsOverlay.js

Lines changed: 179 additions & 179 deletions
Large diffs are not rendered by default.

templates/js/imageCaptions.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// js/imageCaptions.js
2+
// Image captions for bone images, extracted from PowerPoint slides
3+
4+
export const imageCaptions = {
5+
// Bony Pelvis (main boneset)
6+
"bony_pelvis": {
7+
image1: "Right Pelvis (lateral aspect)",
8+
image2: "Right Pelvis(medial aspect)"
9+
},
10+
11+
// Ilium and its subbones
12+
"ilium": {
13+
image1: "Right Pelvis (lateral aspect)",
14+
image2: "Right Pelvis(medial aspect)"
15+
},
16+
"iliac_crest": {
17+
image1: "Right Pelvis (lateral aspect)",
18+
image2: "Right Pelvis(medial aspect)"
19+
},
20+
"anterior_iliac_spines": {
21+
image1: "Right Pelvis (lateral aspect)",
22+
image2: "Right Pelvis(medial aspect)"
23+
},
24+
"posterior_iliac_spines": {
25+
image1: "Right Pelvis (lateral aspect)",
26+
image2: "Right Pelvis(medial aspect)"
27+
},
28+
"auricular_surface": {
29+
image1: "Right Pelvis(medial aspect)",
30+
image2: null
31+
},
32+
33+
// Ischium and its subbones
34+
"ischium": {
35+
image1: "Right Pelvis (lateral aspect)",
36+
image2: "Right Pelvis(medial aspect)"
37+
},
38+
"ramus": {
39+
image1: "Right Pelvis (lateral aspect)",
40+
image2: "Right Pelvis(medial aspect)"
41+
},
42+
"ischial_tuberosity": {
43+
image1: "Right Pelvis (lateral aspect)",
44+
image2: "Right Pelvis(medial aspect)"
45+
},
46+
"ischial_spine": {
47+
image1: "Right Pelvis (lateral aspect)",
48+
image2: "Right Pelvis(medial aspect)"
49+
},
50+
"sciatic_notches": {
51+
image1: "Right Pelvis (lateral aspect)",
52+
image2: "Right Pelvis(medial aspect)"
53+
},
54+
55+
// Pubis and its subbones
56+
"pubis": {
57+
image1: "Right Pelvis (lateral aspect)",
58+
image2: "Right Pelvis(medial aspect)"
59+
},
60+
"pubic_rami": {
61+
image1: "Right Pelvis (lateral aspect)",
62+
image2: "Right Pelvis(medial aspect)"
63+
},
64+
"pectineal_line": {
65+
image1: "Right Pelvis(medial aspect)",
66+
image2: null
67+
},
68+
"symphyseal_surface": {
69+
image1: "Right Pelvis(medial aspect)",
70+
image2: null
71+
},
72+
"pubic_tubercle": {
73+
image1: "Right Pelvis (lateral aspect)",
74+
image2: null
75+
}
76+
};

templates/js/imageDisplay.js

Lines changed: 84 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// Rendering helpers for the image area (no dropdown wiring).
33

44
import { clearAnnotations, loadAndDrawAnnotations } from "./annotationOverlay.js";
5-
import { displayColoredRegions, clearAllColoredRegions } from './coloredRegionsOverlay.js';
5+
import { displayColoredRegions, clearAllColoredRegions } from "./coloredRegionsOverlay.js";
6+
import { imageCaptions } from "./imageCaptions.js";
67

78
// Track the current boneId for colored regions
89
let currentBoneId = null;
@@ -14,6 +15,14 @@ function getImageContainer() {
1415
);
1516
}
1617

18+
/** Helper function to get captions for a boneId */
19+
function getCaptionsForBone(boneId) {
20+
if (!boneId || !imageCaptions[boneId]) {
21+
return { image1: null, image2: null };
22+
}
23+
return imageCaptions[boneId];
24+
}
25+
1726
/** ---- Empty-state / clearing ------------------------------------------- */
1827
export function showPlaceholder() {
1928
const c = getImageContainer();
@@ -28,6 +37,12 @@ export function showPlaceholder() {
2837
clearAllColoredRegions();
2938
currentBoneId = null;
3039

40+
// Remove caption container if it exists
41+
const captionContainer = document.getElementById("caption-container");
42+
if (captionContainer) {
43+
captionContainer.remove();
44+
}
45+
3146
// Remove black background class when showing placeholder
3247
const imagesContent = document.querySelector(".images-content");
3348
if (imagesContent) imagesContent.classList.remove("has-images");
@@ -40,6 +55,13 @@ export function clearImages() {
4055
clearAnnotations(c);
4156
clearAllColoredRegions();
4257
}
58+
59+
// Remove caption container if it exists
60+
const captionContainer = document.getElementById("caption-container");
61+
if (captionContainer) {
62+
captionContainer.remove();
63+
}
64+
4365
currentBoneId = null;
4466
currentIsBonesetSelection = false; // Reset the flag
4567

@@ -92,24 +114,40 @@ export function displayBoneImages(images, options = {}) {
92114

93115
//** ---- Single image ------------------------------------------------------ */
94116
function displaySingleImage(image, container, options = {}) {
95-
// 1. CRITICAL FIX: Add the 'single-image' class to the main container.
96-
// This CSS class is required for the styles to correctly size the single image layout.
117+
// Get captions for this bone
118+
const captions = getCaptionsForBone(currentBoneId);
119+
97120
container.className = "single-image";
98121

99-
// 2. Simplification: Use innerHTML to directly create the necessary structure
100-
// (.single-image-wrapper > img), which better aligns with your CSS.
101122
container.innerHTML = `
102123
<div class="single-image-wrapper">
103-
<img
104-
class="bone-image"
105-
src="${image.url || image.src || ""}"
106-
alt="${image.alt || image.filename || "Bone image"}"
107-
>
124+
<div class="image-wrapper">
125+
<img
126+
class="bone-image"
127+
src="${image.url || image.src || ""}"
128+
alt="${image.alt || image.filename || "Bone image"}"
129+
>
130+
</div>
108131
</div>
109132
`;
110133

111-
// 3. Get reference to the image element for colored regions and event handlers
112-
const img = container.querySelector('img');
134+
// Create caption container OUTSIDE the image container if caption exists
135+
if (captions.image1) {
136+
const captionContainer = document.createElement("div");
137+
captionContainer.id = "caption-container";
138+
captionContainer.className = "single-image";
139+
140+
const caption = document.createElement("div");
141+
caption.className = "caption-box image-caption";
142+
caption.textContent = captions.image1;
143+
captionContainer.appendChild(caption);
144+
145+
// Insert caption container after the image container
146+
container.parentElement.insertBefore(captionContainer, container.nextSibling);
147+
}
148+
149+
// Get reference to the image element for colored regions and event handlers
150+
const img = container.querySelector("img");
113151
if (img) {
114152
const loadColoredRegions = () => {
115153
img.classList.add("loaded");
@@ -137,7 +175,7 @@ function displaySingleImage(image, container, options = {}) {
137175
// Check if already loaded (cached) - use setTimeout to let browser process
138176
setTimeout(() => {
139177
if (img.complete && img.naturalHeight !== 0) {
140-
console.log(`[ImageDisplay] Single image was cached, calling loadColoredRegions immediately`);
178+
console.log("[ImageDisplay] Single image was cached, calling loadColoredRegions immediately");
141179
loadColoredRegions();
142180
}
143181
}, 0);
@@ -160,13 +198,20 @@ function applyRotation(imgEl, { rot_deg = 0, flipH = false } = {}) {
160198
}
161199

162200
function displayTwoImages(images, container, options = {}) {
201+
// Get captions for this bone
202+
const captions = getCaptionsForBone(currentBoneId);
203+
163204
// Add the two-images class to the container for CSS styling
164205
container.className = "two-images";
165206

207+
// Create images first
166208
images.slice(0, 2).forEach((image, index) => {
167209
const imgItem = document.createElement("div");
168210
imgItem.className = "image-item";
169211

212+
const imgWrapper = document.createElement("div");
213+
imgWrapper.className = "image-wrapper";
214+
170215
const img = document.createElement("img");
171216
img.alt = image.alt || image.filename || "Bone image";
172217

@@ -191,21 +236,44 @@ function displayTwoImages(images, container, options = {}) {
191236
imgItem.textContent = "Failed to load image.";
192237
});
193238

194-
imgItem.appendChild(img);
239+
imgWrapper.appendChild(img);
240+
imgItem.appendChild(imgWrapper);
195241
container.appendChild(imgItem);
196242

197243
// Set src LAST - this triggers the load
198244
img.src = image.url || image.src || "";
199245

200246
// Check if image is already loaded from cache after setting src
201-
// Use setTimeout to allow the browser to process the src assignment first
202247
setTimeout(() => {
203248
if (img.complete && img.naturalWidth > 0) {
204249
console.log(`[ImageDisplay] Image ${index} was already cached, manually triggering load handler`);
205250
loadColoredRegions();
206251
}
207252
}, 10);
208253
});
254+
255+
// Create caption container AFTER images, OUTSIDE the grid
256+
if (captions.image1 || captions.image2) {
257+
const captionContainer = document.createElement("div");
258+
captionContainer.id = "caption-container";
259+
260+
if (captions.image1) {
261+
const caption1 = document.createElement("div");
262+
caption1.className = "caption-box image-caption";
263+
caption1.textContent = captions.image1;
264+
captionContainer.appendChild(caption1);
265+
}
266+
267+
if (captions.image2) {
268+
const caption2 = document.createElement("div");
269+
caption2.className = "caption-box image-caption";
270+
caption2.textContent = captions.image2;
271+
captionContainer.appendChild(caption2);
272+
}
273+
274+
// Insert caption container after the image container
275+
container.parentElement.insertBefore(captionContainer, container.nextSibling);
276+
}
209277
}
210278

211279
/** ---- 3+ images grid ---------------------------------------------------- */
@@ -230,4 +298,4 @@ function displayMultipleImages(images, container) {
230298
});
231299

232300
container.appendChild(wrapper);
233-
}
301+
}

templates/js/quiz.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class QuizManager {
161161
}
162162

163163
/**
164-
* Get image URL for an item
164+
* Get image URL for an item....
165165
*/
166166
getImageUrl(itemId) {
167167
// Use the API endpoint that serves bone images

0 commit comments

Comments
 (0)