diff --git a/__tests__/src/components/OpenSeadragonViewer.test.js b/__tests__/src/components/OpenSeadragonViewer.test.js
index 8d42ce59c0547d54456ed7b833a9cbc0500c85cb..dc5637a9637dd92cd5e2e2dc2b1649b33d79ac89 100644
--- a/__tests__/src/components/OpenSeadragonViewer.test.js
+++ b/__tests__/src/components/OpenSeadragonViewer.test.js
@@ -285,6 +285,8 @@ describe('OpenSeadragonViewer', () => {
     it('calls the OSD viewport panTo and zoomTo with the component state and forces a redraw', () => {
       const panTo = jest.fn();
       const zoomTo = jest.fn();
+      const setFlip = jest.fn();
+      const setRotation = jest.fn();
       const forceRedraw = jest.fn();
 
       wrapper.setState({
@@ -293,22 +295,37 @@ describe('OpenSeadragonViewer', () => {
           viewport: {
             centerSpringX: { target: { value: 10 } },
             centerSpringY: { target: { value: 10 } },
+            getFlip: () => false,
+            getRotation: () => (0),
             panTo,
+            setFlip,
+            setRotation,
             zoomSpring: { target: { value: 1 } },
             zoomTo,
           },
         },
       });
 
-      wrapper.setProps({ viewerConfig: { x: 0.5, y: 0.5, zoom: 0.1 } });
-      wrapper.setProps({ viewerConfig: { x: 1, y: 0, zoom: 0.5 } });
+      wrapper.setProps({
+        viewerConfig: {
+          flip: false, rotation: 90, x: 0.5, y: 0.5, zoom: 0.1,
+        },
+      });
+
+      wrapper.setProps({
+        viewerConfig: {
+          flip: true, rotation: 0, x: 1, y: 0, zoom: 0.5,
+        },
+      });
 
       expect(panTo).toHaveBeenCalledWith(
-        { x: 1, y: 0, zoom: 0.5 }, false,
+        expect.objectContaining({ x: 1, y: 0, zoom: 0.5 }), false,
       );
       expect(zoomTo).toHaveBeenCalledWith(
-        0.5, { x: 1, y: 0, zoom: 0.5 }, false,
+        0.5, expect.objectContaining({ x: 1, y: 0, zoom: 0.5 }), false,
       );
+      expect(setRotation).toHaveBeenCalledWith(90);
+      expect(setFlip).toHaveBeenCalledWith(true);
       expect(forceRedraw).not.toHaveBeenCalled();
     });
   });
@@ -320,6 +337,8 @@ describe('OpenSeadragonViewer', () => {
           viewport: {
             centerSpringX: { target: { value: 1 } },
             centerSpringY: { target: { value: 0 } },
+            getFlip: () => false,
+            getRotation: () => 90,
             zoomSpring: { target: { value: 0.5 } },
           },
         },
@@ -327,7 +346,9 @@ describe('OpenSeadragonViewer', () => {
 
       expect(updateViewport).toHaveBeenCalledWith(
         'base',
-        { x: 1, y: 0, zoom: 0.5 },
+        {
+          flip: false, rotation: 90, x: 1, y: 0, zoom: 0.5,
+        },
       );
     });
   });
diff --git a/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js b/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js
index 73ca48ab1fba3ea94a5cc12a2ed777aad4c181d2..23a785b56d3cbaf971b7f3748e6678045a16de64 100644
--- a/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js
+++ b/__tests__/src/lib/OpenSeadragonCanvasOverlay.test.js
@@ -17,12 +17,15 @@ describe('OpenSeadragonCanvasOverlay', () => {
         clientWidth: 200,
       },
       viewport: {
-        getBounds: jest.fn(() => ({
+        getBoundsNoRotate: jest.fn(() => ({
           height: 300,
           width: 200,
           x: 40,
           y: 80,
         })),
+        getCenter: () => ({ x: 0, y: 0 }),
+        getFlip: () => false,
+        getRotation: () => 0,
         getZoom: jest.fn(() => (0.75)),
       },
       world: {
@@ -89,7 +92,7 @@ describe('OpenSeadragonCanvasOverlay', () => {
           clientWidth: 200,
         },
         viewport: {
-          getBounds: jest.fn(() => (new OpenSeadragon.Rect(0, 0, 200, 200))),
+          getBoundsNoRotate: jest.fn(() => (new OpenSeadragon.Rect(0, 0, 200, 200))),
         },
         world: {
           getItemAt: jest.fn(),
diff --git a/src/components/OpenSeadragonViewer.js b/src/components/OpenSeadragonViewer.js
index f1fcd154b5ac517a6b3133f8c98ee43baff3eba0..7dbb00736046ea794b828b30aa52272b3fbad94a 100644
--- a/src/components/OpenSeadragonViewer.js
+++ b/src/components/OpenSeadragonViewer.js
@@ -82,6 +82,8 @@ export class OpenSeadragonViewer extends Component {
       if (viewerConfig) {
         viewer.viewport.panTo(viewerConfig, true);
         viewer.viewport.zoomTo(viewerConfig.zoom, viewerConfig, true);
+        viewerConfig.degrees !== undefined && viewer.viewport.setRotation(viewerConfig.degrees);
+        viewerConfig.flip !== undefined && viewer.viewport.setFlip(viewerConfig.flip);
       }
 
       this.addAllImageSources(!(viewerConfig));
@@ -102,11 +104,19 @@ export class OpenSeadragonViewer extends Component {
 
       if (viewerConfig.x !== viewport.centerSpringX.target.value
         || viewerConfig.y !== viewport.centerSpringY.target.value) {
-        viewer.viewport.panTo(viewerConfig, false);
+        viewport.panTo(viewerConfig, false);
       }
 
       if (viewerConfig.zoom !== viewport.zoomSpring.target.value) {
-        viewer.viewport.zoomTo(viewerConfig.zoom, viewerConfig, false);
+        viewport.zoomTo(viewerConfig.zoom, viewerConfig, false);
+      }
+
+      if (viewerConfig.rotation !== viewport.getRotation()) {
+        viewport.setRotation(viewerConfig.rotation);
+      }
+
+      if (viewerConfig.flip !== viewport.getFlip()) {
+        viewport.setFlip(viewerConfig.flip);
       }
     }
   }
@@ -129,6 +139,8 @@ export class OpenSeadragonViewer extends Component {
     const { viewport } = event.eventSource;
 
     updateViewport(windowId, {
+      flip: viewport.getFlip(),
+      rotation: viewport.getRotation(),
       x: Math.round(viewport.centerSpringX.target.value),
       y: Math.round(viewport.centerSpringY.target.value),
       zoom: viewport.zoomSpring.target.value,
diff --git a/src/lib/OpenSeadragonCanvasOverlay.js b/src/lib/OpenSeadragonCanvasOverlay.js
index 4e23466cda85e50e81d8aecc2e2a0ac00be5e6af..d10bd5014b0da1dc612f778caa049449cda5b8da 100644
--- a/src/lib/OpenSeadragonCanvasOverlay.js
+++ b/src/lib/OpenSeadragonCanvasOverlay.js
@@ -58,7 +58,7 @@ export default class OpenSeadragonCanvasOverlay {
     }
 
     this.viewportOrigin = new OpenSeadragon.Point(0, 0);
-    const boundsRect = this.viewer.viewport.getBounds(true);
+    const boundsRect = this.viewer.viewport.getBoundsNoRotate(true);
     this.viewportOrigin.x = boundsRect.x;
     this.viewportOrigin.y = boundsRect.y * this.imgAspectRatio;
 
@@ -93,6 +93,20 @@ export default class OpenSeadragonCanvasOverlay {
     this.context2d.translate(x, y);
     this.context2d.scale(zoom, zoom);
 
+    const center = this.viewer.viewport.getCenter();
+
+    const flip = this.viewer.viewport.getFlip();
+    if (flip) {
+      this.context2d.translate(center.x * 2, 0);
+      this.context2d.scale(-1, 1);
+    }
+
+    const rotation = this.viewer.viewport.getRotation();
+    if (rotation !== 0) {
+      this.context2d.translate(center.x, center.y);
+      this.context2d.rotate(rotation * Math.PI / 180);
+      this.context2d.translate(-1 * center.x, -1 * center.y);
+    }
     update();
 
     this.context2d.setTransform(1, 0, 0, 1, 0, 0);