Skip to content

Commit

Permalink
Fix: Presentation preloading scales without max (#487)
Browse files Browse the repository at this point in the history
This now matches the behavior of the presentation viewer, which doesn't have a max zoom scale.
  • Loading branch information
tonyjin authored Nov 17, 2017
1 parent a9580a6 commit 11b2277
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 154 deletions.
5 changes: 5 additions & 0 deletions src/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ export const X_REP_HINT_IMAGE = '[jpg?dimensions=2048x2048,png?dimensions=2048x2
export const X_REP_HINT_VIDEO_DASH = '[dash,mp4][filmstrip]';
export const X_REP_HINT_VIDEO_MP4 = '[mp4]';

export const PDFJS_CSS_UNITS = 96.0 / 72.0; // Should match CSS_UNITS in pdf_viewer.js
export const PDFJS_MAX_AUTO_SCALE = 1.25; // Should match MAX_AUTO_SCALE in pdf_viewer.js
export const PDFJS_WIDTH_PADDING_PX = 40; // Should match SCROLLBAR_PADDING in pdf_viewer.js
export const PDFJS_HEIGHT_PADDING_PX = 5; // Should match VERTICAL_PADDING in pdf_viewer.js

// These should be updated to match the Preview version in package.json whenever a file in that third party directory
// is updated. Also, update the matching configuration in karma.conf.js, which is needed for tests
export const DOC_STATIC_ASSETS_VERSION = '1.17.0';
Expand Down
65 changes: 35 additions & 30 deletions src/lib/viewers/doc/DocPreloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@ import {
CLASS_INVISIBLE,
CLASS_IS_TRANSPARENT,
CLASS_PREVIEW_LOADED,
CLASS_SPINNER
CLASS_SPINNER,
PDFJS_CSS_UNITS,
PDFJS_MAX_AUTO_SCALE,
PDFJS_WIDTH_PADDING_PX,
PDFJS_HEIGHT_PADDING_PX
} from '../../constants';
import { get, setDimensions } from '../../util';

const EXIF_COMMENT_TAG_NAME = 'UserComment'; // Read EXIF data from 'UserComment' tag
const EXIF_COMMENT_REGEX = /pdfWidth:([0-9.]+)pts,pdfHeight:([0-9.]+)pts,numPages:([0-9]+)/;

const PDFJS_CSS_UNITS = 96.0 / 72.0; // Should match CSS_UNITS in pdf_viewer.js
const PDFJS_MAX_AUTO_SCALE = 1.25; // Should match MAX_AUTO_SCALE in pdf_viewer.js
const PDFJS_WIDTH_PADDING_PX = 40; // Should match SCROLLBAR_PADDING in pdf_viewer.js
const PDFJS_HEIGHT_PADDING_PX = 5; // Should match VERTICAL_PADDING in pdf_viewer.js

const NUM_PAGES_DEFAULT = 2; // Default to 2 pages for preload if true number of pages cannot be read
const NUM_PAGES_MAX = 500; // Don't show more than 500 placeholder pages

Expand All @@ -33,6 +32,9 @@ class DocPreloader extends EventEmitter {
/** @property {HTMLElement} - Preload image element */
imageEl;

/** @property {HTMLElement} - Maximum auto-zoom scale */
maxZoomScale = PDFJS_MAX_AUTO_SCALE;

/** @property {HTMLElement} - Preload overlay element */
overlayEl;

Expand All @@ -59,7 +61,6 @@ class DocPreloader extends EventEmitter {
*/
constructor(previewUI) {
super();

this.previewUI = previewUI;
this.wrapperClassName = CLASS_BOX_PREVIEW_PRELOAD_WRAPPER_DOCUMENT;
}
Expand Down Expand Up @@ -242,6 +243,33 @@ class DocPreloader extends EventEmitter {
});
};

/**
* Returns scaled PDF dimensions using same algorithm as pdf.js up to a maximum of 1.25x zoom.
*
* @private
* @param {number} pdfWidth - Width of PDF in pixels
* @param {number} pdfHeight - Height of PDF in pixels
* @return {Object} Scaled width and height in pixels
*/
getScaledDimensions(pdfWidth, pdfHeight) {
const { clientWidth, clientHeight } = this.wrapperEl;
const widthScale = (clientWidth - PDFJS_WIDTH_PADDING_PX) / pdfWidth;
const heightScale = (clientHeight - PDFJS_HEIGHT_PADDING_PX) / pdfHeight;

const isLandscape = pdfWidth > pdfHeight;
let scale = isLandscape ? Math.min(heightScale, widthScale) : widthScale;

// Optionally limit to maximum zoom scale if defined
if (this.maxZoomScale) {
scale = Math.min(this.maxZoomScale, scale);
}

return {
scaledWidth: Math.floor(scale * pdfWidth),
scaledHeight: Math.floor(scale * pdfHeight)
};
}

/**
* Reads EXIF from preload JPG for PDF width, height, and numPages. This is currently encoded
* by Box Conversion into the preload JPG itself, but eventually this information will be
Expand Down Expand Up @@ -309,29 +337,6 @@ class DocPreloader extends EventEmitter {
});
}

/**
* Returns scaled PDF dimensions using same algorithm as pdf.js up to a maximum of 1.25x zoom.
*
* @private
* @param {number} pdfWidth - Width of PDF in pixels
* @param {number} pdfHeight - Height of PDF in pixels
* @return {Object} Scaled width and height in pixels
*/
getScaledDimensions(pdfWidth, pdfHeight) {
const { clientWidth, clientHeight } = this.wrapperEl;
const widthScale = (clientWidth - PDFJS_WIDTH_PADDING_PX) / pdfWidth;
const heightScale = (clientHeight - PDFJS_HEIGHT_PADDING_PX) / pdfHeight;
const isLandscape = pdfWidth > pdfHeight;

let scale = isLandscape ? Math.min(heightScale, widthScale) : widthScale;
scale = Math.min(PDFJS_MAX_AUTO_SCALE, scale);

return {
scaledWidth: Math.floor(scale * pdfWidth),
scaledHeight: Math.floor(scale * pdfHeight)
};
}

/**
* Check if full document is already loaded - if so, hide the preload.
*
Expand Down
7 changes: 7 additions & 0 deletions src/lib/viewers/doc/PresentationPreloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { CLASS_INVISIBLE, CLASS_BOX_PREVIEW_PRELOAD_WRAPPER_PRESENTATION } from
import { setDimensions } from '../../util';

class PresentationPreloader extends DocPreloader {
/**
* @property {HTMLELement} - Maximum auto-zoom scale, set to 0 for no limit since presentation viewer doesn't
* have a maximum zoom scale and scales up to available viewport
*/
maxZoomScale = 0;

/** @property {HTMLElement} - Preload container element */
preloadEl;

Expand All @@ -20,6 +26,7 @@ class PresentationPreloader extends DocPreloader {
*/
constructor(previewUI) {
super(previewUI);

this.wrapperClassName = CLASS_BOX_PREVIEW_PRELOAD_WRAPPER_PRESENTATION;
}

Expand Down
Loading

0 comments on commit 11b2277

Please sign in to comment.