22// Rendering helpers for the image area (no dropdown wiring).
33
44import { 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
89let 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 ------------------------------------------- */
1827export 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
@@ -49,7 +71,7 @@ export function clearImages() {
4971}
5072
5173/** ---- Public entry: render images array --------------------------------
52- * Optionally pass { annotationsUrl: ' templates/data/annotations/xyz.json' , boneId: ' bone_name' }
74+ * Optionally pass { annotationsUrl: " templates/data/annotations/xyz.json" , boneId: " bone_name" }
5375 */
5476export function displayBoneImages ( images , options = { } ) {
5577 const container = getImageContainer ( ) ;
@@ -92,24 +114,39 @@ export function displayBoneImages(images, options = {}) {
92114
93115//** ---- Single image ------------------------------------------------------ */
94116function displaySingleImage ( image , container , options = { } ) {
95- // 1. CRITICAL FIX: Add the ' single-image' class to the main container.
117+ // 1. CRITICAL FIX: Add the " single-image" class to the main container.
96118 // This CSS class is required for the styles to correctly size the single image layout.
97119 container . className = "single-image" ;
98120
99- // 2. Simplification: Use innerHTML to directly create the necessary structure
100- // (.single-image-wrapper > img), which better aligns with your CSS.
101121 container . innerHTML = `
102122 <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- >
123+ <div class="image-wrapper">
124+ <img
125+ class="bone-image"
126+ src="${ image . url || image . src || "" } "
127+ alt="${ image . alt || image . filename || "Bone image" } "
128+ >
129+ </div>
108130 </div>
109131 ` ;
110132
133+ // Create caption container OUTSIDE the image container if caption exists
134+ if ( imageCaptions . image1 ) {
135+ const captionContainer = document . createElement ( "div" ) ;
136+ captionContainer . id = "caption-container" ;
137+ captionContainer . className = "single-image" ;
138+
139+ const caption = document . createElement ( "div" ) ;
140+ caption . className = "caption-box image-caption" ;
141+ caption . textContent = imageCaptions . image1 ;
142+ captionContainer . appendChild ( caption ) ;
143+
144+ // Insert caption container after the image container
145+ container . parentElement . insertBefore ( captionContainer , container . nextSibling ) ;
146+ }
147+
111148 // 3. Get reference to the image element for colored regions and event handlers
112- const img = container . querySelector ( ' img' ) ;
149+ const img = container . querySelector ( " img" ) ;
113150 if ( img ) {
114151 const loadColoredRegions = ( ) => {
115152 img . classList . add ( "loaded" ) ;
@@ -137,7 +174,7 @@ function displaySingleImage(image, container, options = {}) {
137174 // Check if already loaded (cached) - use setTimeout to let browser process
138175 setTimeout ( ( ) => {
139176 if ( img . complete && img . naturalHeight !== 0 ) {
140- console . log ( ` [ImageDisplay] Single image was cached, calling loadColoredRegions immediately` ) ;
177+ console . log ( " [ImageDisplay] Single image was cached, calling loadColoredRegions immediately" ) ;
141178 loadColoredRegions ( ) ;
142179 }
143180 } , 0 ) ;
@@ -160,13 +197,20 @@ function applyRotation(imgEl, { rot_deg = 0, flipH = false } = {}) {
160197}
161198
162199function displayTwoImages ( images , container , options = { } ) {
200+ // Get captions for this bone
201+ const captions = getCaptionsForBone ( currentBoneId ) ;
202+
163203 // Add the two-images class to the container for CSS styling
164204 container . className = "two-images" ;
165205
206+ // Create images first
166207 images . slice ( 0 , 2 ) . forEach ( ( image , index ) => {
167208 const imgItem = document . createElement ( "div" ) ;
168209 imgItem . className = "image-item" ;
169210
211+ const imgWrapper = document . createElement ( "div" ) ;
212+ imgWrapper . className = "image-wrapper" ;
213+
170214 const img = document . createElement ( "img" ) ;
171215 img . alt = image . alt || image . filename || "Bone image" ;
172216
@@ -191,21 +235,44 @@ function displayTwoImages(images, container, options = {}) {
191235 imgItem . textContent = "Failed to load image." ;
192236 } ) ;
193237
194- imgItem . appendChild ( img ) ;
238+ imgWrapper . appendChild ( img ) ;
239+ imgItem . appendChild ( imgWrapper ) ;
195240 container . appendChild ( imgItem ) ;
196241
197242 // Set src LAST - this triggers the load
198243 img . src = image . url || image . src || "" ;
199244
200245 // Check if image is already loaded from cache after setting src
201- // Use setTimeout to allow the browser to process the src assignment first
202246 setTimeout ( ( ) => {
203247 if ( img . complete && img . naturalWidth > 0 ) {
204248 console . log ( `[ImageDisplay] Image ${ index } was already cached, manually triggering load handler` ) ;
205249 loadColoredRegions ( ) ;
206250 }
207251 } , 10 ) ;
208252 } ) ;
253+
254+ // Create caption container AFTER images, OUTSIDE the grid
255+ if ( captions . image1 || captions . image2 ) {
256+ const captionContainer = document . createElement ( "div" ) ;
257+ captionContainer . id = "caption-container" ;
258+
259+ if ( captions . image1 ) {
260+ const caption1 = document . createElement ( "div" ) ;
261+ caption1 . className = "caption-box image-caption" ;
262+ caption1 . textContent = captions . image1 ;
263+ captionContainer . appendChild ( caption1 ) ;
264+ }
265+
266+ if ( captions . image2 ) {
267+ const caption2 = document . createElement ( "div" ) ;
268+ caption2 . className = "caption-box image-caption" ;
269+ caption2 . textContent = captions . image2 ;
270+ captionContainer . appendChild ( caption2 ) ;
271+ }
272+
273+ // Insert caption container after the image container
274+ container . parentElement . insertBefore ( captionContainer , container . nextSibling ) ;
275+ }
209276}
210277
211278/** ---- 3+ images grid ---------------------------------------------------- */
@@ -230,4 +297,4 @@ function displayMultipleImages(images, container) {
230297 } ) ;
231298
232299 container . appendChild ( wrapper ) ;
233- }
300+ }
0 commit comments