UNPKG

react-native

Version:

A framework for building native apps using React

168 lines (144 loc) 5.07 kB
/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow strict-local * @format */ // flowlint unsafe-getters-setters:off import type ReactNativeElement from '../dom/nodes/ReactNativeElement'; import type {NativeIntersectionObserverEntry} from './specs/NativeIntersectionObserver'; import DOMRectReadOnly from '../dom/geometry/DOMRectReadOnly'; /** * The [`IntersectionObserverEntry`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry) * interface of the Intersection Observer API describes the intersection between * the target element and its root container at a specific moment of transition. * * An array of `IntersectionObserverEntry` is delivered to * `IntersectionObserver` callbacks as the first argument. */ export default class IntersectionObserverEntry { // We lazily compute all the properties from the raw entry provided by the // native module, so we avoid unnecessary work. _nativeEntry: NativeIntersectionObserverEntry; // There are cases where this cannot be safely derived from the instance // handle in the native entry (when the target is detached), so we need to // keep a reference to it directly. _target: ReactNativeElement; constructor( nativeEntry: NativeIntersectionObserverEntry, target: ReactNativeElement, ) { this._nativeEntry = nativeEntry; this._target = target; } /** * Returns the bounds rectangle of the target element as a `DOMRectReadOnly`. * The bounds are computed as described in the documentation for * [`Element.getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). */ get boundingClientRect(): DOMRectReadOnly { const targetRect = this._nativeEntry.targetRect; return new DOMRectReadOnly( targetRect[0], targetRect[1], targetRect[2], targetRect[3], ); } /** * Returns the ratio of the `intersectionRect` to the `boundingClientRect`. */ get intersectionRatio(): number { const intersectionRect = this.intersectionRect; const boundingClientRect = this.boundingClientRect; if (boundingClientRect.width === 0 || boundingClientRect.height === 0) { return 0; } const ratio = (intersectionRect.width * intersectionRect.height) / (boundingClientRect.width * boundingClientRect.height); // Prevent rounding errors from making this value greater than 1. return Math.min(ratio, 1); } /** * Returns the ratio of the `intersectionRect` to the `boundingRootRect`. */ get rnRootIntersectionRatio(): number { const intersectionRect = this.intersectionRect; const rootRect = this._nativeEntry.rootRect; const boundingRootRect = new DOMRectReadOnly( rootRect[0], rootRect[1], rootRect[2], rootRect[3], ); if (boundingRootRect.width === 0 || boundingRootRect.height === 0) { return 0; } const ratio = (intersectionRect.width * intersectionRect.height) / (boundingRootRect.width * boundingRootRect.height); // Prevent rounding errors from making this value greater than 1. return Math.min(ratio, 1); } /** * Returns a `DOMRectReadOnly` representing the target's visible area. */ get intersectionRect(): DOMRectReadOnly { const intersectionRect = this._nativeEntry.intersectionRect; if (intersectionRect == null) { return new DOMRectReadOnly(); } return new DOMRectReadOnly( intersectionRect[0], intersectionRect[1], intersectionRect[2], intersectionRect[3], ); } /** * A `Boolean` value which is `true` if the target element intersects with the * intersection observer's root. * * If this is `true`, then, the `IntersectionObserverEntry` describes a * transition into a state of intersection. * * If it's `false`, then you know the transition is from intersecting to * not-intersecting. */ get isIntersecting(): boolean { return this._nativeEntry.isIntersectingAboveThresholds; } /** * Returns a `DOMRectReadOnly` for the intersection observer's root. */ get rootBounds(): DOMRectReadOnly { const rootRect = this._nativeEntry.rootRect; return new DOMRectReadOnly( rootRect[0], rootRect[1], rootRect[2], rootRect[3], ); } /** * The `ReactNativeElement` whose intersection with the root changed. */ get target(): ReactNativeElement { return this._target; } /** * A `DOMHighResTimeStamp` indicating the time at which the intersection was * recorded, relative to the `IntersectionObserver`'s time origin. */ get time(): DOMHighResTimeStamp { return this._nativeEntry.time; } } export function createIntersectionObserverEntry( entry: NativeIntersectionObserverEntry, target: ReactNativeElement, ): IntersectionObserverEntry { return new IntersectionObserverEntry(entry, target); }