in src/component/popup/popup/Popup.ts [396:485]
private _rectToPixel(
rect: number[],
position: PopupAlignment,
appliedPosition: PopupAlignment,
renderCamera: RenderCamera,
size: ViewportSize,
transform: Transform): [number[], PopupAlignment] {
if (!position) {
const width: number = this._container.offsetWidth;
const height: number = this._container.offsetHeight;
const floatOffsets: { [key: string]: number[]; } = {
"bottom": [0, height / 2],
"bottom-left": [-width / 2, height / 2],
"bottom-right": [width / 2, height / 2],
"left": [-width / 2, 0],
"right": [width / 2, 0],
"top": [0, -height / 2],
"top-left": [-width / 2, -height / 2],
"top-right": [width / 2, -height / 2],
};
const automaticPositions: PopupAlignment[] =
["top", "bottom", "left", "right"];
let largestVisibleArea: [number, number[], PopupAlignment] = [0, null, null];
for (const automaticPosition of automaticPositions) {
const autoPointBasic: number[] = this._pointFromRectPosition(rect, automaticPosition);
const autoPointPixel: number[] =
this._viewportCoords.basicToCanvasSafe(
autoPointBasic[0],
autoPointBasic[1],
{ offsetHeight: size.height, offsetWidth: size.width },
transform,
renderCamera.perspective);
if (autoPointPixel == null) {
continue;
}
const floatOffset: number[] = floatOffsets[automaticPosition];
const offsetedPosition: number[] = [autoPointPixel[0] + floatOffset[0], autoPointPixel[1] + floatOffset[1]];
const staticCoeff: number = appliedPosition != null && appliedPosition === automaticPosition ? 1 : 0.7;
const floats: PopupAlignment[] =
this._pixelToFloats(offsetedPosition, size, width / staticCoeff, height / (2 * staticCoeff));
if (floats.length === 0 &&
autoPointPixel[0] > 0 &&
autoPointPixel[0] < size.width &&
autoPointPixel[1] > 0 &&
autoPointPixel[1] < size.height) {
return [autoPointPixel, automaticPosition];
}
const minX: number = Math.max(offsetedPosition[0] - width / 2, 0);
const maxX: number = Math.min(offsetedPosition[0] + width / 2, size.width);
const minY: number = Math.max(offsetedPosition[1] - height / 2, 0);
const maxY: number = Math.min(offsetedPosition[1] + height / 2, size.height);
const visibleX: number = Math.max(0, maxX - minX);
const visibleY: number = Math.max(0, maxY - minY);
const visibleArea: number = staticCoeff * visibleX * visibleY;
if (visibleArea > largestVisibleArea[0]) {
largestVisibleArea[0] = visibleArea;
largestVisibleArea[1] = autoPointPixel;
largestVisibleArea[2] = automaticPosition;
}
}
if (largestVisibleArea[0] > 0) {
return [largestVisibleArea[1], largestVisibleArea[2]];
}
}
const pointBasic: number[] = this._pointFromRectPosition(rect, position);
const pointPixel: number[] =
this._viewportCoords.basicToCanvasSafe(
pointBasic[0],
pointBasic[1],
{ offsetHeight: size.height, offsetWidth: size.width },
transform,
renderCamera.perspective);
return [pointPixel, position != null ? position : "top"];
}