partial
diff --git a/player/index.html b/player/index.html
index 07db12b..19bb60c 100644
--- a/player/index.html
+++ b/player/index.html
@@ -40,6 +40,6 @@
 </head>
 <body style="background-color:#666; margin: 10px;height: 100%; font-family: sans-serif;font-size: 10px">
 <div id="loader"></div>
-<div style="width:510px;height:676px;background-color:#cccccc" class="bodymovin" data-animation-path="exports/mcangel" data-bm-player="0" data-anim-type="svg" data-anim-loop="true"></div>
+<div style="width:510px;height:676px;background-color:#cccccc" class="bodymovin" data-animation-path="exports/mcangel" data-bm-player="0" data-anim-type="canvas" data-anim-loop="true"></div>
 </body>
 </html>
diff --git a/player/js/animation/AnimationItem.js b/player/js/animation/AnimationItem.js
index 4bb6b11..1e0491d 100644
--- a/player/js/animation/AnimationItem.js
+++ b/player/js/animation/AnimationItem.js
@@ -20,6 +20,7 @@
     this.isScrolling = false;
     this.loop = true;
     this.renderer = null;
+    this.animationID = randomString(10);
 };
 
 AnimationItem.prototype.setData = function (wrapper) {
@@ -60,12 +61,14 @@
 
     this.effectsManager = new EffectsManager();
     this.animationData = animData;
+    this.animationData._id = this.animationID;
+    this.animationData._animType = this.animType;
     this.layers = this.animationData.animation.layers;
     this.assets = this.animationData.assets;
     this.totalFrames = this.animationData.animation.totalFrames;
     this.frameRate = this.animationData.animation.frameRate;
     this.frameMult = this.animationData.animation.frameRate / 1000;
-    dataManager.completeData(this.layers, this.frameRate);
+    dataManager.completeData(this.animationData);
     this.renderer.buildItems(this.animationData.animation.layers);
     this.updaFrameModifier();
     this.checkLoaded();
@@ -120,7 +123,7 @@
     }
     if(!this.renderedFrames[this.currentFrame]){
         this.renderedFrames[this.currentFrame] = true;
-        dataManager.renderFrame(this.layers,this.currentFrame,this.animType);
+        dataManager.renderFrame(this.animationID,this.currentFrame);
     }
     this.renderer.renderFrame(this.currentFrame);
 };
diff --git a/player/js/elements/canvasElements/CVBaseElement.js b/player/js/elements/canvasElements/CVBaseElement.js
index b3bb1f6..47c0218 100644
--- a/player/js/elements/canvasElements/CVBaseElement.js
+++ b/player/js/elements/canvasElements/CVBaseElement.js
@@ -26,7 +26,7 @@
         this.currentAnimData = null;
         return false;
     }
-    this.currentAnimData = this.data.an[this.data.an[num].forwardFrame];
+    this.currentAnimData = this.data.renderedData[num].an;
 
     if(this.data.hasMask){
         this.maskManager.prepareFrame(num);
diff --git a/player/js/elements/canvasElements/CVShapeItemElement.js b/player/js/elements/canvasElements/CVShapeItemElement.js
index 685876e..374780e 100644
--- a/player/js/elements/canvasElements/CVShapeItemElement.js
+++ b/player/js/elements/canvasElements/CVShapeItemElement.js
@@ -22,6 +22,7 @@
         return;
     }
     var num = this.frameNum;
+    this.currentData = this.data.renderedData[num];
     var ctx = this.renderer.canvasContext;
     var flag = this.renderTransform(num);
     if(this.data.type=="pathShape"){
@@ -61,12 +62,11 @@
     this.frameNum = num;
 };
 
-CVShapeItemElement.prototype.renderTransform = function(num){
-    var animData = this.data.an;
+CVShapeItemElement.prototype.renderTransform = function(){
+    var animData = this.currentData;
     if(animData.tr){
         var ctx = this.renderer.canvasContext;
-        var tr = animData.tr[animData.tr[num].forwardFrame];
-        animData.renderedFrame.tr = tr.forwardFrame;
+        var tr = animData.tr;
         var matrixValue = tr.mtArr;
         if(matrixValue[0] == 1 && matrixValue[1] == 0 && matrixValue[2] == 0 && matrixValue[3] == 1 && matrixValue[4] == 0 && matrixValue[5] == 0 && tr.o >= 1){
             return false;
@@ -180,15 +180,14 @@
 };
 
 CVShapeItemElement.prototype.renderPath = function(num){
-    var animData = this.data.an;
-    var path = animData.path[animData.path[num].forwardFrame];
+    var animData = this.currentData;
+    var path = animData.path;
 
     if(this.renderedPaths[num]){
         return;
     }
     var path2d = new Path2D();
 
-    animData.renderedFrame.path = path.pathString;
     var ctx = this.renderer.canvasContext;
 
     var pathNodes = path.pathNodes;
@@ -214,7 +213,6 @@
 CVShapeItemElement.prototype.renderEllipse = function(num){
     var animData = this.data.an;
     var ell = animData.ell[animData.ell[num].forwardFrame];
-    animData.renderedFrame.ell = ell.forwardFrame;
 
     var ctx = this.renderer.canvasContext;
 
@@ -249,10 +247,9 @@
 };
 
 CVShapeItemElement.prototype.renderFill = function(num){
-    var animData = this.data.an;
+    var animData = this.currentData;
     if(animData.fill){
-        var fill = animData.fill[animData.fill[num].forwardFrame];
-        animData.renderedFrame.fill = {color:fill.color,opacity:fill.opacity};
+        var fill = animData.fill;
         if(this.data.fillEnabled!==false){
             if(fill.opacity < 1){
                 this.renderer.canvasContext.fillStyle=fillToRgba(fill.color, fill.opacity);
@@ -266,10 +263,9 @@
 };
 
 CVShapeItemElement.prototype.renderStroke = function(num){
-    var animData = this.data.an;
+    var animData = this.currentData;
     if(animData.stroke){
-        var stroke = animData.stroke[animData.stroke[num].forwardFrame];
-        animData.renderedFrame.stroke = stroke.forwardFrame;
+        var stroke = animData.stroke;
         /*ctx.strokeStyle="red";
          */
         this.renderer.canvasContext.lineWidth=stroke.width;
diff --git a/player/js/renderers/CanvasRenderer.js b/player/js/renderers/CanvasRenderer.js
index cbea694..2dfcb2e 100644
--- a/player/js/renderers/CanvasRenderer.js
+++ b/player/js/renderers/CanvasRenderer.js
@@ -36,7 +36,7 @@
 
 CanvasRenderer.prototype.createComp = function (data) {
     data.element = new CVCompElement(data, this);
-    this.buildItems(data.layers, data.element.getType());
+    this.buildItems(data.layers);
 };
 
 CanvasRenderer.prototype.createSolid = function (data) {
diff --git a/player/js/utils/DataManager.js b/player/js/utils/DataManager.js
index 45b9167..85d168b 100644
--- a/player/js/utils/DataManager.js
+++ b/player/js/utils/DataManager.js
@@ -1,7 +1,7 @@
-var dataManager = (function(){
+function dataFunctionManager(){
     var frameRate = 0;
     var matrixInstance =  new MatrixManager();
-    var storedBezierCurves = {};
+    var animations = {};
 
     function completeTimeRemap(tm, layerFrames, offsetFrame){
         var interpolatedProperty = getInterpolatedValues(tm,layerFrames, offsetFrame);
@@ -23,6 +23,7 @@
                 layerData.parent = convertLayerNameToID(layerData.parent);
             }
             layerData.renderedFrame = {};
+            layerData.renderedData = {};
             animArray = [];
             lastFrame = -1;
             if(layerData.tm){
@@ -30,13 +31,20 @@
             }
             if(layerData.type=='PreCompLayer'){
                 completeLayers(layerData.layers);
+            }else if(layerData.type == 'ShapeLayer'){
+                var i, len = layerData.shapes.length;
+                for(i=0;i<len;i+=1){
+                    shapeItem = layerData.shapes[i];
+                    shapeItem.renderedData = {};
+                }
             }
         })
     }
 
-    function completeData(layers, fRate){
-        frameRate = fRate;
-        completeLayers(layers);
+    function completeData(animationData){
+        animations[animationData._id] = animationData;
+        frameRate = animationData.animation.frameRate;
+        completeLayers(animationData.animation.layers);
     }
 
     function convertLayerNameToID(string){
@@ -389,7 +397,7 @@
     var fillOpacity,fillColor, shape, strokeColor, strokeOpacity, strokeWidth, elmPos, elmSize, elmRound;
     var shapeTrOb = {};
 
-    function iterateLayers(layers, frameNum,renderType){
+    function iterateLayers(layers, frameNum,renderType, rendered){
 
         var offsettedFrameNum, i, len;
         var j, jLen = layers.length, item;
@@ -397,9 +405,11 @@
             item = layers[j];
             offsettedFrameNum = frameNum - item.startTime;
             if(frameNum < item.inPoint || frameNum > item.outPoint){
+                rendered.push('');
                 continue;
             }
             if(item.an[offsettedFrameNum]){
+                rendered.push('');
                 continue;
             }
             trOb = {};
@@ -413,7 +423,8 @@
             trOb.s = scale instanceof Array ? scale.length > 1 ? [scale[0]/100,scale[1]/100,scale[2]/100] : [scale[0]/100,scale[0]/100,scale[0]/100] : [scale/100,scale/100,scale/100];
             trOb.r = rot instanceof Array ? rot.length > 1 ? [rot[0]*Math.PI/180,rot[1]*Math.PI/180,rot[2]*Math.PI/180] : [rot[0]*Math.PI/180,rot[0]*Math.PI/180,rot[0]*Math.PI/180] : [0,0,rot*Math.PI/180];
             trOb.p = pos;
-            item.an[offsettedFrameNum] = {
+            rendered[j] = {};
+            rendered[j].an = {
                 forwardFrame : offsettedFrameNum,
                 tr: dataOb,
                 matrixValue: matrixInstance.getMatrix2(trOb),
@@ -439,10 +450,13 @@
             }
             if(item.type == 'PreCompLayer'){
                 timeRemapped = item.tm ? item.tm[offsettedFrameNum] < 0 ? 0 : item.tm[offsettedFrameNum] : offsettedFrameNum;
-                iterateLayers(item.layers,timeRemapped,renderType);
+                rendered.renderedArray = [];
+                iterateLayers(item.layers,timeRemapped,renderType,rendered.renderedArray);
             }else if(item.type == 'ShapeLayer'){
+                rendered[j].shapes = [];
                 len = item.shapes.length;
                 for(i=0;i<len;i+=1){
+                    rendered[j].shapes.push({});
                     shapeItem = item.shapes[i];
                     if(!shapeItem._created){
                         shapeItem.an.tr = [];
@@ -467,7 +481,7 @@
                     if(shapeItem.fl){
                         fillColor = getInterpolatedValue(shapeItem.fl.c,offsettedFrameNum, item.startTime);
                         fillOpacity = getInterpolatedValue(shapeItem.fl.o,offsettedFrameNum, item.startTime);
-                        shapeItem.an.fill[offsettedFrameNum] = {
+                        rendered[j].shapes[i].fill = {
                             color : rgbToHex(Math.round(fillColor[0]),Math.round(fillColor[1]),Math.round(fillColor[2])),
                             opacity : fillOpacity instanceof Array ? fillOpacity[0]/100 : fillOpacity/100,
                             forwardFrame : offsettedFrameNum
@@ -475,18 +489,18 @@
                     }
                     if(shapeItem.ks){
                         shape = getInterpolatedValue(shapeItem.ks,offsettedFrameNum, item.startTime);
-                        shapeItem.an.path[offsettedFrameNum] = {
+                        rendered[j].shapes[i].path = {
                             pathNodes: shape,
                             closed: shapeItem.closed,
                             forwardFrame : offsettedFrameNum
                         };
                         if(renderType == 'svg'){
-                            shapeItem.an.path[offsettedFrameNum].pathString = createPathString(shape,shapeItem.closed);
+                            rendered[j].shapes[i].path.pathString = createPathString(shape,shapeItem.closed);
                         }
                     }else if(shapeItem.el){
                         elmPos = getInterpolatedValue(shapeItem.el.p,offsettedFrameNum, item.startTime);
                         elmSize = getInterpolatedValue(shapeItem.el.s,offsettedFrameNum, item.startTime);
-                        shapeItem.an.ell[offsettedFrameNum] = {
+                        rendered[j].shapes[i].ell = {
                             p : elmPos,
                             size : elmSize,
                             forwardFrame : offsettedFrameNum
@@ -495,7 +509,7 @@
                         elmPos = getInterpolatedValue(shapeItem.rc.p,offsettedFrameNum, item.startTime);
                         elmSize = getInterpolatedValue(shapeItem.rc.s,offsettedFrameNum, item.startTime);
                         elmRound = getInterpolatedValue(shapeItem.rc.r,offsettedFrameNum, item.startTime);
-                        shapeItem.an.rect[offsettedFrameNum] = {
+                        rendered[j].shapes[i].rect = {
                             position : elmPos,
                             size : elmSize,
                             roundness : elmRound,
@@ -506,7 +520,7 @@
                         strokeColor = getInterpolatedValue(shapeItem.st.c,offsettedFrameNum, item.startTime);
                         strokeOpacity = getInterpolatedValue(shapeItem.st.o,offsettedFrameNum, item.startTime);
                         strokeWidth = getInterpolatedValue(shapeItem.st.w,offsettedFrameNum, item.startTime);
-                        shapeItem.an.stroke[offsettedFrameNum] = {
+                        rendered[j].shapes[i].stroke = {
                             color : rgbToHex(Math.round(strokeColor[0]),Math.round(strokeColor[1]),Math.round(strokeColor[2])),
                             opacity : strokeOpacity instanceof Array ? strokeOpacity[0]/100 : strokeOpacity/100,
                             width : strokeWidth instanceof Array ? strokeWidth[0] : strokeWidth,
@@ -527,12 +541,13 @@
                     shapeTrOb.mtArr = matrixInstance.getMatrixArray(shapeTrOb);
                     shapeTrOb.forwardFrame = offsettedFrameNum;
                     shapeItem.an.tr[offsettedFrameNum] = shapeTrOb;
+                    rendered[j].shapes[i].tr = shapeTrOb;
 
                     if(shapeItem.trim){
                         var trimS = getInterpolatedValue(shapeItem.trim.s,offsettedFrameNum, item.startTime);
                         var trimE = getInterpolatedValue(shapeItem.trim.e,offsettedFrameNum, item.startTime);
                         var trimO = getInterpolatedValue(shapeItem.trim.o,offsettedFrameNum, item.startTime);
-                        shapeItem.trim.an[offsettedFrameNum] = {
+                        rendered[j].shapes[i].trim = {
                             s: trimS,
                             e: trimE,
                             o: trimO,
@@ -547,8 +562,33 @@
         }
     }
 
-    function renderFrame(layers,num, renderType){
-        iterateLayers(layers, num, renderType);
+    function renderFrame(animationId,num){
+        var renderedArray = [];
+        iterateLayers(animations[animationId].animation.layers, num, animations[animationId]._animType, renderedArray);
+        populateLayers(animations[animationId].animation.layers, num,renderedArray);
+    }
+
+    function populateLayers(layers, num, rendered){
+        var i, len = layers.length, j, jLen;
+        var offsettedFrameNum, timeRemapped;
+        var shapes;
+        for(i=0;i<len;i+=1){
+            if(rendered[i] == ''){
+                continue;
+            }
+            offsettedFrameNum = num - layers[i].startTime;
+            layers[i].renderedData[offsettedFrameNum] = rendered[i];
+            if(layers[i].type == 'PreCompLayer'){
+                timeRemapped = layers[i].tm ? layers[i].tm[offsettedFrameNum] < 0 ? 0 : layers[i].tm[offsettedFrameNum] : offsettedFrameNum;
+                populateLayers(layers[i].layers,timeRemapped,rendered.renderedArray);
+            }else if(layers[i].type == 'ShapeLayer'){
+                shapes = layers[i].shapes;
+                jLen = shapes.length;
+                for(j=0;j<jLen;j+=1){
+                    shapes[j].renderedData[offsettedFrameNum] = rendered[i].shapes[j];
+                }
+            }
+        }
     }
 
     var moduleOb = {};
@@ -556,4 +596,49 @@
     moduleOb.renderFrame = renderFrame;
 
     return moduleOb;
-}());
\ No newline at end of file
+};
+if(Worker && 1 == 2){
+    function handleEvents(){
+        self.onmessage = function(e){
+            var data = e.data;
+            if(data.message == 'new'){
+                dataManager.completeData(data.animation);
+            }
+            self.postMessage("new anim created");
+        }
+    }
+// URL.createObjectURL
+    window.URL = window.URL || window.webkitURL;
+// Build a worker from an anonymous function body
+    var blobURL = URL.createObjectURL( new Blob([
+            handleEvents.toString(),
+            matrixManagerFunction.toString(),
+            'var MatrixManager = matrixManagerFunction;',
+
+            dataFunctionManager.toString(),
+            Matrix.toString(),
+
+            'var dataManager = dataFunctionManager();handleEvents();' ], { type: 'application/javascript' } ) ),
+
+        worker = new Worker( blobURL );
+// Won't be needing this anymore
+    URL.revokeObjectURL( blobURL );
+
+    worker.addEventListener('message',function(e){
+        console.log('mensaje', e.data);
+    })
+    var dataManager = function(){
+        function completeData(animationData){
+            worker.postMessage({message:'new',animation:animationData});
+        }
+        function renderFrame(num){
+
+        }
+        return {
+            completeData: completeData
+        }
+    }();
+
+}else{
+    var dataManager = dataFunctionManager();
+}
\ No newline at end of file
diff --git a/player/js/utils/MatrixManager.js b/player/js/utils/MatrixManager.js
index 9a57e1c..9e5ac33 100644
--- a/player/js/utils/MatrixManager.js
+++ b/player/js/utils/MatrixManager.js
@@ -1,4 +1,4 @@
-var MatrixManager = function(){
+function matrixManagerFunction(){
 
     var mat = new Matrix();
 
@@ -135,4 +135,5 @@
         getMatrixArray : getMatrixArray
     }
 
-};
\ No newline at end of file
+};
+var MatrixManager = matrixManagerFunction;
\ No newline at end of file