import { getWebWorker } from '../main'; const dataManager = (function () { var _counterId = 1; var processes = []; var workerFn; var workerInstance; var workerProxy = { onmessage: function () { }, postMessage: function (path) { workerFn({ data: path, }); }, }; var _workerSelf = { postMessage: function (data) { workerProxy.onmessage({ data: data, }); }, }; function createWorker(fn) { if (window.Worker && window.Blob && getWebWorker()) { var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' }); // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' }); var url = URL.createObjectURL(blob); return new Worker(url); } workerFn = fn; return workerProxy; } function setupWorker() { if (!workerInstance) { workerInstance = createWorker(function workerStart(e) { function dataFunctionManager() { function completeLayers(layers, comps) { var layerData; var i; var len = layers.length; var j; var jLen; var k; var kLen; for (i = 0; i < len; i += 1) { layerData = layers[i]; if (('ks' in layerData) && !layerData.completed) { layerData.completed = true; if (layerData.hasMask) { var maskProps = layerData.masksProperties; jLen = maskProps.length; for (j = 0; j < jLen; j += 1) { if (maskProps[j].pt.k.i) { convertPathsToAbsoluteValues(maskProps[j].pt.k); } else { kLen = maskProps[j].pt.k.length; for (k = 0; k < kLen; k += 1) { if (maskProps[j].pt.k[k].s) { convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]); } if (maskProps[j].pt.k[k].e) { convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]); } } } } } if (layerData.ty === 0) { layerData.layers = findCompLayers(layerData.refId, comps); completeLayers(layerData.layers, comps); } else if (layerData.ty === 4) { completeShapes(layerData.shapes); } else if (layerData.ty === 5) { completeText(layerData); } } } } function completeChars(chars, assets) { if (chars) { var i = 0; var len = chars.length; for (i = 0; i < len; i += 1) { if (chars[i].t === 1) { // var compData = findComp(chars[i].data.refId, assets); chars[i].data.layers = findCompLayers(chars[i].data.refId, assets); // chars[i].data.ip = 0; // chars[i].data.op = 99999; // chars[i].data.st = 0; // chars[i].data.sr = 1; // chars[i].w = compData.w; // chars[i].data.ks = { // a: { k: [0, 0, 0], a: 0 }, // p: { k: [0, -compData.h, 0], a: 0 }, // r: { k: 0, a: 0 }, // s: { k: [100, 100], a: 0 }, // o: { k: 100, a: 0 }, // }; completeLayers(chars[i].data.layers, assets); } } } } function findComp(id, comps) { var i = 0; var len = comps.length; while (i < len) { if (comps[i].id === id) { return comps[i]; } i += 1; } return null; } function findCompLayers(id, comps) { var comp = findComp(id, comps); if (comp) { if (!comp.layers.__used) { comp.layers.__used = true; return comp.layers; } return JSON.parse(JSON.stringify(comp.layers)); } return null; } function completeShapes(arr) { var i; var len = arr.length; var j; var jLen; for (i = len - 1; i >= 0; i -= 1) { if (arr[i].ty === 'sh') { if (arr[i].ks.k.i) { convertPathsToAbsoluteValues(arr[i].ks.k); } else { jLen = arr[i].ks.k.length; for (j = 0; j < jLen; j += 1) { if (arr[i].ks.k[j].s) { convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]); } if (arr[i].ks.k[j].e) { convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]); } } } } else if (arr[i].ty === 'gr') { completeShapes(arr[i].it); } } } function convertPathsToAbsoluteValues(path) { var i; var len = path.i.length; for (i = 0; i < len; i += 1) { path.i[i][0] += path.v[i][0]; path.i[i][1] += path.v[i][1]; path.o[i][0] += path.v[i][0]; path.o[i][1] += path.v[i][1]; } } function checkVersion(minimum, animVersionString) { var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100]; if (minimum[0] > animVersion[0]) { return true; } if (animVersion[0] > minimum[0]) { return false; } if (minimum[1] > animVersion[1]) { return true; } if (animVersion[1] > minimum[1]) { return false; } if (minimum[2] > animVersion[2]) { return true; } if (animVersion[2] > minimum[2]) { return false; } return null; } var checkText = (function () { var minimumVersion = [4, 4, 14]; function updateTextLayer(textLayer) { var documentData = textLayer.t.d; textLayer.t.d = { k: [ { s: documentData, t: 0, }, ], }; } function iterateLayers(layers) { var i; var len = layers.length; for (i = 0; i < len; i += 1) { if (layers[i].ty === 5) { updateTextLayer(layers[i]); } } } return function (animationData) { if (checkVersion(minimumVersion, animationData.v)) { iterateLayers(animationData.layers); if (animationData.assets) { var i; var len = animationData.assets.length; for (i = 0; i < len; i += 1) { if (animationData.assets[i].layers) { iterateLayers(animationData.assets[i].layers); } } } } }; }()); var checkChars = (function () { var minimumVersion = [4, 7, 99]; return function (animationData) { if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) { var i; var len = animationData.chars.length; for (i = 0; i < len; i += 1) { var charData = animationData.chars[i]; if (charData.data && charData.data.shapes) { completeShapes(charData.data.shapes); charData.data.ip = 0; charData.data.op = 99999; charData.data.st = 0; charData.data.sr = 1; charData.data.ks = { p: { k: [0, 0], a: 0 }, s: { k: [100, 100], a: 0 }, a: { k: [0, 0], a: 0 }, r: { k: 0, a: 0 }, o: { k: 100, a: 0 }, }; if (!animationData.chars[i].t) { charData.data.shapes.push( { ty: 'no', } ); charData.data.shapes[0].it.push( { p: { k: [0, 0], a: 0 }, s: { k: [100, 100], a: 0 }, a: { k: [0, 0], a: 0 }, r: { k: 0, a: 0 }, o: { k: 100, a: 0 }, sk: { k: 0, a: 0 }, sa: { k: 0, a: 0 }, ty: 'tr', } ); } } } } }; }()); var checkPathProperties = (function () { var minimumVersion = [5, 7, 15]; function updateTextLayer(textLayer) { var pathData = textLayer.t.p; if (typeof pathData.a === 'number') { pathData.a = { a: 0, k: pathData.a, }; } if (typeof pathData.p === 'number') { pathData.p = { a: 0, k: pathData.p, }; } if (typeof pathData.r === 'number') { pathData.r = { a: 0, k: pathData.r, }; } } function iterateLayers(layers) { var i; var len = layers.length; for (i = 0; i < len; i += 1) { if (layers[i].ty === 5) { updateTextLayer(layers[i]); } } } return function (animationData) { if (checkVersion(minimumVersion, animationData.v)) { iterateLayers(animationData.layers); if (animationData.assets) { var i; var len = animationData.assets.length; for (i = 0; i < len; i += 1) { if (animationData.assets[i].layers) { iterateLayers(animationData.assets[i].layers); } } } } }; }()); var checkColors = (function () { var minimumVersion = [4, 1, 9]; function iterateShapes(shapes) { var i; var len = shapes.length; var j; var jLen; for (i = 0; i < len; i += 1) { if (shapes[i].ty === 'gr') { iterateShapes(shapes[i].it); } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') { if (shapes[i].c.k && shapes[i].c.k[0].i) { jLen = shapes[i].c.k.length; for (j = 0; j < jLen; j += 1) { if (shapes[i].c.k[j].s) { shapes[i].c.k[j].s[0] /= 255; shapes[i].c.k[j].s[1] /= 255; shapes[i].c.k[j].s[2] /= 255; shapes[i].c.k[j].s[3] /= 255; } if (shapes[i].c.k[j].e) { shapes[i].c.k[j].e[0] /= 255; shapes[i].c.k[j].e[1] /= 255; shapes[i].c.k[j].e[2] /= 255; shapes[i].c.k[j].e[3] /= 255; } } } else { shapes[i].c.k[0] /= 255; shapes[i].c.k[1] /= 255; shapes[i].c.k[2] /= 255; shapes[i].c.k[3] /= 255; } } } } function iterateLayers(layers) { var i; var len = layers.length; for (i = 0; i < len; i += 1) { if (layers[i].ty === 4) { iterateShapes(layers[i].shapes); } } } return function (animationData) { if (checkVersion(minimumVersion, animationData.v)) { iterateLayers(animationData.layers); if (animationData.assets) { var i; var len = animationData.assets.length; for (i = 0; i < len; i += 1) { if (animationData.assets[i].layers) { iterateLayers(animationData.assets[i].layers); } } } } }; }()); var checkShapes = (function () { var minimumVersion = [4, 4, 18]; function completeClosingShapes(arr) { var i; var len = arr.length; var j; var jLen; for (i = len - 1; i >= 0; i -= 1) { if (arr[i].ty === 'sh') { if (arr[i].ks.k.i) { arr[i].ks.k.c = arr[i].closed; } else { jLen = arr[i].ks.k.length; for (j = 0; j < jLen; j += 1) { if (arr[i].ks.k[j].s) { arr[i].ks.k[j].s[0].c = arr[i].closed; } if (arr[i].ks.k[j].e) { arr[i].ks.k[j].e[0].c = arr[i].closed; } } } } else if (arr[i].ty === 'gr') { completeClosingShapes(arr[i].it); } } } function iterateLayers(layers) { var layerData; var i; var len = layers.length; var j; var jLen; var k; var kLen; for (i = 0; i < len; i += 1) { layerData = layers[i]; if (layerData.hasMask) { var maskProps = layerData.masksProperties; jLen = maskProps.length; for (j = 0; j < jLen; j += 1) { if (maskProps[j].pt.k.i) { maskProps[j].pt.k.c = maskProps[j].cl; } else { kLen = maskProps[j].pt.k.length; for (k = 0; k < kLen; k += 1) { if (maskProps[j].pt.k[k].s) { maskProps[j].pt.k[k].s[0].c = maskProps[j].cl; } if (maskProps[j].pt.k[k].e) { maskProps[j].pt.k[k].e[0].c = maskProps[j].cl; } } } } } if (layerData.ty === 4) { completeClosingShapes(layerData.shapes); } } } return function (animationData) { if (checkVersion(minimumVersion, animationData.v)) { iterateLayers(animationData.layers); if (animationData.assets) { var i; var len = animationData.assets.length; for (i = 0; i < len; i += 1) { if (animationData.assets[i].layers) { iterateLayers(animationData.assets[i].layers); } } } } }; }()); function completeData(animationData) { if (animationData.__complete) { return; } checkColors(animationData); checkText(animationData); checkChars(animationData); checkPathProperties(animationData); checkShapes(animationData); completeLayers(animationData.layers, animationData.assets); completeChars(animationData.chars, animationData.assets); animationData.__complete = true; } function completeText(data) { if (data.t.a.length === 0 && !('m' in data.t.p)) { // data.singleShape = true; } } var moduleOb = {}; moduleOb.completeData = completeData; moduleOb.checkColors = checkColors; moduleOb.checkChars = checkChars; moduleOb.checkPathProperties = checkPathProperties; moduleOb.checkShapes = checkShapes; moduleOb.completeLayers = completeLayers; return moduleOb; } if (!_workerSelf.dataManager) { _workerSelf.dataManager = dataFunctionManager(); } if (!_workerSelf.assetLoader) { _workerSelf.assetLoader = (function () { function formatResponse(xhr) { // using typeof doubles the time of execution of this method, // so if available, it's better to use the header to validate the type var contentTypeHeader = xhr.getResponseHeader('content-type'); if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) { return xhr.response; } if (xhr.response && typeof xhr.response === 'object') { return xhr.response; } if (xhr.response && typeof xhr.response === 'string') { return JSON.parse(xhr.response); } if (xhr.responseText) { return JSON.parse(xhr.responseText); } return null; } function loadAsset(path, fullPath, callback, errorCallback) { var response; var xhr = new XMLHttpRequest(); // set responseType after calling open or IE will break. try { // This crashes on Android WebView prior to KitKat xhr.responseType = 'json'; } catch (err) {} // eslint-disable-line no-empty xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { response = formatResponse(xhr); callback(response); } else { try { response = formatResponse(xhr); callback(response); } catch (err) { if (errorCallback) { errorCallback(err); } } } } }; try { // Hack to workaround banner validation xhr.open(['G', 'E', 'T'].join(''), path, true); } catch (error) { // Hack to workaround banner validation xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true); } xhr.send(); } return { load: loadAsset, }; }()); } if (e.data.type === 'loadAnimation') { _workerSelf.assetLoader.load( e.data.path, e.data.fullPath, function (data) { _workerSelf.dataManager.completeData(data); _workerSelf.postMessage({ id: e.data.id, payload: data, status: 'success', }); }, function () { _workerSelf.postMessage({ id: e.data.id, status: 'error', }); } ); } else if (e.data.type === 'complete') { var animation = e.data.animation; _workerSelf.dataManager.completeData(animation); _workerSelf.postMessage({ id: e.data.id, payload: animation, status: 'success', }); } else if (e.data.type === 'loadData') { _workerSelf.assetLoader.load( e.data.path, e.data.fullPath, function (data) { _workerSelf.postMessage({ id: e.data.id, payload: data, status: 'success', }); }, function () { _workerSelf.postMessage({ id: e.data.id, status: 'error', }); } ); } }); workerInstance.onmessage = function (event) { var data = event.data; var id = data.id; var process = processes[id]; processes[id] = null; if (data.status === 'success') { process.onComplete(data.payload); } else if (process.onError) { process.onError(); } }; } } function createProcess(onComplete, onError) { _counterId += 1; var id = 'processId_' + _counterId; processes[id] = { onComplete: onComplete, onError: onError, }; return id; } function loadAnimation(path, onComplete, onError) { setupWorker(); var processId = createProcess(onComplete, onError); workerInstance.postMessage({ type: 'loadAnimation', path: path, fullPath: window.location.origin + window.location.pathname, id: processId, }); } function loadData(path, onComplete, onError) { setupWorker(); var processId = createProcess(onComplete, onError); workerInstance.postMessage({ type: 'loadData', path: path, fullPath: window.location.origin + window.location.pathname, id: processId, }); } function completeAnimation(anim, onComplete, onError) { setupWorker(); var processId = createProcess(onComplete, onError); workerInstance.postMessage({ type: 'complete', animation: anim, id: processId, }); } return { loadAnimation: loadAnimation, loadData: loadData, completeAnimation: completeAnimation, }; }()); export default dataManager;