Skip to content

Commit

Permalink
Update: Animate Thumbnails Sidebar transition (#948)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conrad Chan authored Mar 12, 2019
1 parent 68fa4d1 commit 5616b74
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 74 deletions.
6 changes: 3 additions & 3 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
.setters-container {
display: flex;
font-size: 75%;
height: 25vh;
height: 10vh;
justify-content: space-around;
padding: 20px;
}
Expand All @@ -37,8 +37,8 @@
text-align: center;
}

#preview-container {
height: 75vh;
.preview-container {
height: 90vh;
width: 100vw;
}
</style>
Expand Down
25 changes: 8 additions & 17 deletions src/lib/ThumbnailsSidebar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import isFinite from 'lodash/isFinite';
import VirtualScroller from './VirtualScroller';
import { CLASS_HIDDEN } from './constants';
import BoundedCache from './BoundedCache';

const CLASS_BOX_PREVIEW_THUMBNAIL = 'bp-thumbnail';
Expand All @@ -26,6 +25,9 @@ class ThumbnailsSidebar {
/** @property {Array<HTMLElement>} - The list of currently rendered thumbnail elements */
currentThumbnails;

/** @property {Boolean} - Whether the sidebar is open or not */
isOpen;

/** @property {PDfViewer} - The PDFJS viewer instance */
pdfViewer;

Expand All @@ -46,6 +48,7 @@ class ThumbnailsSidebar {
this.currentThumbnails = [];
this.pdfViewer = pdfViewer;
this.thumbnailImageCache = new BoundedCache();
this.isOpen = false;

this.createImageEl = this.createImageEl.bind(this);
this.createPlaceholderThumbnail = this.createPlaceholderThumbnail.bind(this);
Expand Down Expand Up @@ -404,31 +407,23 @@ class ThumbnailsSidebar {
return;
}

if (!this.isOpen()) {
if (!this.isOpen) {
this.toggleOpen();
} else {
this.toggleClose();
}
}

/**
* Returns whether the sidebar is open or not
* @return {boolean} true if the sidebar is open, false if not
*/
isOpen() {
return this.anchorEl && !this.anchorEl.classList.contains(CLASS_HIDDEN);
}

/**
* Toggles the sidebar open. This will scroll the current page into view
* @return {void}
*/
toggleOpen() {
if (!this.anchorEl) {
if (!this.virtualScroller) {
return;
}

this.anchorEl.classList.remove(CLASS_HIDDEN);
this.isOpen = true;

this.virtualScroller.scrollIntoView(this.currentPage - 1);
}
Expand All @@ -438,11 +433,7 @@ class ThumbnailsSidebar {
* @return {void}
*/
toggleClose() {
if (!this.anchorEl) {
return;
}

this.anchorEl.classList.add(CLASS_HIDDEN);
this.isOpen = false;
}

/**
Expand Down
38 changes: 10 additions & 28 deletions src/lib/__tests__/ThumbnailsSidebar-test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable no-unused-expressions */
import ThumbnailsSidebar from '../ThumbnailsSidebar';
import VirtualScroller from '../VirtualScroller';
import { CLASS_HIDDEN } from '../constants';

const sandbox = sinon.sandbox.create();

Expand Down Expand Up @@ -431,7 +430,6 @@ describe('ThumbnailsSidebar', () => {

describe('toggle()', () => {
beforeEach(() => {
stubs.isOpen = sandbox.stub(thumbnailsSidebar, 'isOpen');
stubs.toggleOpen = sandbox.stub(thumbnailsSidebar, 'toggleOpen');
stubs.toggleClose = sandbox.stub(thumbnailsSidebar, 'toggleClose');
});
Expand All @@ -441,29 +439,26 @@ describe('ThumbnailsSidebar', () => {

thumbnailsSidebar.toggle();

expect(stubs.isOpen).not.to.be.called;
expect(stubs.toggleOpen).not.to.be.called;
expect(stubs.toggleClose).not.to.be.called;

thumbnailsSidebar.anchorEl = anchorEl;
});

it('should toggle open if it was closed', () => {
stubs.isOpen.returns(false);
thumbnailsSidebar.isOpen = false;

thumbnailsSidebar.toggle();

expect(stubs.isOpen).to.be.called;
expect(stubs.toggleOpen).to.be.called;
expect(stubs.toggleClose).not.to.be.called;
});

it('should toggle closed if it was open', () => {
stubs.isOpen.returns(true);
thumbnailsSidebar.isOpen = true;

thumbnailsSidebar.toggle();

expect(stubs.isOpen).to.be.called;
expect(stubs.toggleOpen).not.to.be.called;
expect(stubs.toggleClose).to.be.called;
});
Expand All @@ -475,46 +470,33 @@ describe('ThumbnailsSidebar', () => {
thumbnailsSidebar.virtualScroller = virtualScroller;
});

it('should do nothing if there is no anchorEl', () => {
thumbnailsSidebar.anchorEl = null;
it('should do nothing if there is no virtualScroller', () => {
thumbnailsSidebar.virtualScroller = null;
thumbnailsSidebar.isOpen = false;

thumbnailsSidebar.toggleOpen();

expect(stubs.removeClass).not.to.be.called;
expect(thumbnailsSidebar.isOpen).to.be.false;
expect(stubs.vsScrollIntoView).not.to.be.called;

thumbnailsSidebar.anchorEl = anchorEl;
});

it('should remove the hidden class and scroll the page into view', () => {
thumbnailsSidebar.currentPage = 3;

thumbnailsSidebar.toggleOpen();

expect(stubs.removeClass).to.be.calledWith(CLASS_HIDDEN);
expect(thumbnailsSidebar.isOpen).to.be.true;
expect(stubs.vsScrollIntoView).to.be.calledWith(2);
});
});

describe('toggleClose()', () => {
beforeEach(() => {
stubs.addClass = sandbox.stub(thumbnailsSidebar.anchorEl.classList, 'add');
});

it('should do nothing if there is no anchorEl', () => {
thumbnailsSidebar.anchorEl = null;

thumbnailsSidebar.toggleClose();

expect(stubs.addClass).not.to.be.called;

thumbnailsSidebar.anchorEl = anchorEl;
});
it('should set isOpen to false', () => {
thumbnailsSidebar.isOpen = true;

it('should add the hidden class', () => {
thumbnailsSidebar.toggleClose();

expect(stubs.addClass).to.be.calledWith(CLASS_HIDDEN);
expect(thumbnailsSidebar.isOpen).to.be.false;
});
});
});
10 changes: 9 additions & 1 deletion src/lib/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,14 @@ $header-height: 48px;

.bp-content {
align-items: center;
bottom: 0;
display: flex;
flex: 1 1 auto;
left: 0;
outline: none;
position: relative;
position: absolute;
right: 0;
top: 0;
}

.bp-content.bp-is-fullscreen {
Expand All @@ -159,6 +163,10 @@ $header-height: 48px;
}
}

.bp.bp-loaded .bp-content {
transition: left 300ms cubic-bezier(.4, 0, .2, 1);
}

.accessibility-hidden {
left: -9999px;
position: absolute;
Expand Down
1 change: 1 addition & 0 deletions src/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export const CLASS_BOX_PREVIEW_NOTIFICATION = 'bp-notification';
export const CLASS_BOX_PREVIEW_NOTIFICATION_WRAPPER = 'bp-notifications-wrapper';
export const CLASS_BOX_PREVIEW_TOGGLE_OVERLAY = 'bp-toggle-overlay';
export const CLASS_BOX_PREVIEW_THEME_DARK = 'bp-theme-dark';
export const CLASS_BOX_PREVIEW_THUMBNAILS_OPEN = 'bp-thumbnails-open';
export const CLASS_BOX_PREVIEW_THUMBNAILS_CONTAINER = 'bp-thumbnails-container';
export const CLASS_ELEM_KEYBOARD_FOCUS = 'bp-has-keyboard-focus';
export const CLASS_FULLSCREEN = 'bp-is-fullscreen';
Expand Down
35 changes: 20 additions & 15 deletions src/lib/viewers/doc/DocBaseViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
QUERY_PARAM_ENCODING,
ENCODING_TYPES,
CLASS_BOX_PREVIEW_THUMBNAILS_CONTAINER,
ANNOTATOR_EVENT
ANNOTATOR_EVENT,
CLASS_BOX_PREVIEW_THUMBNAILS_OPEN
} from '../../constants';
import { checkPermission, getRepresentation } from '../../file';
import { appendQueryParams, createAssetUrlCreator, getMidpoint, getDistance, getClosestPageToPinch } from '../../util';
Expand All @@ -39,24 +40,25 @@ import Timer from '../../Timer';

const CURRENT_PAGE_MAP_KEY = 'doc-current-page-map';
const DEFAULT_SCALE_DELTA = 1.1;
const IS_SAFARI_CLASS = 'is-safari';
const LOAD_TIMEOUT_MS = 180000; // 3 min timeout
const SAFARI_PRINT_TIMEOUT_MS = 1000; // Wait 1s before trying to print
const PRINT_DIALOG_TIMEOUT_MS = 500;
const MAX_SCALE = 10.0;
const MIN_SCALE = 0.1;
const MAX_PINCH_SCALE_VALUE = 3;
const MIN_PINCH_SCALE_VALUE = 0.25;
const MAX_SCALE = 10.0;
const MIN_PINCH_SCALE_DELTA = 0.01;
const IS_SAFARI_CLASS = 'is-safari';
const SCROLL_EVENT_THROTTLE_INTERVAL = 200;
const SCROLL_END_TIMEOUT = this.isMobile ? 500 : 250;
const RANGE_REQUEST_CHUNK_SIZE_US = 1048576; // 1MB
const RANGE_REQUEST_CHUNK_SIZE_NON_US = 524288; // 512KB
const MIN_PINCH_SCALE_VALUE = 0.25;
const MIN_SCALE = 0.1;
const MINIMUM_RANGE_REQUEST_FILE_SIZE_NON_US = 26214400; // 25MB
const MOBILE_MAX_CANVAS_SIZE = 2949120; // ~3MP 1920x1536
const PAGES_UNIT_NAME = 'pages';
const PINCH_PAGE_CLASS = 'pinch-page';
const PINCHING_CLASS = 'pinching';
const PAGES_UNIT_NAME = 'pages';
const PRINT_DIALOG_TIMEOUT_MS = 500;
const RANGE_REQUEST_CHUNK_SIZE_NON_US = 524288; // 512KB
const RANGE_REQUEST_CHUNK_SIZE_US = 1048576; // 1MB
const SAFARI_PRINT_TIMEOUT_MS = 1000; // Wait 1s before trying to print
const SCROLL_END_TIMEOUT = this.isMobile ? 500 : 250;
const SCROLL_EVENT_THROTTLE_INTERVAL = 200;
const THUMBNAILS_SIDEBAR_TRANSITION_TIME = 301; // 301ms
// List of metrics to be emitted only once per session
const METRICS_WHITELIST = [
USER_DOCUMENT_THUMBNAIL_EVENTS.CLOSE,
Expand Down Expand Up @@ -127,7 +129,7 @@ class DocBaseViewer extends BaseViewer {

if (this.options.enableThumbnailsSidebar) {
this.thumbnailsSidebarEl = document.createElement('div');
this.thumbnailsSidebarEl.className = `${CLASS_BOX_PREVIEW_THUMBNAILS_CONTAINER} ${CLASS_HIDDEN}`;
this.thumbnailsSidebarEl.className = `${CLASS_BOX_PREVIEW_THUMBNAILS_CONTAINER}`;
this.thumbnailsSidebarEl.setAttribute('data-testid', 'thumbnails-sidebar');
this.containerEl.parentNode.insertBefore(this.thumbnailsSidebarEl, this.containerEl);
}
Expand Down Expand Up @@ -1329,18 +1331,21 @@ class DocBaseViewer extends BaseViewer {

let metricName;
let eventName;
if (!this.thumbnailsSidebar.isOpen()) {
if (!this.thumbnailsSidebar.isOpen) {
this.rootEl.classList.remove(CLASS_BOX_PREVIEW_THUMBNAILS_OPEN);
metricName = USER_DOCUMENT_THUMBNAIL_EVENTS.CLOSE;
eventName = 'thumbnailsClose';
} else {
this.rootEl.classList.add(CLASS_BOX_PREVIEW_THUMBNAILS_OPEN);
metricName = USER_DOCUMENT_THUMBNAIL_EVENTS.OPEN;
eventName = 'thumbnailsOpen';
}

this.emitMetric({ name: metricName, data: pagesCount });
this.emit(eventName);

this.resize();
// Resize after the CSS animation to toggle the sidebar is complete
setTimeout(() => this.resize(), THUMBNAILS_SIDEBAR_TRANSITION_TIME);
}

/**
Expand Down
Loading

0 comments on commit 5616b74

Please sign in to comment.