mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-15 02:17:32 +00:00
110 lines
No EOL
3.8 KiB
TypeScript
110 lines
No EOL
3.8 KiB
TypeScript
import { RecognitionZoneSource } from "./recognitionZoneSource.js";
|
|
import { ViewportZoneSource } from "./viewportZoneSource.js";
|
|
|
|
export class PaddedZoneSource implements RecognitionZoneSource {
|
|
private readonly root: RecognitionZoneSource;
|
|
|
|
private edgePadding: {
|
|
x: number,
|
|
y: number,
|
|
w: number,
|
|
h: number
|
|
};
|
|
|
|
/**
|
|
* Provides a dynamic 'padded' recognition zone based upon offsetting from the borders
|
|
* of the active page's viewport.
|
|
*
|
|
* Padding is defined using the standard CSS border & padding spec style:
|
|
* - [a]: equal and even padding on all sides
|
|
* - [a, b]: top & bottom use `a`, left & right use `b`
|
|
* - [a, b, c]: top uses `a`, left & right use `b`, bottom uses `c`
|
|
* - [a, b, c, d]: top, right, bottom, then left.
|
|
*
|
|
* Positive padding reduces the size of the resulting zone; negative padding expands it.
|
|
*
|
|
* @param rootZoneSource The root zone source object/element to be 'padded'
|
|
* @param edgePadding A set of 1 to 4 numbers defining padding per the standard CSS border & padding spec style.
|
|
*/
|
|
public constructor(...edgePadding: number[])
|
|
/**
|
|
* Provides a dynamic 'padded' recognition zone based upon offsetting from the borders
|
|
* of another defined zone.
|
|
*
|
|
* Padding is defined using the standard CSS border & padding spec style:
|
|
* - [a]: equal and even padding on all sides
|
|
* - [a, b]: top & bottom use `a`, left & right use `b`
|
|
* - [a, b, c]: top uses `a`, left & right use `b`, bottom uses `c`
|
|
* - [a, b, c, d]: top, right, bottom, then left.
|
|
*
|
|
* Positive padding reduces the size of the resulting zone; negative padding expands it.
|
|
*
|
|
* @param rootZoneSource The root zone source object/element to be 'padded'
|
|
* @param edgePadding A set of 1 to 4 numbers defining padding per the standard CSS border & padding spec style.
|
|
*/
|
|
public constructor(rootZoneSource: RecognitionZoneSource, ...edgePadding: number[]);
|
|
public constructor(rootZoneSource: RecognitionZoneSource | number, ...edgePadding: number[]) {
|
|
// Disambiguate which constructor style was intended.
|
|
if(typeof rootZoneSource == 'number') {
|
|
edgePadding = [rootZoneSource, ...edgePadding];
|
|
rootZoneSource = new ViewportZoneSource();
|
|
}
|
|
|
|
this.root = rootZoneSource;
|
|
// In case it isn't yet defined.
|
|
edgePadding = edgePadding || [0, 0, 0, 0];
|
|
|
|
// Modeled after CSS styling definitions... just with preprocessed numbers, not strings.
|
|
switch(edgePadding.length) {
|
|
case 1:
|
|
// all sides equal
|
|
const val = edgePadding[0];
|
|
this.edgePadding = {
|
|
x: val,
|
|
y: val,
|
|
w: 2 * val,
|
|
h: 2 * val
|
|
};
|
|
break;
|
|
case 2:
|
|
// top & bottom, left & right
|
|
this.edgePadding = {
|
|
x: edgePadding[1],
|
|
y: edgePadding[0],
|
|
w: 2 * edgePadding[1],
|
|
h: 2 * edgePadding[0]
|
|
};
|
|
break;
|
|
case 3:
|
|
// top, left & right, bottom
|
|
this.edgePadding = {
|
|
x: edgePadding[1],
|
|
y: edgePadding[0],
|
|
w: 2 * edgePadding[1],
|
|
h: edgePadding[0] + edgePadding[2]
|
|
};
|
|
case 4:
|
|
// top, right, bottom, left
|
|
this.edgePadding = {
|
|
x: edgePadding[3],
|
|
y: edgePadding[0],
|
|
w: edgePadding[1] + edgePadding[3],
|
|
h: edgePadding[0] + edgePadding[2]
|
|
}
|
|
break;
|
|
default:
|
|
throw new Error("Invalid values for PaddedZoneSource's edgePadding - must be between 1 to 4 `number` values.");
|
|
}
|
|
}
|
|
|
|
getBoundingClientRect(): DOMRect {
|
|
const rootZone = this.root.getBoundingClientRect();
|
|
|
|
return DOMRect.fromRect({
|
|
x: rootZone.x + this.edgePadding.x,
|
|
y: rootZone.y + this.edgePadding.y,
|
|
width: rootZone.width - this.edgePadding.w,
|
|
height: rootZone.height - this.edgePadding.h
|
|
});
|
|
}
|
|
} |