UNPKG

gp-crm-ui

Version:

Модуль компонентов UI Имя модуля: `gp-crm-ui`

135 lines (118 loc) 3.79 kB
import { Injectable } from '@angular/core'; // Интерфейсы import { IDelta, IOffset } from '../interfaces'; // Сервис вспомогательных функций @Injectable() export class CrmHelperService { // Фиксирование числа в диапазоне public static clamp( value: number, min: number = 0, max: number = Number.POSITIVE_INFINITY): number { return Math.min(Math.max(value, min), max); } // Расстояние между двумя точками public static distance(a: IOffset, b: IOffset): number { const DOUBLE = 2; return Math.sqrt( Math.pow(a.left - b.left, DOUBLE) + Math.pow(a.top - b.top, DOUBLE) ); } /** * Получить путь из Node по событию * @param event - событие */ public static eventPath(event: MouseEvent | any): Node[] { const target = event.target || event.srcElement || event.currentTarget; const composedPath = event.composedPath && event.composedPath(); const path = composedPath || event.path; if (path) { // Safari fix return (path.indexOf(window) === -1) ? path.concat(window) : path; } const getParents = (node: Node, memo: Node[] = []): Node[] => ( node.parentNode ? getParents(node.parentNode, memo.concat(node.parentNode)) : memo ); return [target].concat(getParents(target), window); } /** * Проверить принадлежность element к parent в иерархии * @param parent - элемент родителя * @param element - проверяемый элемент */ public static hasParent(parent: any, element: any): boolean { let el = element; while (el) { if (el === parent) { return true; } el = el.parentElement; } return false; } /** * Расчет смещения элемента element от родительского элемента parent * @param parent - элемент родителя * @param element - проверяемый элемент * Возвращает объект содержащий значения смещения left, top * Учитывает смещения при помощи transform: translate */ public static getOffsetElement(parent: any, element: any): IOffset { let el: any = null; const offset: IOffset = { left: 0, top: 0 }; const hasParent = CrmHelperService.hasParent(parent, element); if (element !== parent && hasParent) { // Первый проход по иерархии (сбор смещений offsetLeft, offsetTop) el = element; while (el && el !== parent) { offset.left += el.offsetLeft; offset.top += el.offsetTop; el = el.offsetParent; } // Второй проход по иерархии (сбор смещений transform) el = element; const INDEX_MATRIX = 1; const INDEX_TX = 4; const INDEX_TY = 5; while (el && el !== parent) { const style = window.getComputedStyle(el); const mat = style.transform.match(/^matrix\((.+)\)$/); if (mat) { const matrix = mat[INDEX_MATRIX].split(', '); const tx = parseFloat(matrix[INDEX_TX]); const ty = parseFloat(matrix[INDEX_TY]); if (!isNaN(tx)) { offset.left += tx; } if (!isNaN(ty)) { offset.top += ty; } } el = el.parentElement; } } return offset; } // Получить дельту из события прокрутки public static getDeltaFromWheelEvent(event: any): IDelta { const delta: IDelta = { x: 0, y: 0 }; const e = event || window.event; const wheelDelta = -e.wheelDelta || e.detail; if (e.shiftKey === true) { delta.x = CrmHelperService.clamp(wheelDelta, -1, 1); } else { delta.y = CrmHelperService.clamp(wheelDelta, -1, 1); } return delta; } }