diff --git a/packages/core/src/core/ui/thumbnail/tests/thumbnail-core.test.ts b/packages/core/src/core/ui/thumbnail/tests/thumbnail-core.test.ts index da4a7fb0..c91691bd 100644 --- a/packages/core/src/core/ui/thumbnail/tests/thumbnail-core.test.ts +++ b/packages/core/src/core/ui/thumbnail/tests/thumbnail-core.test.ts @@ -251,6 +251,34 @@ describe('ThumbnailCore', () => { }); }); + it('rounds fractional pixel dimensions to integers', () => { + const core = new ThumbnailCore(); + const thumbnail = createImage({ coords: { x: 512, y: 320 } }); + + // maxWidth 177 / tileWidth 256 = scale 0.69140625 → fractional dimensions + const result = core.resize(thumbnail, 2560, 1600, { + minWidth: 0, + maxWidth: 177, + minHeight: 0, + maxHeight: Infinity, + }); + + expect(result).toEqual({ + scale: 177 / 256, + containerWidth: 177, + containerHeight: Math.round(160 * (177 / 256)), + imageWidth: Math.round(2560 * (177 / 256)), + imageHeight: Math.round(1600 * (177 / 256)), + offsetX: Math.round(512 * (177 / 256)), + offsetY: Math.round(320 * (177 / 256)), + }); + + // Verify all pixel values are integers (no sub-pixel rendering gaps). + for (const key of ['containerWidth', 'containerHeight', 'imageWidth', 'imageHeight', 'offsetX', 'offsetY']) { + expect(Number.isInteger(result![key as keyof typeof result])).toBe(true); + } + }); + it('returns undefined when dimensions are unavailable', () => { const core = new ThumbnailCore(); const thumbnail: ThumbnailImage = { url: 'thumb.jpg', startTime: 0, endTime: 5 }; diff --git a/packages/core/src/core/ui/thumbnail/thumbnail-core.ts b/packages/core/src/core/ui/thumbnail/thumbnail-core.ts index f4a3f704..b5fb75aa 100644 --- a/packages/core/src/core/ui/thumbnail/thumbnail-core.ts +++ b/packages/core/src/core/ui/thumbnail/thumbnail-core.ts @@ -119,12 +119,12 @@ export class ThumbnailCore { return { scale, - containerWidth: tileWidth * scale, - containerHeight: tileHeight * scale, - imageWidth: imgNaturalWidth * scale, - imageHeight: imgNaturalHeight * scale, - offsetX: (thumbnail.coords?.x ?? 0) * scale, - offsetY: (thumbnail.coords?.y ?? 0) * scale, + containerWidth: Math.round(tileWidth * scale), + containerHeight: Math.round(tileHeight * scale), + imageWidth: Math.round(imgNaturalWidth * scale), + imageHeight: Math.round(imgNaturalHeight * scale), + offsetX: Math.round((thumbnail.coords?.x ?? 0) * scale), + offsetY: Math.round((thumbnail.coords?.y ?? 0) * scale), }; }