UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

133 lines (116 loc) 4.59 kB
/* eslint-disable @typescript-eslint/no-use-before-define */ /** * Measure vertical or horizontal intersection of current and target object * depending on given direction. * @param {Object} current rect object {right, left, top, bottom, x, y, width. height} * @param {Object} target rect object {right, left, top, bottom, x, y, width. height} * @param {Object} direction of measuring intersection * @returns {Int} Returns vaertival intersection of current and target object */ export function measureDimensionalIntersection(direction, current, target) { if (direction.isHorizontal) { return measureVerticalIntersectiont(current, target); } else { return measureHorizontalIntersection(current, target); } } /** * Measure vertical intersection of current and target object * ┏━━━━┓ * ┃ ┃┄┄┄┄┏━━━━┓┄┄ ← Vertical intersection of 2 elements * ┗━━━━┛┄┄┄┄┃ ┃┄┄ ← for horizontal movement * ┗━━━━┛ * @param {Object} current rect object {right, left, top, bottom, x, y, width. height} * @param {Object} target rect object {right, left, top, bottom, x, y, width. height} * @returns {Int} Returns vertical intersection of current and target object */ export function measureVerticalIntersectiont(current, target) { if (target.top >= current.bottom || target.bottom <= current.top) { return 0; } const top = Math.max(current.top, target.top); const bottom = Math.min(current.bottom, target.bottom); return bottom - top; } /** * Measure horizontal intersection of current and target object * ┏━━━━┓ * ┃ ┃ * ┗━━━━┛ * ┆ ┆ * ┏━━━━┓ * ┃ ┃ * ┗━━━━┛ * ↑ ↑ * Horizontal intersection of 2 elements for vertical movement * @param {Object} current rect object {right, left, top, bottom, x, y, width. height} * @param {Object} target rect object {right, left, top, bottom, x, y, width. height} * @returns {Int} Returns horizontal intersection of current and target object */ export function measureHorizontalIntersection(current, target) { if (target.right <= current.left || target.left >= current.right) { return 0; } const left = Math.max(current.left, target.left); const right = Math.min(current.right, target.right); return right - left; } /** * Returns always positive value to the elements in specific direction * For instance if I direction is left and target is on the left it will return a * distance to current direction which will be > 0. If target is on the right of the * current element then returned value will be negative * @param {Object} current rect object {right, left, top, bottom, x, y, width. height} * @param {Object} target rect object {right, left, top, bottom, x, y, width. height} * @param {Object} direction direction of the navigation intent any of ["right", "left", "up", "down"] * @returns {Int} distance to target object in soecified direction */ export function measureDistance(direction, current, target) { switch (direction.value) { case "right": return -1 * (current.right - target.left); case "left": return current.left - target.right; case "up": if (target.x + target.width < 0) { // Offscreen to the left, make sure it's too far away ( more than -1 away) return -10000; } return current.top - target.bottom; case "down": if (target.x > 1920) { // // Offscreen to the right, make sure it's too far away ( more than -1 away) return -10000; } return -1 * (current.bottom - target.top); } } export function measureEuclidianDistanceToCenter(current, target) { const currentCenter = getCenter(current); const targetCenter = getCenter(target); return Math.sqrt( Math.pow(targetCenter.x - currentCenter.x, 2) + Math.pow(targetCenter.y - currentCenter.y, 2) ); } function getCenter(rect) { const { left, right, top, bottom } = rect; return { x: (left + right) / 2, y: (top + bottom) / 2, }; } export function isOnDirection(direction, current, target) { const currentCenter = getCenter(current); const targetCenter = getCenter(target); if (direction.isHorizontal) { return direction.value === "right" ? targetCenter.x - currentCenter.x > 0 : targetCenter.x - currentCenter.x < 0; } if (direction.isVertical) { return direction.value === "up" ? targetCenter.y - currentCenter.y < 0 : targetCenter.y - currentCenter.y > 0; } }