diff --git a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx
index c9b4075afe1ab9f2d649922121ab27d555741272..c97619fe19c3137b0554da1047b36a7d0b536fbc 100644
--- a/bigbluebutton-html5/imports/ui/components/presentation/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/presentation/component.jsx
@@ -43,15 +43,6 @@ export default class PresentationArea extends Component {
     });
   }
 
-  componentDidUpdate() {
-    // const {
-    //   currentSlide,
-    // } = this.props;
-    // const viewW = (currentSlide.calculatedData.viewBoxWidth / currentSlide.calculatedData.width) * 100;
-    // const percentage = Math.ceil((100 / viewW) * 100);
-    // this.zoomChanger(percentage);
-    // console.error(percentage);
-  }
   // returns a ref to the svg element, which is required by a WhiteboardOverlay
   // to transform screen coordinates to svg coordinate system
   getSvgRef() {
@@ -83,6 +74,7 @@ export default class PresentationArea extends Component {
   getInitialPresentationSizes() {
     // determining the presentationWidth and presentationHeight (available space for the svg)
     // on the initial load
+    
     const presentationSizes = this.getPresentationSizesAvailable();
     if (Object.keys(presentationSizes).length > 0) {
       // setting the state of the available space for the svg
@@ -96,6 +88,7 @@ export default class PresentationArea extends Component {
   }
 
   handleResize() {
+    
     const presentationSizes = this.getPresentationSizesAvailable();
     if (Object.keys(presentationSizes).length > 0) {
       // updating the size of the space available for the slide
@@ -254,15 +247,12 @@ export default class PresentationArea extends Component {
       <PresentationOverlayContainer
         podId={this.props.podId}
         currentSlideNum={this.props.currentSlide.num}
-        presentationId={this.props.currentSlide.presentationId}
         slide={slideObj}
         whiteboardId={slideObj.id}
         slideWidth={width}
         slideHeight={height}
         viewBoxWidth={viewBoxWidth}
         viewBoxHeight={viewBoxHeight}
-        x={x}
-        y={y}
         zoom={this.state.zoom}
         zoomChanger={this.zoomChanger}
         adjustedSizes={adjustedSizes}
diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx
index d39bf2e4afe51a367bddbcdb1de22d197cdd27bf..27686c0c0b24fd4c0421955eb9f787dff4673011 100755
--- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-overlay/component.jsx
@@ -1,9 +1,9 @@
 import React, { Component } from 'react';
 import PropTypes from 'prop-types';
-import SlideViewModel from '/imports/utils/slideViewModel';
+import SlideCalcUtil from '/imports/utils/slideCalcUtils';
 
 const CURSOR_INTERVAL = 16;
-const MYSTERY_NUM = 5;
+const MYSTERY_NUM = 2;
 const HUNDRED_PERCENT = 100;
 const MAX_PERCENT = 400;
 
@@ -11,8 +11,6 @@ export default class PresentationOverlay extends Component {
   constructor(props) {
     super(props);
 
-    this.SlideZoomData = new SlideViewModel(props.adjustedSizes.width, props.adjustedSizes.height, props.slideHeight, props.slideWidth);
-
     // last sent coordinates
     this.lastSentClientX = 0;
     this.lastSentClientY = 0;
@@ -24,7 +22,7 @@ export default class PresentationOverlay extends Component {
     // id of the setInterval()
     this.intervalId = 0;
     this.state = {
-        zoom: props.zoom,
+      zoom: props.zoom,
     };
 
     // Mobile Firefox has a bug where e.preventDefault on touchstart doesn't prevent
@@ -48,44 +46,65 @@ export default class PresentationOverlay extends Component {
     this.zoomCalculation = this.zoomCalculation.bind(this);
     this.doZoomCall = this.doZoomCall.bind(this);
     this.zoomCall = this.zoomCall.bind(this);
-    this.updateCursorWhenZoom = this.updateCursorWhenZoom.bind(this);
-  }
-  // transforms the coordinate from window coordinate system
-  // to the main svg coordinate system
-  componentDidMount() {
+
+    this.isPortraitDoc = this.isPortraitDoc.bind(this);
+    this.doWidthBoundsDetection = this.doWidthBoundsDetection.bind(this);
+    this.doHeightBoundsDetection = this.doHeightBoundsDetection.bind(this);
+    this.calcViewedRegion = this.calcViewedRegion.bind(this);
+    this.onZoom = this.onZoom.bind(this);
+
     const {
+      adjustedSizes,
+      presentationSize,
       viewBoxWidth,
       viewBoxHeight,
-      adjustedSizes,
+      slideWidth,
       slideHeight,
+      slide,
+    } = props;
+
+    this.fitToPage = false;
+
+    this.viewportW = adjustedSizes.width;
+    this.viewportH = adjustedSizes.height;
+
+    this.viewedRegionX = slide.xOffset;
+    this.viewedRegionY = slide.yOffset;
+    this.viewedRegionW = (viewBoxWidth / slideWidth) * 100;
+    this.viewedRegionH = (viewBoxHeight / slideHeight) * 100;
+
+    this.pageOrigW = slideWidth;
+    this.pageOrigH = slideHeight;
+
+    this.parentW = presentationSize.presentationWidth;
+    this.parentH = presentationSize.presentationHeight;
+
+    this.calcPageW = this.viewportW / (this.viewedRegionW / HUNDRED_PERCENT);
+    this.calcPageH = this.viewportH / (this.viewedRegionH / HUNDRED_PERCENT);
+    this.calcPageX = (this.viewedRegionX / HUNDRED_PERCENT) * this.calcPageW;
+    this.calcPageY = (this.viewedRegionY / HUNDRED_PERCENT) * this.calcPageH;
+  }
+
+  componentDidMount() {
+    const {
+      viewBoxWidth,
       slideWidth,
-      x,
-      y,
       zoomChanger,
-      presentationSize,
-      getSvgRef,
     } = this.props;
-    const svgRect = getSvgRef().getBoundingClientRect();
-    const svgCenterX = svgRect.left + (svgRect.width / 2);
-    const svgCenterY = svgRect.top + (svgRect.height / 2);
-    const VRW = (viewBoxWidth / slideWidth) * 100;
-
-    this.SlideZoomData.viewportW = adjustedSizes.width;
-    this.SlideZoomData.viewportH = adjustedSizes.height;
-    this.SlideZoomData.pageOrigW = adjustedSizes.width;
-    this.SlideZoomData.pageOrigH = adjustedSizes.height;
-    this.SlideZoomData.parentW = presentationSize.presentationWidth;
-    this.SlideZoomData.parentH = presentationSize.presentationHeight;
-
-    const percentage = (Math.round((100 / VRW) * 100));
-    this.zoomCalculation(percentage, svgCenterX, svgCenterY);
-    this.doZoomCall(percentage, svgCenterX, svgCenterY);
+
+    const realZoom = (viewBoxWidth / slideWidth) * 100;
+    const zoomPercentage = (Math.round((100 / realZoom) * 100));
+
+    zoomChanger(zoomPercentage);
+
+    window.addEventListener('resize', () => {
+      setTimeout(this.handleResize.bind(this), 0);
+    });
   }
 
   componentDidUpdate() {
-    const { 
+    const {
       zoom,
-      zoomChanger,
       getSvgRef,
     } = this.props;
 
@@ -95,23 +114,98 @@ export default class PresentationOverlay extends Component {
 
     const isDiferent = zoom !== this.state.zoom;
     if (isDiferent) {
-
       this.doZoomCall(zoom, svgCenterX, svgCenterY);
     }
   }
+
+  componentWillUnmount() {
+    window.removeEventListener('resize', () => {
+      setTimeout(this.handleResize.bind(this), 0);
+    });
+  }
+
+  onZoom(zoomValue, mouseX, mouseY) {
+    let absXcoordInPage = (Math.abs(this.calcPageX) * MYSTERY_NUM) + mouseX;
+    let absYcoordInPage = (Math.abs(this.calcPageY) * MYSTERY_NUM) + mouseY;
+
+    const relXcoordInPage = absXcoordInPage / this.calcPageW;
+    const relYcoordInPage = absYcoordInPage / this.calcPageH;
+
+    if (this.isPortraitDoc() && this.fitToPage) {
+      this.calcPageH = (this.viewportH * zoomValue) / HUNDRED_PERCENT;
+      this.calcPageW = (this.pageOrigW / this.pageOrigH) * this.calcPageH;
+    } else if (!this.isPortraitDoc() && this.fitToPage) {
+      this.calcPageW = (this.viewportW * zoomValue) / HUNDRED_PERCENT;
+      this.calcPageH = (this.viewportH * zoomValue) / HUNDRED_PERCENT;
+    } else {
+      this.calcPageW = (this.viewportW * zoomValue) / HUNDRED_PERCENT;
+      this.calcPageH = (this.calcPageW / this.pageOrigW) * this.pageOrigH;
+    }
+
+    absXcoordInPage = relXcoordInPage * this.calcPageW;
+    absYcoordInPage = relYcoordInPage * this.calcPageH;
+
+    this.calcPageX = -((absXcoordInPage - mouseX) / MYSTERY_NUM);
+    this.calcPageY = -((absYcoordInPage - mouseY) / MYSTERY_NUM);
+
+    this.doWidthBoundsDetection();
+    this.doHeightBoundsDetection();
+
+    this.calcViewedRegion();
+  }
+
   getTransformedSvgPoint(clientX, clientY) {
     const svgObject = this.props.getSvgRef();
     const screenPoint = svgObject.createSVGPoint();
     screenPoint.x = clientX;
     screenPoint.y = clientY;
-    console.error(clientX, clientY);
-    
     // transform a screen point to svg point
     const CTM = svgObject.getScreenCTM();
 
     return screenPoint.matrixTransform(CTM.inverse());
   }
 
+  isPortraitDoc() {
+    return this.pageOrigH > this.pageOrigW;
+  }
+
+  handleResize() {
+    const {
+      presentationSize,
+      adjustedSizes,
+    } = this.props;
+
+    this.viewportW = adjustedSizes.width;
+    this.viewportH = adjustedSizes.height;
+    this.parentW = presentationSize.presentationWidth;
+    this.parentH = presentationSize.presentationHeight;
+  }
+
+  doWidthBoundsDetection() {
+    const verifyPositionToBound = (this.calcPageW + (this.calcPageX * MYSTERY_NUM));
+    if (this.calcPageX >= 0) {
+      this.calcPageX = 0;
+    } else if (verifyPositionToBound < this.viewportW) {
+      this.calcPageX = (this.viewportW - this.calcPageW) / MYSTERY_NUM;
+    }
+  }
+
+  doHeightBoundsDetection() {
+    const verifyPositionToBound = (this.calcPageH + (this.calcPageY * MYSTERY_NUM));
+    if (this.calcPageY >= 0) {
+      this.calcPageY = 0;
+    } else if (verifyPositionToBound < this.viewportH) {
+      this.calcPageY = (this.viewportH - this.calcPageH) / MYSTERY_NUM;
+    }
+  }
+
+  calcViewedRegion() {
+    this.viewedRegionW = SlideCalcUtil.calcViewedRegionWidth(this.viewportW, this.calcPageW);
+    this.viewedRegionH = SlideCalcUtil.calcViewedRegionHeight(this.viewportH, this.calcPageH);
+    this.viewedRegionX = SlideCalcUtil.calcViewedRegionX(this.calcPageX, this.calcPageW);
+    this.viewedRegionY = SlideCalcUtil.calcViewedRegionY(this.calcPageY, this.calcPageH);
+  }
+
   checkCursor() {
     // check if the cursor hasn't moved since last check
     if (this.lastSentClientX !== this.currentClientX
@@ -119,7 +213,7 @@ export default class PresentationOverlay extends Component {
       const { currentClientX, currentClientY } = this;
       // retrieving a transformed coordinate
       let transformedSvgPoint = this.getTransformedSvgPoint(currentClientX, currentClientY);
-      
+
       // determining the cursor's coordinates as percentages from the slide's width/height
       transformedSvgPoint = this.svgCoordinateToPercentages(transformedSvgPoint);
       // updating last sent raw coordinates
@@ -148,13 +242,13 @@ export default class PresentationOverlay extends Component {
   zoomCalculation(zoom, mouseX, mouseY) {
     const svgPosition = this.getTransformedSvgPoint(mouseX, mouseY);
 
-    this.SlideZoomData.onZoom(zoom, svgPosition.x, svgPosition.y);
+    this.onZoom(zoom, svgPosition.x, svgPosition.y);
 
     return {
-      viewedRegionW: this.SlideZoomData.viewedRegionW,
-      viewedRegionH: this.SlideZoomData.viewedRegionH,
-      viewedRegionX: this.SlideZoomData.viewedRegionX,
-      viewedRegionY: this.SlideZoomData.viewedRegionY,
+      viewedRegionW: this.viewedRegionW,
+      viewedRegionH: this.viewedRegionH,
+      viewedRegionX: this.viewedRegionX,
+      viewedRegionY: this.viewedRegionY,
     };
   }
 
@@ -167,24 +261,10 @@ export default class PresentationOverlay extends Component {
     zoomSlide(currentSlideNum, podId, w, h, x, y);
     this.setState({ zoom });
   }
-  updateCursorWhenZoom(mouseX, mouseY) {
-    const {
-      updateCursor,
-      whiteboardId,
-    } = this.props;
-    const svgPosition = this.getTransformedSvgPoint(mouseX, mouseY);
-    const svgPercentage = this.svgCoordinateToPercentages(svgPosition);
-    updateCursor({
-      xPercent: svgPercentage.x,
-      yPercent: svgPercentage.y,
-      whiteboardId,
-    });
-  }
 
   doZoomCall(zoom, mouseX, mouseY) {
     const zoomData = this.zoomCalculation(zoom, mouseX, mouseY);
-    console.error(zoomData);
-    
+
     const {
       viewedRegionW,
       viewedRegionH,
@@ -193,12 +273,16 @@ export default class PresentationOverlay extends Component {
     } = zoomData;
 
     this.zoomCall(zoom, viewedRegionW, viewedRegionH, viewedRegionX, viewedRegionY);
-    this.updateCursorWhenZoom(mouseX, mouseY);
     this.props.zoomChanger(zoom);
   }
 
   mouseZoomHandler(e) {
-    const { zoom } = this.props;
+    const {
+      zoom,
+      whiteboardId,
+      updateCursor,
+    } = this.props;
+
     let newZoom = zoom;
     if (e.deltaY < 0) {
       newZoom += 5;
@@ -214,10 +298,17 @@ export default class PresentationOverlay extends Component {
 
     const mouseX = e.clientX;
     const mouseY = e.clientY;
+    const svgPosition = this.getTransformedSvgPoint(mouseX, mouseY);
+    const svgPercentage = this.svgCoordinateToPercentages(svgPosition);
+
     this.doZoomCall(newZoom, mouseX, mouseY);
+    updateCursor({
+      xPercent: svgPercentage.x,
+      yPercent: svgPercentage.y,
+      whiteboardId,
+    });
   }
 
-
   handleTouchStart(event) {
     // to prevent default behavior (scrolling) on devices (in Safari), when you draw a text box
     event.preventDefault();
diff --git a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/component.jsx b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/component.jsx
index 597a5bd9aa4f929cea69542bbc88a8eac2542946..0e976e08d004a7f378fde855070ecf1ec1d3b475 100644
--- a/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/presentation/presentation-toolbar/zoom-tool/component.jsx
@@ -4,14 +4,14 @@ import { FormattedMessage } from 'react-intl';
 import Button from '/imports/ui/components/button/component';
 import { styles } from '../styles.scss';
 
-const DELAY_MILLISECONDS = 500;
+const DELAY_MILLISECONDS = 200;
 const STEP_TIME = 100;
 
 export default class ZoomTool extends Component {
   static renderAriaLabelsDescs() {
     return (
-      <div hidden >
-        {/* Previous Slide button aria */}
+      <div hidden key="hidden-div">
+        {/* Zoom in button aria */}
         <div id="zoomInLabel">
           <FormattedMessage
             id="app.presentation.presentationToolbar.zoomInLabel"
@@ -26,7 +26,7 @@ export default class ZoomTool extends Component {
             defaultMessage="Change the presentation to the previous slide"
           />
         </div>
-        {/* Next Slide button aria */}
+        {/* Zoom out button aria */}
         <div id="zoomOutLabel">
           <FormattedMessage
             id="app.presentation.presentationToolbar.zoomOutLabel"
@@ -41,7 +41,7 @@ export default class ZoomTool extends Component {
             defaultMessage="Change the presentation to the next slide"
           />
         </div>
-        {/* Skip Slide drop down aria */}
+        {/* Zoom indicator aria */}
         <div id="zoomIndicator">
           <FormattedMessage
             id="app.presentation.presentationToolbar.zoomIndicator"