import { sML } from "../../helpers/sML.ts"; export interface Point { X: number; Y: number; } export enum HorizontalThird { Left, Center, Right } export enum VerticalThird { Top, Middle, Bottom } export interface NinthPoint { X: HorizontalThird | null; Y: VerticalThird | null; } export interface BibiEvent { Target: EventTarget | null; Coord: Point | null; Ratio: Point | null; Division: NinthPoint | null; } export class FXLCoordinator { HTML: HTMLElement; Head: HTMLHeadElement; Body: HTMLElement; constructor() { this.HTML = document.documentElement; this.Head = document.head; this.Body = document.body; } /* getElementCoord(El: any) { var Coord = { X: El["offsetLeft"], Y: El["offsetTop"] }; while(El.offsetParent) El = El.offsetParent, Coord.X += El["offsetLeft"], Coord.Y += El["offsetTop"]; return Coord; } */ private outerWidth = 0; private outerHeight = 0; refreshOuterPixels(_: DOMRect) { if(sML.OS.iOS) return; // No need on iOS this.outerHeight = window.outerHeight - window.innerHeight; if(sML.OS.Android && sML.UA.Chrome) { if(window.screen.height > window.innerHeight) // This is a hack: since outer/inner are zero, we assume there's a // top (chrome url bar) and bottom (android controls) bar and divide // by 1.5 because the top bar is roughtly 2x height of the bottom one this.outerHeight = (window.screen.height - window.innerHeight) / 1.5; } this.outerWidth = window.outerWidth - window.innerWidth; } getBibiEventCoord(Eve: TouchEvent | MouseEvent, touch=0): Point { const Coord: Point = { X:0, Y:0 }; if(/^touch/.test(Eve.type)) { Coord.X = (Eve as TouchEvent).touches[touch].screenX; Coord.Y = (Eve as TouchEvent).touches[touch].screenY; } else { Coord.X = (Eve as MouseEvent).screenX; Coord.Y = (Eve as MouseEvent).screenY; } if(((Eve.target as HTMLElement).ownerDocument?.documentElement || (Eve.target as HTMLDocument).documentElement) === this.HTML) { Coord.X -= (this.HTML.scrollLeft + this.Body.scrollLeft); Coord.Y -= (this.HTML.scrollTop + this.Body.scrollTop); } else { /* var Item = Eve.target.ownerDocument.documentElement.Item; ItemCoord = this.getElementCoord(Item); if(!Item.PrePaginated && !Item.Outsourcing) ItemCoord.X += settings.S["item-padding-left"], ItemCoord.Y += settings.S["item-padding-top"]; Coord.X = (Coord.X + ItemCoord.X - R.Main.scrollLeft) * R.Main.Transformation.Scale + R.Main.Transformation.Translation.X; Coord.Y = (Coord.Y + ItemCoord.Y - R.Main.scrollTop ) * R.Main.Transformation.Scale + R.Main.Transformation.Translation.Y; */ } Coord.X -= this.outerWidth; Coord.Y -= this.outerHeight; return Coord; } getTouchDistance(Eve: TouchEvent) { if (Eve.touches.length !== 2) return 0; const x1 = Eve.touches[0].screenX - this.outerWidth; const y1 = Eve.touches[0].screenY - this.outerHeight; const x2 = Eve.touches[1].screenX - this.outerWidth; const y2 = Eve.touches[1].screenY - this.outerHeight; return Math.sqrt((Math.pow((x2 - x1), 2)) + (Math.pow((y2 - y1), 2))); } getTouchCenter(Eve: TouchEvent): Point | null { if (Eve.touches.length !== 2) return null; const subL = (this.HTML.scrollLeft + this.Body.scrollLeft); const subT = (this.HTML.scrollTop + this.Body.scrollTop); const x1 = Eve.touches[0].screenX - this.outerWidth - subL; const y1 = Eve.touches[0].screenY - this.outerHeight - subT; const x2 = Eve.touches[1].screenX - this.outerWidth - subL; const y2 = Eve.touches[1].screenY - this.outerHeight - subT; return { X: (x1 + x2) / 2, Y: (y1 + y2) / 2 }; } getBibiEvent(Eve: Event): BibiEvent { if(!Eve) return { Coord: null, Division: null, Ratio: null, Target: null }; const Coord = this.getBibiEventCoord(Eve as TouchEvent | MouseEvent); let FlipperWidth = 0.3; // TODO flipper-width const Ratio = { X: Coord.X / window.innerWidth, Y: Coord.Y / window.innerHeight }; let BorderT, BorderB, BorderL, BorderR; if(FlipperWidth < 1) { // Ratio BorderL = BorderT = FlipperWidth; BorderR = BorderB = 1 - FlipperWidth; } else { // Pixel to Ratio BorderL = FlipperWidth / window.innerWidth; BorderT = FlipperWidth / window.innerHeight; BorderR = 1 - BorderL; BorderB = 1 - BorderT; } const Division: NinthPoint = { X: null, Y: null }; if(Ratio.X < BorderL) Division.X = HorizontalThird.Left; else if(BorderR < Ratio.X) Division.X = HorizontalThird.Right; else Division.X = HorizontalThird.Center; if(Ratio.Y < BorderT) Division.Y = VerticalThird.Top; else if(BorderB < Ratio.Y) Division.Y = VerticalThird.Bottom; else Division.Y = VerticalThird.Middle; return { Target: Eve.target, Coord: Coord, Ratio: Ratio, Division: Division }; } }