Add handling for popover animation
Browse files- index.html +3 -3
- src/highlight.ts +15 -4
- src/popover.ts +9 -0
- src/style.css +4 -0
index.html
CHANGED
|
@@ -321,15 +321,15 @@ npm install driver.js</pre
|
|
| 321 |
|
| 322 |
window.setTimeout(() => {
|
| 323 |
driverObj.highlight({ element: ".buttons button:first-child" });
|
| 324 |
-
},
|
| 325 |
|
| 326 |
window.setTimeout(() => {
|
| 327 |
driverObj.highlight({ element: ".buttons button:nth-child(5)" });
|
| 328 |
-
},
|
| 329 |
|
| 330 |
window.setTimeout(() => {
|
| 331 |
driverObj.highlight({ element: "h2" });
|
| 332 |
-
},
|
| 333 |
});
|
| 334 |
|
| 335 |
document
|
|
|
|
| 321 |
|
| 322 |
window.setTimeout(() => {
|
| 323 |
driverObj.highlight({ element: ".buttons button:first-child" });
|
| 324 |
+
}, 2000);
|
| 325 |
|
| 326 |
window.setTimeout(() => {
|
| 327 |
driverObj.highlight({ element: ".buttons button:nth-child(5)" });
|
| 328 |
+
}, 4000);
|
| 329 |
|
| 330 |
window.setTimeout(() => {
|
| 331 |
driverObj.highlight({ element: "h2" });
|
| 332 |
+
}, 8000);
|
| 333 |
});
|
| 334 |
|
| 335 |
document
|
src/highlight.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
import { DriveStep } from "./driver";
|
| 2 |
import { refreshStage, trackActiveElement, transitionStage } from "./stage";
|
| 3 |
import { getConfig } from "./config";
|
| 4 |
-
import { repositionPopover, renderPopover } from "./popover";
|
| 5 |
import { bringInView } from "./utils";
|
| 6 |
|
| 7 |
let previousHighlight: Element | undefined;
|
|
@@ -37,6 +37,13 @@ function transferHighlight(from: Element, to: Element) {
|
|
| 37 |
const duration = 400;
|
| 38 |
const start = Date.now();
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
const animate = () => {
|
| 41 |
// This makes sure that the repeated calls to transferHighlight
|
| 42 |
// don't interfere with each other. Only the last call will be
|
|
@@ -52,11 +59,13 @@ function transferHighlight(from: Element, to: Element) {
|
|
| 52 |
} else {
|
| 53 |
trackActiveElement(to);
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
currentTransitionCallback = undefined;
|
| 56 |
}
|
| 57 |
|
| 58 |
-
// refreshStage();
|
| 59 |
-
// refreshPopover();
|
| 60 |
window.requestAnimationFrame(animate);
|
| 61 |
};
|
| 62 |
|
|
@@ -64,7 +73,9 @@ function transferHighlight(from: Element, to: Element) {
|
|
| 64 |
window.requestAnimationFrame(animate);
|
| 65 |
|
| 66 |
bringInView(to);
|
| 67 |
-
|
|
|
|
|
|
|
| 68 |
|
| 69 |
from.classList.remove("driver-active-element");
|
| 70 |
to.classList.add("driver-active-element");
|
|
|
|
| 1 |
import { DriveStep } from "./driver";
|
| 2 |
import { refreshStage, trackActiveElement, transitionStage } from "./stage";
|
| 3 |
import { getConfig } from "./config";
|
| 4 |
+
import { repositionPopover, renderPopover, hidePopover } from "./popover";
|
| 5 |
import { bringInView } from "./utils";
|
| 6 |
|
| 7 |
let previousHighlight: Element | undefined;
|
|
|
|
| 37 |
const duration = 400;
|
| 38 |
const start = Date.now();
|
| 39 |
|
| 40 |
+
// If it's the first time we're highlighting an element, we show
|
| 41 |
+
// the popover immediately. Otherwise, we wait for the animation
|
| 42 |
+
// to finish before showing the popover.
|
| 43 |
+
const hasDelayedPopover = !from || from !== to;
|
| 44 |
+
|
| 45 |
+
hidePopover();
|
| 46 |
+
|
| 47 |
const animate = () => {
|
| 48 |
// This makes sure that the repeated calls to transferHighlight
|
| 49 |
// don't interfere with each other. Only the last call will be
|
|
|
|
| 59 |
} else {
|
| 60 |
trackActiveElement(to);
|
| 61 |
|
| 62 |
+
if (hasDelayedPopover) {
|
| 63 |
+
renderPopover(to);
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
currentTransitionCallback = undefined;
|
| 67 |
}
|
| 68 |
|
|
|
|
|
|
|
| 69 |
window.requestAnimationFrame(animate);
|
| 70 |
};
|
| 71 |
|
|
|
|
| 73 |
window.requestAnimationFrame(animate);
|
| 74 |
|
| 75 |
bringInView(to);
|
| 76 |
+
if (!hasDelayedPopover) {
|
| 77 |
+
renderPopover(to);
|
| 78 |
+
}
|
| 79 |
|
| 80 |
from.classList.remove("driver-active-element");
|
| 81 |
to.classList.add("driver-active-element");
|
src/popover.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
import { bringInView } from "./utils";
|
| 2 |
import { STAGE_PADDING } from "./stage";
|
|
|
|
| 3 |
|
| 4 |
export type Side = "top" | "right" | "bottom" | "left";
|
| 5 |
export type Alignment = "start" | "center" | "end";
|
|
@@ -27,6 +28,14 @@ type PopoverDOM = {
|
|
| 27 |
|
| 28 |
let popover: PopoverDOM | undefined;
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
export function renderPopover(element: Element) {
|
| 31 |
if (!popover) {
|
| 32 |
popover = createPopover();
|
|
|
|
| 1 |
import { bringInView } from "./utils";
|
| 2 |
import { STAGE_PADDING } from "./stage";
|
| 3 |
+
import { getConfig } from "./config";
|
| 4 |
|
| 5 |
export type Side = "top" | "right" | "bottom" | "left";
|
| 6 |
export type Alignment = "start" | "center" | "end";
|
|
|
|
| 28 |
|
| 29 |
let popover: PopoverDOM | undefined;
|
| 30 |
|
| 31 |
+
export function hidePopover() {
|
| 32 |
+
if (!popover) {
|
| 33 |
+
return;
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
popover.wrapper.style.display = "none";
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
export function renderPopover(element: Element) {
|
| 40 |
if (!popover) {
|
| 41 |
popover = createPopover();
|
src/style.css
CHANGED
|
@@ -25,6 +25,10 @@
|
|
| 25 |
animation: animate-fade-in 100ms ease-in-out;
|
| 26 |
}
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
/* Popover styles */
|
| 29 |
.driver-popover {
|
| 30 |
color: #2d2d2d;
|
|
|
|
| 25 |
animation: animate-fade-in 100ms ease-in-out;
|
| 26 |
}
|
| 27 |
|
| 28 |
+
.driver-fade .driver-popover {
|
| 29 |
+
animation: animate-fade-in 100ms;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
/* Popover styles */
|
| 33 |
.driver-popover {
|
| 34 |
color: #2d2d2d;
|