@applitools/utils
Version:
260 lines (259 loc) • 10.3 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.padding = exports.divide = exports.equals = exports.contains = exports.isIntersected = exports.intersect = exports.offsetNegative = exports.offset = exports.scale = exports.rotate = exports.floor = exports.ceil = exports.round = exports.isEmpty = exports.region = exports.size = exports.location = void 0;
const types = __importStar(require("./types"));
const guard = __importStar(require("./guard"));
function location(region) {
return { x: region.x, y: region.y };
}
exports.location = location;
function size(region) {
return { width: region.width, height: region.height };
}
exports.size = size;
function region(location, size) {
if (!location)
location = { x: 0, y: 0 };
return { x: location.x, y: location.y, width: size.width, height: size.height };
}
exports.region = region;
function isEmpty(sizeOrRegion) {
return sizeOrRegion.width === 0 || sizeOrRegion.height === 0;
}
exports.isEmpty = isEmpty;
function round(target) {
const result = { ...target };
if (types.has(target, ['x', 'y'])) {
result.x = Math.round(target.x);
result.y = Math.round(target.y);
}
if (types.has(target, ['width', 'height'])) {
result.width = Math.round(target.width);
result.height = Math.round(target.height);
}
return result;
}
exports.round = round;
function ceil(target) {
const result = { ...target };
if (types.has(target, ['x', 'y'])) {
// intentionally using Math.round and not Math.ceil here, because the point is that for width and height it makes sense to use ceil, but not for x and y
result.x = Math.round(target.x);
result.y = Math.round(target.y);
}
if (types.has(target, ['width', 'height'])) {
result.width = Math.ceil(target.width);
result.height = Math.ceil(target.height);
}
return result;
}
exports.ceil = ceil;
function floor(target) {
const result = { ...target };
if (types.has(target, ['x', 'y'])) {
result.x = Math.floor(target.x);
result.y = Math.floor(target.y);
}
if (types.has(target, ['width', 'height'])) {
result.width = Math.floor(target.width + (types.has(target, 'x') ? target.x - result.x : 0));
result.height = Math.floor(target.height + (types.has(target, 'y') ? target.y - result.y : 0));
}
return result;
}
exports.floor = floor;
function rotate(target, degrees, size) {
degrees = (360 + degrees) % 360;
const result = {};
if (types.has(target, ['width', 'height'])) {
// rotate size
if (degrees === 90 || degrees === 270) {
result.width = target.height;
result.height = target.width;
}
else {
result.width = target.width;
result.height = target.height;
}
}
if (types.has(target, ['x', 'y']) && size) {
const hasSize = types.has(target, ['width', 'height']);
// rotate coordinate system around a target
if (degrees === 0) {
result.x = target.x;
result.y = target.y;
}
else if (degrees === 90) {
result.x = size.height - target.y;
result.y = target.x;
if (hasSize)
result.x -= result.width;
}
else if (degrees === 180) {
result.x = size.width - target.x;
result.y = size.height - target.y;
if (hasSize) {
result.x -= result.width;
result.y -= result.height;
}
}
else if (degrees === 270) {
result.x = target.y;
result.y = size.width - target.x;
if (hasSize)
result.y -= result.height;
}
}
return result;
}
exports.rotate = rotate;
function scale(target, scaleRatio) {
const result = { ...target };
if (types.has(target, ['x', 'y'])) {
result.x = target.x * scaleRatio;
result.y = target.y * scaleRatio;
}
if (types.has(target, ['width', 'height'])) {
result.width = target.width * scaleRatio;
result.height = target.height * scaleRatio;
}
return result;
}
exports.scale = scale;
function offset(target, offset) {
const result = { ...target };
result.x += offset.x;
result.y += offset.y;
return result;
}
exports.offset = offset;
function offsetNegative(target, offset) {
const result = { ...target };
result.x -= offset.x;
result.y -= offset.y;
return result;
}
exports.offsetNegative = offsetNegative;
function intersect(region1, region2) {
if (!isIntersected(region1, region2))
return { x: 0, y: 0, width: 0, height: 0 };
const result = {};
result.x = Math.max(region1.x, region2.x);
result.y = Math.max(region1.y, region2.y);
result.width = Math.min(region1.x + region1.width, region2.x + region2.width) - result.x;
result.height = Math.min(region1.y + region1.height, region2.y + region2.height) - result.y;
return result;
}
exports.intersect = intersect;
function isIntersected(region1, region2) {
return ((region1.x <= region2.x ? region2.x < region1.x + region1.width : region1.x < region2.x + region2.width) &&
(region1.y <= region2.y ? region2.y < region1.y + region1.height : region1.y < region2.y + region2.height));
}
exports.isIntersected = isIntersected;
function contains(region, locationOrRegion) {
if (region.x <= locationOrRegion.x && region.y <= locationOrRegion.y) {
if (types.has(locationOrRegion, ['width', 'height'])) {
return (region.x + region.width >= locationOrRegion.x + locationOrRegion.width &&
region.y + region.height >= locationOrRegion.y + locationOrRegion.height);
}
return true;
}
return false;
}
exports.contains = contains;
function equals(locationOrSizeOrRegion1, locationOrSizeOrRegion2) {
if (types.has(locationOrSizeOrRegion1, ['x', 'y', 'width', 'height'])) {
if (types.has(locationOrSizeOrRegion2, ['x', 'y', 'width', 'height'])) {
return (locationOrSizeOrRegion1.x === locationOrSizeOrRegion2.x &&
locationOrSizeOrRegion1.y === locationOrSizeOrRegion2.y &&
locationOrSizeOrRegion1.width === locationOrSizeOrRegion2.width &&
locationOrSizeOrRegion1.height === locationOrSizeOrRegion2.height);
}
return false;
}
if (types.has(locationOrSizeOrRegion1, ['x', 'y'])) {
if (types.has(locationOrSizeOrRegion2, ['x', 'y'])) {
return (locationOrSizeOrRegion1.x === locationOrSizeOrRegion2.x &&
locationOrSizeOrRegion1.y === locationOrSizeOrRegion2.y);
}
return false;
}
if (types.has(locationOrSizeOrRegion1, ['width', 'height'])) {
if (types.has(locationOrSizeOrRegion2, ['width', 'height'])) {
return (locationOrSizeOrRegion1.width === locationOrSizeOrRegion2.width &&
locationOrSizeOrRegion1.height === locationOrSizeOrRegion2.height);
}
return false;
}
return false;
}
exports.equals = equals;
function divide(region, size, padding = {}) {
var _a, _b;
guard.notNull(region, { name: 'region' });
guard.notNull(size, { name: 'size' });
guard.isNumber(size.width, { name: 'size.width', gt: 0 });
guard.isNumber(size.height, { name: 'size.height', gt: 0 });
(_a = padding.top) !== null && _a !== void 0 ? _a : (padding.top = 0);
(_b = padding.bottom) !== null && _b !== void 0 ? _b : (padding.bottom = 0);
const subRegions = [];
const maxX = region.x + region.width;
const maxY = region.y + region.height;
const stepX = size.width;
const stepY = padding.top + padding.bottom < size.height ? size.height - (padding.top + padding.bottom) : size.height;
let currentY = region.y;
while (currentY < maxY) {
let nextY = Math.min(currentY + stepY, maxY);
// first region
if (currentY === region.y)
nextY += padding.top;
// last region
else if (nextY < maxY && nextY + padding.top >= maxY)
nextY = maxY;
const currentHeight = nextY - currentY;
let currentX = region.x;
while (currentX < maxX) {
const nextX = Math.min(currentX + stepX, maxX);
const currentWidth = nextX - currentX;
subRegions.push({ x: currentX, y: currentY, width: currentWidth, height: currentHeight });
currentX = nextX;
}
currentY = nextY;
}
return subRegions;
}
exports.divide = divide;
function padding(region, padding) {
var _a, _b, _c, _d, _e, _f;
if (types.isNumber(padding)) {
padding = { left: padding, right: padding, top: padding, bottom: padding };
}
region.x -= (_a = padding.left) !== null && _a !== void 0 ? _a : 0;
region.width += ((_b = padding.left) !== null && _b !== void 0 ? _b : 0) + ((_c = padding.right) !== null && _c !== void 0 ? _c : 0);
region.y -= (_d = padding.top) !== null && _d !== void 0 ? _d : 0;
region.height += ((_e = padding.top) !== null && _e !== void 0 ? _e : 0) + ((_f = padding.bottom) !== null && _f !== void 0 ? _f : 0);
return region;
}
exports.padding = padding;
;