export const cssUnitCalc = (input: number | string) => { return typeof input === 'string' ? input : input + 'px'; }; export const mountContainer = (id: string) => { let node = document.getElementById(id); if (!node) { document.body.insertAdjacentHTML('beforeend', `
`); node = document.getElementById(id); } return node as HTMLElement; }; export function getTextWidth(text: string, element: HTMLElement): number { // re-use canvas object for better performance const canvas = (getTextWidth as any).canvas || ((getTextWidth as any).canvas = document.createElement('canvas')); const style: CSSStyleDeclaration = window.getComputedStyle(element); const fontMap = (getTextWidth as any).fontFamilyMap || ((getTextWidth as any).fontFamilyMap = new WeakMap()); let fontFamily; const cachedFF = fontMap.get(element); if (cachedFF) { fontFamily = cachedFF; } else { fontFamily = renderedFont(element); fontMap.set(element, fontFamily); } const context = canvas.getContext('2d'); context.font = `${style.fontSize} ${fontFamily}`; return context.measureText(text).width; } export function renderedFont(ele: HTMLElement) { var fonts: any = getComputedStyle(ele).fontFamily; var fontsArray = fonts.split(','); var canvas = document.createElement('canvas'); var ctx: any = canvas.getContext('2d'); var testString = '和那要下看天时过出小么起你都把好还多没为又abcdefghijklmnopqrstuvwxyz!@#$%^&*()ñ1234567890'; var prevImageData; document.body.appendChild(canvas); canvas.width = 500; canvas.height = 300; fontsArray.unshift('"Font That Doesnt Exists ' + Math.random() + '"'); for (var i = 0; i < fontsArray.length; i++) { var fontName = fontsArray[i].trim(); ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.font = '16px ' + fontName + ', monospace'; ctx.fillText(testString, 10, 100); var idata = ctx.getImageData(0, 0, canvas.width, canvas.height); var data = idata.data; if (prevImageData) { for (var j = 0; j < data.length; j += 3) { if (prevImageData[j + 3] !== data[j + 3]) { document.body.removeChild(canvas); return fontName; } } } prevImageData = data; } document.body.removeChild(canvas); return 'monospace'; } export const getDescendantProp = (obj: any, path: string) => path .split('.') .filter(Boolean) .reduce((acc, part) => acc && acc[part], obj); export const buildNestedObj = (obj: any, path: string, value: any) => { const pathArr = path.split('.').filter(Boolean); const lastKeyIndex = pathArr.length - 1; for (var i = 0; i < lastKeyIndex; ++i) { const key = pathArr[i]; if (!(key in obj)) obj[key] = {}; obj = obj[key]; } obj[pathArr[lastKeyIndex]] = value; return obj; }; export const getImgDimension = (file: File) => { return new Promise((resolve, reject) => { let img = new Image(); img.onload = function() { resolve({ width: img.width, height: img.height, size: file.size }); }; img.src = window.URL.createObjectURL(file); }); }; export function genUUID() { // Public Domain/MIT var d = new Date().getTime(); if (typeof performance !== 'undefined' && typeof performance.now === 'function') { d += performance.now(); //use high-precision timer if available } return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); }); } export default { downloadObjectAsJson(obj: string, filename: string) { const dataStr = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(obj, null, 4)); const a = document.createElement('a'); a.setAttribute('href', dataStr); a.setAttribute('download', filename + '.json'); document.body.appendChild(a); a.click(); a.remove(); }, getNumbersArray(max: number) { let res = []; for (let i = 0; i <= max; i++) { res.push(+i); } return res; }, concatClassNames(...args: string[]) { let res = []; for (let i = 0; i < args.length; i++) { let arr = args[i].split(' '); for (let k = 0; k < arr.length; k++) { if (arr[k] !== '') { res.push(arr[k]); } } } return res.join(' '); }, cssUnitCalc, getDescendantProp, buildNestedObj, };