| 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.tt) { |
| layers[i - 1].td = layerData.tt; |
| } |
| 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 { |
| xhr.open('GET', path, true); |
| } catch (error) { |
| xhr.open('GET', 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; |