@lightningjs/renderer
Version:
Lightning 3 Renderer
267 lines • 8.43 kB
JavaScript
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2023 Comcast Cable Communications Management, LLC.
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const PROTOCOL_REGEX = /^(data|ftps?|https?):/;
export const getNormalizedRgbaComponents = (rgba) => {
const r = rgba >>> 24;
const g = (rgba >>> 16) & 0xff;
const b = (rgba >>> 8) & 0xff;
const a = rgba & 0xff;
return [r / 255, g / 255, b / 255, a / 255];
};
export const getRgbaComponents = (rgba) => {
const r = rgba >>> 24;
const g = (rgba >>> 16) & 0xff;
const b = (rgba >>> 8) & 0xff;
const a = rgba & 0xff;
return [r, g, b, a];
};
export const norm = (rgba) => {
const r = rgba >>> 24;
const g = (rgba >>> 16) & 0xff;
const b = (rgba >>> 8) & 0xff;
const a = rgba & 0xff;
const rgbaArr = [r / 255, g / 255, b / 255, a / 255];
rgbaArr[0] = Math.max(0, Math.min(255, rgbaArr[0]));
rgbaArr[1] = Math.max(0, Math.min(255, rgbaArr[1]));
rgbaArr[2] = Math.max(0, Math.min(255, rgbaArr[2]));
rgbaArr[3] = Math.max(0, Math.min(255, rgbaArr[3]));
let v = ((rgbaArr[3] | 0) << 24) +
((rgbaArr[0] | 0) << 16) +
((rgbaArr[1] | 0) << 8) +
(rgbaArr[2] | 0);
if (v < 0) {
v = 0xffffffff + v + 1;
}
return v;
};
export function getNormalizedAlphaComponent(rgba) {
return (rgba & 0xff) / 255.0;
}
/**
* Get a CSS color string from a RGBA color
*
* @param color
* @returns
*/
export function getRgbaString(color) {
const r = Math.floor(color[0] * 255.0);
const g = Math.floor(color[1] * 255.0);
const b = Math.floor(color[2] * 255.0);
const a = Math.floor(color[3] * 255.0);
return `rgba(${r},${g},${b},${a.toFixed(4)})`;
}
export function createBound(x1, y1, x2, y2, out) {
if (out) {
out.x1 = x1;
out.y1 = y1;
out.x2 = x2;
out.y2 = y2;
return out;
}
return {
x1,
y1,
x2,
y2,
};
}
export function intersectBound(a, b, out) {
const intersection = createBound(Math.max(a.x1, b.x1), Math.max(a.y1, b.y1), Math.min(a.x2, b.x2), Math.min(a.y2, b.y2), out);
if (intersection.x1 < intersection.x2 && intersection.y1 < intersection.y2) {
return intersection;
}
return createBound(0, 0, 0, 0, intersection);
}
export function boundsOverlap(a, b) {
return a.x1 < b.x2 && a.x2 > b.x1 && a.y1 < b.y2 && a.y2 > b.y1;
}
export function convertBoundToRect(bound, out) {
if (out) {
out.x = bound.x1;
out.y = bound.y1;
out.width = bound.x2 - bound.x1;
out.height = bound.y2 - bound.y1;
return out;
}
return {
x: bound.x1,
y: bound.y1,
width: bound.x2 - bound.x1,
height: bound.y2 - bound.y1,
};
}
export function intersectRect(a, b, out) {
const x = Math.max(a.x, b.x);
const y = Math.max(a.y, b.y);
const width = Math.min(a.x + a.width, b.x + b.width) - x;
const height = Math.min(a.y + a.height, b.y + b.height) - y;
if (width > 0 && height > 0) {
if (out) {
out.x = x;
out.y = y;
out.width = width;
out.height = height;
return out;
}
return {
x,
y,
width,
height,
};
}
if (out) {
out.x = 0;
out.y = 0;
out.width = 0;
out.height = 0;
return out;
}
return {
x: 0,
y: 0,
width: 0,
height: 0,
};
}
export function copyRect(a, out) {
if (out) {
out.x = a.x;
out.y = a.y;
out.width = a.width;
out.height = a.height;
return out;
}
return {
x: a.x,
y: a.y,
width: a.width,
height: a.height,
};
}
export function compareRect(a, b) {
if (a === b) {
return true;
}
if (a === null || b === null) {
return false;
}
return (a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height);
}
export function boundInsideBound(bound1, bound2) {
return (bound1.x1 <= bound2.x2 &&
bound1.y1 <= bound2.y2 &&
bound1.x2 >= bound2.x1 &&
bound1.y2 >= bound2.y1);
}
export function boundLargeThanBound(bound1, bound2) {
return (bound1.x1 < bound2.x1 &&
bound1.x2 > bound2.x2 &&
bound1.y1 < bound2.y1 &&
bound1.y2 > bound2.y2);
}
export function pointInBound(x, y, bound) {
return !(x < bound.x1 || x > bound.x2 || y < bound.y1 || y > bound.y2);
}
export function isBoundPositive(bound) {
return bound.x1 < bound.x2 && bound.y1 < bound.y2;
}
export function isRectPositive(rect) {
return rect.width > 0 && rect.height > 0;
}
/**
* Create a preload bounds from a strict bound
*
* @param strictBound The strict boundary of the node
* @param boundsMargin Boundary margin to apply to the strictBound
* @returns
*/
export function createPreloadBounds(strictBound, boundsMargin) {
return createBound(strictBound.x1 - boundsMargin[3], strictBound.y1 - boundsMargin[0], strictBound.x2 + boundsMargin[1], strictBound.y2 + boundsMargin[2]);
}
export function convertUrlToAbsolute(url) {
// handle local file imports if the url isn't remote resource or data blob
if (self.location.protocol === 'file:' && !PROTOCOL_REGEX.test(url)) {
const path = self.location.pathname.split('/');
path.pop();
const basePath = path.join('/');
const baseUrl = self.location.protocol + '//' + basePath;
// check if url has a leading dot
if (url.charAt(0) === '.') {
url = url.slice(1);
}
// check if url has a leading slash
if (url.charAt(0) === '/') {
url = url.slice(1);
}
return baseUrl + '/' + url;
}
const absoluteUrl = new URL(url, self.location.href);
return absoluteUrl.href;
}
export function isBase64Image(src) {
return src.startsWith('data:') === true;
}
export function calcFactoredRadius(radius, width, height) {
return radius * Math.min(Math.min(width, height) / (2.0 * radius), 1);
}
export function valuesAreEqual(values) {
let prevValue = values[0];
for (let i = 1; i < values.length; i++) {
if (prevValue !== values[i]) {
return false;
}
}
return true;
}
export function calcFactoredRadiusArray(radius, width, height) {
const result = [
radius[0],
radius[1],
radius[2],
radius[3],
];
const factor = Math.min(Math.min(Math.min(width / Math.max(width, radius[0] + radius[1]), width / Math.max(width, radius[2] + radius[3])), Math.min(height / Math.max(height, radius[0] + radius[3]), height / Math.max(height, radius[1] + radius[2]))), 1);
result[0] *= factor;
result[1] *= factor;
result[2] *= factor;
result[3] *= factor;
return result;
}
export function dataURIToBlob(dataURI) {
dataURI = dataURI.replace(/^data:/, '');
const type = dataURI.match(/image\/[^;]+/)?.[0] || '';
const base64 = dataURI.replace(/^[^,]+,/, '');
const sliceSize = 1024;
const byteCharacters = atob(base64);
const bytesLength = byteCharacters.length;
const slicesCount = Math.ceil(bytesLength / sliceSize);
const byteArrays = new Array(slicesCount);
for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
const begin = sliceIndex * sliceSize;
const end = Math.min(begin + sliceSize, bytesLength);
const bytes = new Array(end - begin);
for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
bytes[i] = byteCharacters[offset]?.charCodeAt(0);
}
byteArrays[sliceIndex] = new Uint8Array(bytes);
}
return new Blob(byteArrays, { type });
}
//# sourceMappingURL=utils.js.map