Handle scrollable elements for highlighting

This commit is contained in:
Kamran Ahmed
2023-05-11 05:27:06 +01:00
parent 84809869f8
commit 82a88c5b81
6 changed files with 145 additions and 39 deletions
+87 -2
View File
@@ -94,6 +94,15 @@
padding: 10px;
line-height: 1.75;
}
#scrollable-area {
height: 300px;
overflow: auto;
border: 1px solid #ccc;
padding: 10px;
border-radius: 5px;
margin: 50px 0;
}
</style>
</head>
<body>
@@ -110,6 +119,8 @@
<button id="disallow-close">Disallow Close</button>
<button id="dark-highlight-btn">Super Dark Highlight</button>
<button id="dim-highlight-btn">Super Dim Highlight</button>
<button id="scrollable-area-btn">Scrollable Area</button>
<button id="inner-scroll-area-btn">Inner Scroll Area</button>
<button id="tour-btn">Start Tour</button>
<button id="destroy-btn">Destroy</button>
</div>
@@ -131,14 +142,14 @@
off the Lights" widgets that you might have seen on video players
online, etc.
</p>
<p>
<p class="second-para">
Driver.js is written in Vanilla JS, has zero dependencies and is highly
customizable. It has several options allowing you to manipulate how it
behaves and also provides you the hooks to manipulate the elements as
they are highlighted, about to be highlighted, or deselected.
</p>
<h2>Installation</h2>
<h2 id="installation-head">Installation</h2>
<p>You can install it using yarn or npm, whatever you prefer.</p>
<pre>
@@ -175,6 +186,62 @@ npm install driver.js</pre
libero, minus molestias necessitatibus nesciunt non omnis, quasi
recusandae tempore voluptates!
</p>
<div id="scrollable-area">
<p>
First -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p>
Second -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p id="third-scroll-paragraph">
Third -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p>
Fourth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p>
Fifth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p>
Sixth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p>
Seventh -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p>
Eighth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
<p>
Ninth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
doloremque laborum maxime necessitatibus nostrum odio, officiis
quibusdam veniam! Doloribus eos id quaerat.
</p>
</div>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
@@ -249,6 +316,24 @@ npm install driver.js</pre
window.setTimeout(() => {
driverObj.highlight({ element: ".buttons" });
}, 1000);
window.setTimeout(() => {
driverObj.highlight({ element: "#installation-head" });
}, 1500);
});
document
.getElementById("scrollable-area-btn")
.addEventListener("click", () => {
const driverObj = driver({ animate: true });
driverObj.highlight({ element: "#scrollable-area" });
});
document
.getElementById("inner-scroll-area-btn")
.addEventListener("click", () => {
const driverObj = driver({ animate: true });
driverObj.highlight({ element: "#third-scroll-paragraph" });
});
document
+2
View File
@@ -1,5 +1,6 @@
export type Config = {
animate?: boolean;
smoothScroll?: boolean;
allowClose?: boolean;
opacity?: number;
};
@@ -11,6 +12,7 @@ export function configure(config: Config = {}) {
animate: true,
allowClose: true,
opacity: 0.7,
smoothScroll: true,
...config,
};
}
+3 -25
View File
@@ -2,6 +2,7 @@ import { DriveStep } from "./driver";
import { refreshStage, trackActiveElement, transitionStage } from "./stage";
import { getConfig } from "./config";
import { refreshPopover, renderPopover } from "./popover";
import { bringInView } from "./utils";
let previousHighlight: Element | undefined;
let activeHighlight: Element | undefined;
@@ -48,7 +49,6 @@ function transferHighlight(from: Element, to: Element) {
if (getConfig("animate") && elapsed < duration) {
transitionStage(elapsed, duration, from, to);
} else {
bringInView(to);
trackActiveElement(to);
renderPopover(to);
@@ -63,34 +63,12 @@ function transferHighlight(from: Element, to: Element) {
currentTransitionCallback = animate;
window.requestAnimationFrame(animate);
bringInView(to);
from.classList.remove("driver-active-element");
to.classList.add("driver-active-element");
}
function bringInView(element: Element) {
if (!element || isElementInView(element)) {
return;
}
element.scrollIntoView({
behavior: "smooth",
inline: "center",
block: "center",
});
}
function isElementInView(element: Element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
export function destroyHighlight() {
activeHighlight = undefined;
currentTransitionCallback = undefined;
-11
View File
@@ -1,11 +0,0 @@
export function easeInOutQuad(
elapsed: number,
initialValue: number,
amountOfChange: number,
duration: number
): number {
if ((elapsed /= duration / 2) < 1) {
return (amountOfChange / 2) * elapsed * elapsed + initialValue;
}
return (-amountOfChange / 2) * (--elapsed * (elapsed - 2) - 1) + initialValue;
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { easeInOutQuad } from "./math";
import { easeInOutQuad } from "./utils";
import { onDriverClick } from "./events";
import { trigger } from "./hooks";
import { getConfig } from "./config";
+52
View File
@@ -0,0 +1,52 @@
import { getConfig } from "./config";
export function easeInOutQuad(
elapsed: number,
initialValue: number,
amountOfChange: number,
duration: number
): number {
if ((elapsed /= duration / 2) < 1) {
return (amountOfChange / 2) * elapsed * elapsed + initialValue;
}
return (-amountOfChange / 2) * (--elapsed * (elapsed - 2) - 1) + initialValue;
}
export function bringInView(element: Element) {
if (!element || isElementInView(element)) {
return;
}
const shouldSmoothScroll = getConfig("smoothScroll");
element.scrollIntoView({
// Removing the smooth scrolling for elements which exist inside the scrollable parent
// This was causing the highlight to not properly render
behavior:
!shouldSmoothScroll || hasScrollableParent(element) ? "auto" : "smooth",
inline: "center",
block: "center",
});
}
function hasScrollableParent(e: Element) {
if (!e || !e.parentElement) {
return;
}
const parent = e.parentElement as HTMLElement & { scrollTopMax?: number };
return parent.scrollHeight > parent.clientHeight;
}
function isElementInView(element: Element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <=
(window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}