Simplify reader visible page detection
This commit is contained in:
@@ -494,22 +494,8 @@ export class ReaderControls {
|
|||||||
type: PageInViewportType,
|
type: PageInViewportType,
|
||||||
readingDirection: ReadingDirection,
|
readingDirection: ReadingDirection,
|
||||||
) {
|
) {
|
||||||
const themeDirectionForReadingDirection = READING_DIRECTION_TO_THEME_DIRECTION[readingDirection];
|
|
||||||
|
|
||||||
const firstVisibleImageIndex = imageRefs.current.findIndex(
|
const firstVisibleImageIndex = imageRefs.current.findIndex(
|
||||||
(image) =>
|
(image) => image && isPageInViewport(image, type, { truncateValues: true }),
|
||||||
image &&
|
|
||||||
isPageInViewport(
|
|
||||||
image,
|
|
||||||
type,
|
|
||||||
// the pages aren't always properly scrolled to the top which results in the leading page to still be slightly
|
|
||||||
// visible (e.g. 0.0123px) breaking the "first visible image" detection
|
|
||||||
{
|
|
||||||
bottom: 1,
|
|
||||||
left: getOptionForDirection(0, 1, themeDirectionForReadingDirection),
|
|
||||||
right: getOptionForDirection(1, 0, themeDirectionForReadingDirection),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
const lastPage = imageRefs.current?.[imageRefs.current.length - 1];
|
const lastPage = imageRefs.current?.[imageRefs.current.length - 1];
|
||||||
const isEndReached = lastPage && isEndOfPageInViewport(lastPage, type, readingDirection);
|
const isEndReached = lastPage && isEndOfPageInViewport(lastPage, type, readingDirection);
|
||||||
|
|||||||
@@ -333,13 +333,21 @@ type InViewportThresholds = {
|
|||||||
left?: number;
|
left?: number;
|
||||||
right?: number;
|
right?: number;
|
||||||
};
|
};
|
||||||
const getIsPageInViewportInfo = (
|
type InViewportOptions = {
|
||||||
element: HTMLElement,
|
/**
|
||||||
|
* The pages aren't always properly scrolled to the start/end (e.g., via scrollIntoView) which results in a side to be slightly
|
||||||
|
* visible (e.g. 0.0123px) breaking the visibility detection
|
||||||
|
*/
|
||||||
|
truncateValues?: boolean;
|
||||||
/**
|
/**
|
||||||
* Thresholds are not considered for the detection of an image filling the whole viewport.
|
* Thresholds are not considered for the detection of an image filling the whole viewport.
|
||||||
* They are only used for detecting if a specific side of an image is inside the viewport
|
* They are only used for detecting if a specific side of an image is inside the viewport
|
||||||
*/
|
*/
|
||||||
argThresholds?: InViewportThresholds,
|
thresholds?: InViewportThresholds;
|
||||||
|
};
|
||||||
|
const getIsPageInViewportInfo = (
|
||||||
|
element: HTMLElement,
|
||||||
|
{ truncateValues, thresholds: argThresholds }: InViewportOptions = { truncateValues: false, thresholds: {} },
|
||||||
): {
|
): {
|
||||||
isLeftInViewport: boolean;
|
isLeftInViewport: boolean;
|
||||||
isRightInViewport: boolean;
|
isRightInViewport: boolean;
|
||||||
@@ -348,7 +356,13 @@ const getIsPageInViewportInfo = (
|
|||||||
isBottomInViewport: boolean;
|
isBottomInViewport: boolean;
|
||||||
isFillingHeightViewportCompletely: boolean;
|
isFillingHeightViewportCompletely: boolean;
|
||||||
} => {
|
} => {
|
||||||
const { top, bottom, left, right } = element.getBoundingClientRect();
|
const { top: topRaw, bottom: bottomRaw, left: leftRaw, right: rightRaw } = element.getBoundingClientRect();
|
||||||
|
|
||||||
|
const maybeTruncateValue = (value: number): number => (truncateValues ? Math.trunc(value) : value);
|
||||||
|
const top = maybeTruncateValue(topRaw);
|
||||||
|
const bottom = maybeTruncateValue(bottomRaw);
|
||||||
|
const left = maybeTruncateValue(leftRaw);
|
||||||
|
const right = maybeTruncateValue(rightRaw);
|
||||||
|
|
||||||
const thresholds = {
|
const thresholds = {
|
||||||
top: 0,
|
top: 0,
|
||||||
@@ -379,7 +393,7 @@ const getIsPageInViewportInfo = (
|
|||||||
export const isPageInViewport = (
|
export const isPageInViewport = (
|
||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
type: PageInViewportType,
|
type: PageInViewportType,
|
||||||
thresholds?: InViewportThresholds,
|
options?: InViewportOptions,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const {
|
const {
|
||||||
isLeftInViewport,
|
isLeftInViewport,
|
||||||
@@ -388,7 +402,7 @@ export const isPageInViewport = (
|
|||||||
isTopInViewport,
|
isTopInViewport,
|
||||||
isBottomInViewport,
|
isBottomInViewport,
|
||||||
isFillingHeightViewportCompletely,
|
isFillingHeightViewportCompletely,
|
||||||
} = getIsPageInViewportInfo(element, thresholds);
|
} = getIsPageInViewportInfo(element, options);
|
||||||
|
|
||||||
const isInViewportX = isLeftInViewport || isRightInViewport || isFillingWidthViewportCompletely;
|
const isInViewportX = isLeftInViewport || isRightInViewport || isFillingWidthViewportCompletely;
|
||||||
const isInViewportY = isTopInViewport || isBottomInViewport || isFillingHeightViewportCompletely;
|
const isInViewportY = isTopInViewport || isBottomInViewport || isFillingHeightViewportCompletely;
|
||||||
|
|||||||
Reference in New Issue
Block a user