You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
677 lines
22 KiB
677 lines
22 KiB
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;
|