From 0b9cf09339f7c41048afdcc16937b3f3f0feb434 Mon Sep 17 00:00:00 2001
From: Chris Beer <cabeer@stanford.edu>
Date: Thu, 28 Feb 2019 15:01:59 -0800
Subject: [PATCH] Extend ManifestCanvas#thumbnail to accept a width, height, or
 both to constrain the image by

---
 __tests__/src/lib/ManifestoCanvas.test.js  | 20 ++++++++++++---
 src/components/ThumbnailNavigation.js      |  2 +-
 src/components/WindowSideBarCanvasPanel.js |  2 +-
 src/config/settings.js                     |  3 ++-
 src/lib/ManifestoCanvas.js                 | 29 +++++++++++++++++++---
 5 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/__tests__/src/lib/ManifestoCanvas.test.js b/__tests__/src/lib/ManifestoCanvas.test.js
index 7a3c8db79..ef43ad1c7 100644
--- a/__tests__/src/lib/ManifestoCanvas.test.js
+++ b/__tests__/src/lib/ManifestoCanvas.test.js
@@ -43,14 +43,28 @@ describe('ManifestoCanvas', () => {
     });
   });
   describe('thumbnail', () => {
-    it('calculates a thumbnail image API request based off of height', () => {
+    it('calculates a thumbnail image API request based off of width, height and aspect ratio', () => {
+      expect(instance.thumbnail(100, 100)).toEqual(
+        'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/,100/0/default.jpg',
+      );
+
+      expect(instance.thumbnail(100, 1000)).toEqual(
+        'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/100,/0/default.jpg',
+      );
+    });
+    it('calculates a thumbnail image API request based off of width', () => {
       expect(instance.thumbnail(100)).toEqual(
-        'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/66,/0/default.jpg',
+        'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/100,/0/default.jpg',
+      );
+    });
+    it('calculates a thumbnail image API request based off of height', () => {
+      expect(instance.thumbnail(null, 100)).toEqual(
+        'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/,100/0/default.jpg',
       );
     });
     it('defaults to using 150 as a height', () => {
       expect(instance.thumbnail()).toEqual(
-        'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/100,/0/default.jpg',
+        'https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/full/,150/0/default.jpg',
       );
     });
 
diff --git a/src/components/ThumbnailNavigation.js b/src/components/ThumbnailNavigation.js
index b79404d53..edd162f34 100644
--- a/src/components/ThumbnailNavigation.js
+++ b/src/components/ThumbnailNavigation.js
@@ -73,7 +73,7 @@ export class ThumbnailNavigation extends Component {
             >
               <CanvasThumbnail
                 onClick={() => setCanvas(window.id, currentGroupings[0].index)}
-                imageUrl={new ManifestoCanvas(canvas).thumbnail(config.thumbnailNavigation.height)}
+                imageUrl={new ManifestoCanvas(canvas).thumbnail(null, config.thumbnailNavigation.height)}
                 height={config.thumbnailNavigation.height}
               />
             </div>
diff --git a/src/components/WindowSideBarCanvasPanel.js b/src/components/WindowSideBarCanvasPanel.js
index 58ff4ee62..cd71348bc 100644
--- a/src/components/WindowSideBarCanvasPanel.js
+++ b/src/components/WindowSideBarCanvasPanel.js
@@ -48,7 +48,7 @@ export class WindowSideBarCanvasPanel extends Component {
                     <CanvasThumbnail
                       className={classNames(classes.clickable)}
                       isValid={isValid}
-                      imageUrl={manifestoCanvas.thumbnail(config.canvasNavigation.height)}
+                      imageUrl={manifestoCanvas.thumbnail(config.canvasNavigation.width, config.canvasNavigation.height)}
                       onClick={onClick}
                       style={{
                         cursor: 'pointer',
diff --git a/src/config/settings.js b/src/config/settings.js
index 24e735932..5cb87c448 100644
--- a/src/config/settings.js
+++ b/src/config/settings.js
@@ -1,6 +1,7 @@
 export default {
   canvasNavigation: {
-    height: 100,
+    height: 50,
+    width: 50,
   },
   theme: { // Sets up a MaterialUI theme. See https://material-ui.com/customization/default-theme/
     palette: {
diff --git a/src/lib/ManifestoCanvas.js b/src/lib/ManifestoCanvas.js
index 7f243436b..e092144d4 100644
--- a/src/lib/ManifestoCanvas.js
+++ b/src/lib/ManifestoCanvas.js
@@ -43,14 +43,37 @@ export default class ManifestoCanvas {
    * Creates a canonical image request for a thumb
    * @param {Number} height
    */
-  thumbnail(height = 150) {
-    const width = Math.floor(height * this.aspectRatio);
+  thumbnail(maxWidth = undefined, maxHeight = undefined) {
+    let width;
+    let height;
 
     if (!this.imageInformationUri) {
       return undefined;
     }
 
-    return this.canonicalImageUri.replace(/\/full\/.*\/0\//, `/full/${width},/0/`);
+    if (maxWidth && maxHeight) {
+      const { aspectRatio } = this;
+      const desiredAspectRatio = maxWidth / maxHeight;
+
+      // size to width
+      if (desiredAspectRatio < aspectRatio) {
+        height = null;
+        width = maxWidth;
+      } else {
+        height = maxHeight;
+        width = null;
+      }
+    } else if (!maxWidth && !maxHeight) {
+      width = null;
+      height = '150';
+    } else {
+      width = maxWidth;
+      height = maxHeight;
+    }
+    // note that, although the IIIF server may support sizeByConfinedWh (e.g. !w,h)
+    // this is a IIIF level 2 feature, so we're instead providing w, or h,-style requests
+    // which are only level 1.
+    return this.canonicalImageUri.replace(/\/full\/.*\/0\//, `/full/${width || ''},${height || ''}/0/`);
   }
 
   /**
-- 
GitLab