Skip to content

Commit

Permalink
plots: add kbd nav, more persistent popover.
Browse files Browse the repository at this point in the history
  • Loading branch information
paulirish committed Apr 21, 2017
1 parent 13cb5b0 commit 39409c3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 11 deletions.
8 changes: 5 additions & 3 deletions plots/ab-screenshot/index.html
Expand Up @@ -29,12 +29,14 @@ <h1>Screenshots Viewer</h1>
<div id="legend-b">B (bottom): </div>
</div>
<div class="settings">
Align Timelines:&nbsp
<input id="align-control" class="checkbox" type="checkbox" checked="">
<label>
Align Timelines:&nbsp
<input id="align-control" class="checkbox" type="checkbox" checked="">
</label>
</div>
</div>
<div id="container"></div>
<div id="image-popover"></div>
<div id="image-popover" class="hidden"><img></div>

<script src="../out/screenshotsComparison.js"></script>
<script src="./screenshot-viewer.js"></script>
Expand Down
5 changes: 5 additions & 0 deletions plots/ab-screenshot/screenshot-viewer.css
Expand Up @@ -100,6 +100,7 @@ body {

#image-popover {
position: fixed;
outline: 1px solid black;
}

#image-popover img {
Expand Down Expand Up @@ -168,3 +169,7 @@ h1 {
.run-container {
margin-bottom: 10px;
}

.hidden {
visibility: hidden;
}
63 changes: 55 additions & 8 deletions plots/ab-screenshot/screenshot-viewer.js
Expand Up @@ -21,8 +21,10 @@

const queuedRendering = [];
const imagePopoverElement = document.getElementById('image-popover');
const imagePopoverImageElement = imagePopoverElement.querySelector('img');
const rootElement = document.getElementById('container');
let isAlignTimelineEnabled = true;
let shouldHidePopover = true;

/**
* Incrementally renders the sites, otherwise it hangs the browser
Expand Down Expand Up @@ -51,6 +53,7 @@ function renderFromQueue() {
* Renders the A/B screenshot comparison content generated from analyze.js.
*/
function main() {
registerHotkeys();
renderLegend(aggregatedScreenshots.a, aggregatedScreenshots.b);
renderScreenshots(aggregatedScreenshots.data);
document.getElementById('align-control').addEventListener('click', onToggleAlign);
Expand Down Expand Up @@ -80,6 +83,44 @@ function renderScreenshots(comparisons) {
}));
}

/**
* Animates the horizontal scroll position
* @param {number} scrollDistancePx
*/
function scrollPageHorizontally(scrollDistancePx, durationMs = 350) {
// thank you, paul lewis. <3z
const ease = (v, pow=3) => 1 - Math.pow(1 - v, pow);

const start = Date.now();
const end = start + durationMs;
let lastChangePx = 0;

scroll();

function scroll() {
const now = Date.now();
if (now >= end) return;

const pctDone = (now - start) / durationMs;
const pxToGo = ease(pctDone) * scrollDistancePx;
window.scrollBy(pxToGo - lastChangePx, 0);
lastChangePx = pxToGo;
window.requestAnimationFrame(scroll);
}
}

/**
* Binds global keyboard event handlers for panning the view with A & D keys.
*/
function registerHotkeys() {
document.addEventListener('keydown', event => {
// move to the left
if (event.code === 'KeyA') scrollPageHorizontally(-350);
// move to the right
if (event.code === 'KeyD') scrollPageHorizontally(350);
}, {passive: true});
}

/**
* Renders the legend in the top bar based on the name of the path.
* @param {string} a
Expand Down Expand Up @@ -246,9 +287,14 @@ function createHeaderLabelElement(screenshot) {
function createScreenshotImageElement(screenshot) {
const image = createElement('img', 'screenshot-image');
image.src = screenshot.datauri;
image.addEventListener('mouseover', onImageMouseover.bind(null, imagePopoverElement, screenshot));
image.addEventListener('mouseout', () => {
removeChildren(imagePopoverElement);
image.addEventListener('mouseenter', event =>
onImageMouseover(imagePopoverElement, screenshot, event));
image.addEventListener('mouseleave', () => {
shouldHidePopover = true;
setTimeout(_ => {
if (shouldHidePopover)
imagePopoverElement.classList.add('hidden');
}, 200);
});
return image;
}
Expand All @@ -260,11 +306,12 @@ function createScreenshotImageElement(screenshot) {
* @param {!Event} event
*/
function onImageMouseover(imagePopoverElement, screenshot, event) {
const image = createElement('img');
image.src = screenshot.datauri;
imagePopoverElement.appendChild(image);
imagePopoverElement.style.top = event.clientY + 20 + 'px';
imagePopoverElement.style.left = event.clientX + 20 + 'px';
shouldHidePopover = false;
imagePopoverImageElement.src = screenshot.datauri;
imagePopoverElement.classList.remove('hidden');
const pos = event.currentTarget.getBoundingClientRect();
imagePopoverElement.style.top = pos.bottom + 2 + 'px';
imagePopoverElement.style.left = pos.left + 20 + 'px';
}

/**
Expand Down

0 comments on commit 39409c3

Please sign in to comment.