UNPKG

@lightningjs/renderer

Version:
267 lines 8.43 kB
/* * 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