partial
diff --git a/gulpfile.js b/gulpfile.js
index ae3a2af..62595db 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -158,6 +158,6 @@
             'player/js/module.js'
         ])
         .pipe(concat('concat.js', {newLine: '\r\n'}))
-        .pipe(wrap('\'use strict\';\r\n(function(){\r\n<%= contents %>\r\n}());'))
+        .pipe(wrap('\r\n(function(){\r\n\'use strict\';\r\n<%= contents %>\r\n}());'))
         .pipe(gulp.dest('build/player/'))
 });
\ No newline at end of file
diff --git a/player/index.html b/player/index.html
index ec01d29..1f9d66e 100644
--- a/player/index.html
+++ b/player/index.html
@@ -36,6 +36,6 @@
     <!-- endbuild -->
 </head>
 <body style="background-color:#666; margin: 0px;height: 100%; font-family: sans-serif;font-size: 10px">
-<div style="width:600px;height:300px;background-color:#000;display:inline-block" class="bodymovin" data-bm-path="exports/gear" data-bm-type="svg" data-bm-loop="false" data-bm-prerender="true"></div>
+<div style="width:690px;height:913px;background-color:#000;display:inline-block" class="bodymovin" data-bm-path="exports/gear" data-bm-type="svg" data-bm-loop="true" data-bm-prerender="true"></div>
 </body>
 </html>
diff --git a/player/js/animation/AnimationItem.js b/player/js/animation/AnimationItem.js
index aad5c07..d461e21 100644
--- a/player/js/animation/AnimationItem.js
+++ b/player/js/animation/AnimationItem.js
@@ -125,7 +125,7 @@
     this.frameRate = this.animationData.animation.frameRate;
     this.frameMult = this.animationData.animation.frameRate / 1000;
     dataManager.completeData(this.animationData);
-    this.renderer.buildItems(this.animationData.animation.layers);
+    this.renderer.buildItems(this.animationData.animation.layers,this.container);
     this.updaFrameModifier();
     this.checkLoaded();
 };
diff --git a/player/js/elements/BaseElement.js b/player/js/elements/BaseElement.js
index 5e13cfc..fd921be 100644
--- a/player/js/elements/BaseElement.js
+++ b/player/js/elements/BaseElement.js
@@ -1,9 +1,13 @@
-var BaseElement = function (data, animationItem){
+var BaseElement = function (data, animationItem,parentContainer){
     this.animationItem = animationItem;
     this.data = data;
-    this.transformChanged = false;
     this.forceRender = false;
-    this.currentMatrix = new Matrix();
+    this.ownMatrix = new Matrix();
+    this.finalTransform = {
+        mat: new Matrix(),
+        op: 1
+    };
+    this.parentContainer = parentContainer;
     this.init();
 };
 
@@ -18,35 +22,37 @@
 };
 
 BaseElement.prototype.createElements = function(){
-    this.layerElement = document.createElementNS(svgNS,'g');
-    this.layerElement.setAttribute('id',this.data.layerName);
+    if(this.data.hasMask){
+        this.layerElement = document.createElementNS(svgNS,'g');
+    }else{
+        this.layerElement = this.parentContainer;
+    }
     this.maskingGroup = this.layerElement;
     this.maskedElement = this.layerElement;
 };
 
 BaseElement.prototype.prepareFrame = function(num){
     this.currentAnimData = this.data.renderedData[num].an;
-    if(this.data.renderedFrame.tr !== this.currentAnimData.matrixValue){
-        this.transformChanged = true;
-        this.data.renderedFrame.tr = this.currentAnimData.matrixValue;
-    }else{
-        this.transformChanged = false;
-    }
+    this.data.renderedFrame.tr = this.currentAnimData.matrixValue;
+    var mat = this.currentAnimData.matrixArray;
+    this.ownMatrix.reset();
+    this.ownMatrix.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5]);
+    this.ownMatrix.translate(-this.currentAnimData.tr.a[0],-this.currentAnimData.tr.a[1]);
 };
 
-BaseElement.prototype.renderFrame = function(num){
+BaseElement.prototype.renderFrame = function(num,parentTransform){
     if(this.data.inPoint - this.data.startTime <= num && this.data.outPoint - this.data.startTime > num)
     {
         if(this.isVisible !== true){
             this.isVisible = true;
             this.forceRender = true;
-            this.mainElement.setAttribute('opacity',1);
         }
+        this.finalTransform.opacity = 1;
     }else{
         if(this.isVisible !== false){
             this.isVisible = false;
-            this.mainElement.setAttribute('opacity',0);
         }
+        this.finalTransform.opacity = 0;
     }
 
     if(this.data.eff){
@@ -61,58 +67,37 @@
         this.maskManager.renderFrame(num);
     }
 
-    if(this.data.renderedFrame.o !== this.currentAnimData.tr.o){
-        this.data.renderedFrame.o = this.currentAnimData.tr.o;
-        if(this.isVisible){
-            this.layerElement.setAttribute('opacity',this.currentAnimData.tr.o);
-        }
+    this.finalTransform.opacity *= this.currentAnimData.tr.o;
+
+    if(parentTransform){
+        this.finalTransform.mat.reset();
+        mat = parentTransform.mat.props;
+        this.finalTransform.mat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5]);
+        this.finalTransform.opacity *= parentTransform.opacity;
     }
 
-    var transformValue = '';
-
-
     if(this.data.parents){
-        var changedFlag = false;
-        var i = 0, len = this.data.parents.length, parentAnimData;
-        if(!this.transformChanged){
-            while(i<len){
-                if(this.data.parents[i].elem.element.transformChanged){
-                    changedFlag = true;
-                    break;
-                }
-                i+=1;
-            }
-        }else{
-            changedFlag = true;
+        var i, len = this.data.parents.length, parentAnimData,mat;
+        if(!parentTransform){
+            this.finalTransform.mat.reset();
         }
-        if(changedFlag){
-            for(i=len-1;i>=0;i-=1){
-                parentAnimData = this.data.parents[i].elem.element.currentAnimData;
-                transformValue += parentAnimData.matrixValue + ' ';
-            }
-            transformValue += this.currentAnimData.matrixValue;
-            if(this.isVisible){
-                this.layerElement.setAttribute('transform',transformValue);
-            }
-            this.fullTransform = transformValue;
+        for(i=len-1;i>=0;i-=1){
+            mat = this.data.parents[i].elem.element.ownMatrix.props;
+            this.finalTransform.mat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5]);
+            parentAnimData = this.data.parents[i].elem.element.currentAnimData;
         }
-    }else if(this.transformChanged){
-        transformValue += this.currentAnimData.matrixValue;
+        mat = this.ownMatrix.props;
+        this.finalTransform.mat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5]);
+    }else{
         if(this.isVisible){
-            var mat = this.currentAnimData.matrixArray;
-            this.currentMatrix.reset();
-            this.currentMatrix.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5]);
-            this.currentMatrix.translate(-this.currentAnimData.tr.a[0],-this.currentAnimData.tr.a[1]);
-            //this.layerElement.setAttribute('transform',transformValue);
+            if(!parentTransform){
+                this.finalTransform.mat = this.ownMatrix;
+            }else{
+                mat = this.ownMatrix.props;
+                this.finalTransform.mat.transform(mat[0],mat[1],mat[2],mat[3],mat[4],mat[5]);
+            }
         }
-        this.fullTransform = transformValue;
     }
-    if(this.forceRender){
-        this.forceRender = false;
-        this.layerElement.setAttribute('opacity',this.currentAnimData.tr.o);
-        //this.layerElement.setAttribute('transform',this.fullTransform);
-    }
-
 
     return this.isVisible;
 };
diff --git a/player/js/elements/CompElement.js b/player/js/elements/CompElement.js
index d375452..96551b8 100644
--- a/player/js/elements/CompElement.js
+++ b/player/js/elements/CompElement.js
@@ -1,21 +1,15 @@
-function ICompElement(data, animationItem){
-    this.parent.constructor.call(this,data, animationItem);
+function ICompElement(data, animationItem,parentContainer){
+    this.parent.constructor.call(this,data, animationItem,parentContainer);
     this.layers = data.layers;
 }
 createElement(BaseElement, ICompElement);
 
-ICompElement.prototype.createElements = function(){
-
-    this.svgElem = document.createElementNS (svgNS, "g");
-    this.parent.createElements.call(this);
-};
-
 ICompElement.prototype.getComposingElement = function(){
     return this.layerElement;
 };
 
-ICompElement.prototype.renderFrame = function(num){
-    var renderParent = this.parent.renderFrame.call(this,num);
+ICompElement.prototype.renderFrame = function(num,parentMatrix){
+    var renderParent = this.parent.renderFrame.call(this,num,parentMatrix);
     if(renderParent===false){
         return;
     }
@@ -26,6 +20,6 @@
         this.layers[i].element.prepareFrame(timeRemapped - this.layers[i].startTime);
     }
     for( i = 0; i < len; i+=1 ){
-        this.layers[i].element.renderFrame(timeRemapped - this.layers[i].startTime);
+        this.layers[i].element.renderFrame(timeRemapped - this.layers[i].startTime,this.finalTransform);
     }
 };
\ No newline at end of file
diff --git a/player/js/elements/ImageElement.js b/player/js/elements/ImageElement.js
index 50afe0b..f51de21 100644
--- a/player/js/elements/ImageElement.js
+++ b/player/js/elements/ImageElement.js
@@ -1,8 +1,8 @@
-function IImageElement(data, animationItem){
+function IImageElement(data, animationItem,parentContainer){
     this.animationItem = animationItem;
     this.assets = this.animationItem.getAssets();
     this.path = this.animationItem.getPath();
-    this.parent.constructor.call(this,data, animationItem);
+    this.parent.constructor.call(this,data, animationItem,parentContainer);
 }
 createElement(BaseElement, IImageElement);
 
@@ -20,16 +20,13 @@
     img.addEventListener('load', imageLoaded, false);
     img.src = this.path+this.assets[this.data.assetId].path;
 
-    this.svgElem = document.createElementNS(svgNS, "g");
-
     this.parent.createElements.call(this);
 
     this.image = document.createElementNS(svgNS,'image');
     this.image.setAttribute('width',this.data.width+"px");
     this.image.setAttribute('height',this.data.height+"px");
-    this.svgElem.appendChild(this.image);
-    this.layerElement.appendChild(this.svgElem);
-    this.maskingGroup = this.svgElem;
+    this.layerElement.appendChild(this.image);
+    this.maskingGroup = this.image;
     styleUnselectableDiv(this.image);
 
 };
\ No newline at end of file
diff --git a/player/js/elements/ShapeElement.js b/player/js/elements/ShapeElement.js
index 914d090..342d783 100644
--- a/player/js/elements/ShapeElement.js
+++ b/player/js/elements/ShapeElement.js
@@ -1,6 +1,6 @@
-function IShapeElement(data, animationItem){
+function IShapeElement(data, animationItem,parentContainer){
     this.shapes = [];
-    this.parent.constructor.call(this,data, animationItem);
+    this.parent.constructor.call(this,data, animationItem,parentContainer);
 }
 createElement(BaseElement, IShapeElement);
 
@@ -19,21 +19,36 @@
     }
 };
 
-IShapeElement.prototype.renderFrame = function(num){
-    var renderParent = this.parent.renderFrame.call(this,num);
+IShapeElement.prototype.renderFrame = function(num,parentMatrix){
+    var renderParent = this.parent.renderFrame.call(this,num,parentMatrix);
     if(renderParent===false){
+        if(!this.hidden){
+            this.hideShapes();
+        }
         return;
     }
 
     this.renderShapes(num);
 };
 
-IShapeElement.prototype.renderShapes = function(num){
+IShapeElement.prototype.hideShapes = function(){
     var i,len = this.data.shapes.length,shapeData;
     var shapeItem;
     for(i=len-1;i>=0;i--){
         shapeData = this.data.shapes[i];
         shapeItem = this.shapes[len - 1 - i];
-        shapeItem.renderShape(num,this.currentMatrix);
+        shapeItem.hideShape();
+    }
+    this.hidden = true;
+};
+
+IShapeElement.prototype.renderShapes = function(num){
+    this.hidden = false;
+    var i,len = this.data.shapes.length,shapeData;
+    var shapeItem;
+    for(i=len-1;i>=0;i--){
+        shapeData = this.data.shapes[i];
+        shapeItem = this.shapes[len - 1 - i];
+        shapeItem.renderShape(num,this.finalTransform);
     }
 };
\ No newline at end of file
diff --git a/player/js/elements/ShapeItemElement.js b/player/js/elements/ShapeItemElement.js
index 058fa18..c896ccf 100644
--- a/player/js/elements/ShapeItemElement.js
+++ b/player/js/elements/ShapeItemElement.js
@@ -14,6 +14,12 @@
     var ownArrays = [];
     for(i=len;i>=0;i-=1){
         if(arr[i].ty == 'fl' || arr[i].ty == 'st'){
+            arr[i].renderedFrames = [];
+            arr[i].lastData = {
+                c: '',
+                o:'',
+                w: ''
+            };
             this.stylesList.push({
                 elements: [],
                 type: arr[i].ty,
@@ -24,9 +30,18 @@
         }else if(arr[i].ty == 'gr'){
             this.searchShapes(arr[i].it);
         }else if(arr[i].ty == 'tr'){
-            arr[i].matrix = new Matrix();
+            arr[i].transform = {
+                mat: new Matrix(),
+                opacity: 1
+            };
         }else if(arr[i].ty == 'sh'){
             arr[i].elements = [];
+            arr[i].renderedFrames = [];
+            arr[i].lastData = {
+                d: '',
+                o:'',
+                tr:''
+            };
             jLen = this.stylesList.length;
             for(j=0;j<jLen;j+=1){
                 if(!this.stylesList[j].closed){
@@ -34,11 +49,27 @@
                     arr[i].elements.push(pathNode);
                     this.shape.appendChild(pathNode);
                     this.stylesList[j].elements.push(pathNode);
+                    if(this.stylesList[j].type == 'st'){
+                        pathNode.setAttribute('fill-opacity',0);
+                        pathNode.setAttribute('stroke-linejoin','round');
+                        pathNode.setAttribute('stroke-linecap','round');
+                    }
                 }
             }
 
         }else if(arr[i].ty == 'rc'){
             arr[i].elements = [];
+            arr[i].renderedFrames = [];
+            arr[i].lastData = {
+                roundness: '',
+                w: '',
+                h: '',
+                x: '',
+                y:'',
+                o:'',
+                tr:''
+            };
+            arr[i].renderedFrames = [];
             jLen = this.stylesList.length;
             for(j=0;j<jLen;j+=1){
                 if(!this.stylesList[j].closed){
@@ -46,11 +77,23 @@
                     arr[i].elements.push(pathNode);
                     this.shape.appendChild(pathNode);
                     this.stylesList[j].elements.push(pathNode);
+                    if(this.stylesList[j].type == 'st'){
+                        pathNode.setAttribute('fill-opacity',0);
+                    }
                 }
             }
 
         }else if(arr[i].ty == 'el'){
             arr[i].elements = [];
+            arr[i].renderedFrames = [];
+            arr[i].lastData = {
+                cx: '',
+                cy: '',
+                rx: '',
+                ry: '',
+                o:'',
+                tr:''
+            };
             jLen = this.stylesList.length;
             for(j=0;j<jLen;j+=1){
                 if(!this.stylesList[j].closed){
@@ -58,6 +101,9 @@
                     arr[i].elements.push(pathNode);
                     this.shape.appendChild(pathNode);
                     this.stylesList[j].elements.push(pathNode);
+                    if(this.stylesList[j].type == 'st'){
+                        pathNode.setAttribute('fill-opacity',0);
+                    }
                 }
             }
 
@@ -66,7 +112,6 @@
     len = ownArrays.length;
     for(i=0;i<len;i+=1){
         ownArrays[i].closed = true;
-        console.log('ownArrays[i]: ',ownArrays[i]);
     }
 };
 
@@ -74,156 +119,253 @@
     return this.shape;
 };
 
-ShapeItemElement.prototype.renderShape = function(num,matrix,items){
+ShapeItemElement.prototype.hideShape = function(){
+    var i, len = this.stylesList.length;
+    var j, jLen;
+    var elements;
+    for(i=0;i<len;i+=1){
+        elements = this.stylesList[i].elements;
+        jLen = elements.length;
+        for(j=0;j<jLen;j+=1){
+            elements[j].setAttribute('opacity','0');
+        }
+    }
+};
+
+ShapeItemElement.prototype.renderShape = function(num,parentTransform,items){
     if(!items){
         items = this.data;
     }
     this.posCount = 0;
     this.frameNum = num;
     var i, len;
-    var j, jLen;
-    var styleElem;
     len = items.length - 1;
-    var groupMatrix;
+    var groupTransform,groupMatrix;
     for(i=len;i>=0;i-=1){
         if(items[i].ty == 'tr'){
-            var props = matrix.props;
+            var props = parentTransform.mat.props;
             var mtArr = items[i].renderedData[num].mtArr;
-            groupMatrix = items[i].matrix;
+            groupTransform = items[i].transform;
+            groupTransform.opacity = parentTransform.opacity;
+            groupTransform.opacity *= items[i].renderedData[num].o;
+            groupMatrix = groupTransform.mat;
             groupMatrix.reset().transform(props[0],props[1],props[2],props[3],props[4],props[5]).transform(mtArr[0],mtArr[1],mtArr[2],mtArr[3],mtArr[4],mtArr[5]).translate(-items[i].renderedData[num].a[0],-items[i].renderedData[num].a[1]);
         }else if(items[i].ty == 'sh'){
-            this.renderPath(items[i],num,groupMatrix);
+            this.renderPath(items[i],num,groupTransform);
         }else if(items[i].ty == 'el'){
-            this.renderEllipse(items[i],num,groupMatrix);
+            this.renderEllipse(items[i],num,groupTransform);
         }else if(items[i].ty == 'rc'){
-            this.renderRect(items[i],num,groupMatrix);
+            this.renderRect(items[i],num,groupTransform);
         }else if(items[i].ty == 'fl'){
-            styleElem = items[i].style;
-            jLen = styleElem.elements.length;
-            for(j=0;j<jLen;j+=1){
-                styleElem.elements[j].setAttribute('fill',items[i].renderedData[num].color);
-                styleElem.elements[j].setAttribute('fill-opacity',items[i].renderedData[num].opacity);
-            }
+            this.renderFill(items[i],num);
         }else if(items[i].ty == 'st'){
-            styleElem = items[i].style;
-            jLen = styleElem.elements.length;
-            for(j=0;j<jLen;j+=1){
-                styleElem.elements[j].setAttribute('stroke-width',items[i].renderedData[num].width);
-                styleElem.elements[j].setAttribute('stroke',items[i].renderedData[num].color);
-                styleElem.elements[j].setAttribute('stroke-opacity',items[i].renderedData[num].opacity);
-                styleElem.elements[j].setAttribute('fill-opacity',0);
-            }
+            this.renderStroke(items[i],num);
         }else if(items[i].ty == 'gr'){
-            this.renderShape(num,this.currentMatrix,items[i].it);
+            this.renderShape(num,groupTransform,items[i].it);
         }
     }
 };
 
-ShapeItemElement.prototype.renderPath = function(pathData,num,matrix){
-    if(!pathData.renderedFrames){
-        pathData.renderedFrames = [];
+ShapeItemElement.prototype.renderPath = function(pathData,num,transform){
+    if(!pathData.renderedFrames[num]){
+        pathData.renderedFrames[num] = {
+            d: pathData.renderedData[num].path.pathString,
+            tr: 'matrix('+transform.mat.props.join(',')+')',
+            o: transform.opacity
+        };
     }
-    var pathString = '';
-    if(pathData.renderedFrames[num]){
-        pathString = pathData.renderedFrames[num];
-    }else{
-        pathString = pathData.renderedData[num].path.pathString;
-        pathData.renderedFrames[num] = pathString;
-    }
+    var pathString = pathData.renderedFrames[num].d;
+    var transformString = pathData.renderedFrames[num].tr;
+    var opacity = pathData.renderedFrames[num].o;
     var elements = pathData.elements;
     var i, len = elements.length;
     for(i=0;i<len;i+=1){
-        //this.stylesList[i].d += pathData.path.pathString;
-        elements[i].setAttribute('d',pathString);
-        elements[i].setAttribute('transform','matrix('+matrix.props.join(',')+')');
+        if(pathData.lastData.d != pathString){
+            elements[i].setAttribute('d',pathString);
+        }
+        if(pathData.lastData.tr != transformString){
+            elements[i].setAttribute('transform',transformString);
+        }
+        if(pathData.lastData.o != opacity){
+            elements[i].setAttribute('opacity',opacity);
+        }
     }
+    pathData.lastData.d = pathString;
+    pathData.lastData.tr = transformString;
+    pathData.lastData.o = opacity;
 };
 
 
-ShapeItemElement.prototype.renderEllipse = function(ellipseData,num,matrix){
-    // cx="40" cy="40" rx="30" ry="15"
-
+ShapeItemElement.prototype.renderEllipse = function(ellipseData,num,transform){
+    var ellipseAttrs = ellipseData.renderedData[num];
+    if(!ellipseData.renderedFrames[num]){
+        ellipseData.renderedFrames[num] = {
+            cx: ellipseAttrs.p[0],
+            cy: ellipseAttrs.p[1],
+            rx: ellipseAttrs.size[0]/2,
+            ry: ellipseAttrs.size[1]/2,
+            tr: 'matrix('+transform.mat.props.join(',')+')',
+            o: transform.opacity
+        };
+    }
+    var cx = ellipseData.renderedFrames[num].cx;
+    var cy = ellipseData.renderedFrames[num].cy;
+    var rx = ellipseData.renderedFrames[num].rx;
+    var ry = ellipseData.renderedFrames[num].ry;
+    var tr = ellipseData.renderedFrames[num].tr;
+    var o = ellipseData.renderedFrames[num].o;
 
     var elements = ellipseData.elements;
-    var ellipseAttrs = ellipseData.renderedData[num];
-    console.log(ellipseAttrs);
     var i, len = elements.length;
     for(i=0;i<len;i+=1){
-        elements[i].setAttribute('cx',ellipseAttrs.p[0]);
-        elements[i].setAttribute('cy',ellipseAttrs.p[1]);
-        elements[i].setAttribute('rx',ellipseAttrs.size[0]/2);
-        elements[i].setAttribute('ry',ellipseAttrs.size[1]/2);
-        //elements[i].setAttribute('transform','matrix('+matrix.props.join(',')+')');
+        if(ellipseData.lastData.cx != cx){
+            elements[i].setAttribute('cx',cx);
+        }
+        if(ellipseData.lastData.cy != cy){
+            elements[i].setAttribute('cy',cy);
+        }
+        if(ellipseData.lastData.rx != rx){
+            elements[i].setAttribute('rx',rx);
+        }
+        if(ellipseData.lastData.ry != ry){
+            elements[i].setAttribute('ry',ry);
+        }
+        if(ellipseData.lastData.tr != tr){
+            elements[i].setAttribute('transform',tr);
+        }
+        if(ellipseData.lastData.o != o){
+            elements[i].setAttribute('opacity',o);
+        }
     }
+    ellipseData.lastData.cx = cx;
+    ellipseData.lastData.cy = cy;
+    ellipseData.lastData.rx = rx;
+    ellipseData.lastData.ry = ry;
+    ellipseData.lastData.tr = tr;
+    ellipseData.lastData.o = o;
 };
 
-ShapeItemElement.prototype.renderRect = function(rectData,num,matrix){
+ShapeItemElement.prototype.renderRect = function(rectData,num,transform){
     var elements = rectData.elements;
-    var ellipseAttrs = rectData.renderedData[num];
-    var animData = this.currentData;
+    var rectAttrs = rectData.renderedData[num];
+    var roundness;
+    if(!rectData.renderedFrames[num]){
+        roundness = rectAttrs.roundness;
+
+        if(roundness > rectAttrs.size[0]/2){
+            roundness = rectAttrs.size[0]/2;
+        }
+        if(roundness > rectAttrs.size[1]/2){
+            roundness = rectAttrs.size[1]/2;
+        }
+        rectData.renderedFrames[num] = {
+            round: roundness,
+            w: rectAttrs.size[0],
+            h: rectAttrs.size[1],
+            x: rectAttrs.position[0] - rectAttrs.size[0]/2,
+            y: rectAttrs.position[1] - rectAttrs.size[1]/2,
+            tr: 'matrix('+transform.mat.props.join(',')+')',
+            o: transform.opacity
+        };
+    }
+    roundness = rectData.renderedFrames[num].round;
+    var w = rectData.renderedFrames[num].w;
+    var h = rectData.renderedFrames[num].h;
+    var x = rectData.renderedFrames[num].x;
+    var y = rectData.renderedFrames[num].y;
+    var tr = rectData.renderedFrames[num].tr;
+    var o = rectData.renderedFrames[num].o;
     var i, len = elements.length;
     for(i=0;i<len;i+=1){
-        elements[i].setAttribute('rx',ellipseAttrs.roundness);
-        elements[i].setAttribute('ry',ellipseAttrs.roundness);
-        elements[i].setAttribute('width',ellipseAttrs.size[0]);
-        elements[i].setAttribute('height',ellipseAttrs.size[1]);
-        elements[i].setAttribute('x',ellipseAttrs.position[0] - ellipseAttrs.size[0]/2);
-        elements[i].setAttribute('y',ellipseAttrs.position[1] - ellipseAttrs.size[1]/2);
-        //elements[i].setAttribute('transform','matrix('+matrix.props.join(',')+')');
+        if(rectData.lastData.roundness != roundness){
+            elements[i].setAttribute('rx',roundness);
+            elements[i].setAttribute('ry',roundness);
+        }
+        if(rectData.lastData.w != w){
+            elements[i].setAttribute('width',w);
+        }
+        if(rectData.lastData.h != h){
+            elements[i].setAttribute('height',h);
+        }
+        if(rectData.lastData.x != x){
+            elements[i].setAttribute('x',x);
+        }
+        if(rectData.lastData.y != y){
+            elements[i].setAttribute('y',y);
+        }
+        if(rectData.lastData.tr != tr){
+            elements[i].setAttribute('transform',tr);
+        }
+        if(rectData.lastData.o != o){
+            elements[i].setAttribute('opacity',o);
+        }
     }
+    rectData.lastData.roundness = roundness;
+    rectData.lastData.w = w;
+    rectData.lastData.h = h;
+    rectData.lastData.x = x;
+    rectData.lastData.y = y;
+    rectData.lastData.o = o;
 };
 
-ShapeItemElement.prototype.renderFill = function(num){
-    var animData = this.currentData;
-    if(animData.fill){
-        var fill = animData.fill;
-        if(this.renderedFrame.fill.color !== fill.color){
-            this.shape.setAttribute('fill',fill.color);
-            this.renderedFrame.fill.color = fill.color;
-        }
-        if(this.data.fillEnabled!==false){
-            if(this.renderedFrame.fill.opacity !== fill.opacity){
-                this.shape.setAttribute('fill-opacity',fill.opacity);
-                this.renderedFrame.fill.opacity = fill.opacity;
-            }
-        }else{
-            if(this.renderedFrame.fill.opacity !== 0){
-                this.shape.setAttribute('fill-opacity',0);
-                this.renderedFrame.fill.opacity = 0;
-            }
-        }
-    }else{
-        if(this.renderedFrame.fill.opacity !== 0){
-            this.shape.setAttribute('fill-opacity',0);
-            this.renderedFrame.fill.opacity = 0;
+ShapeItemElement.prototype.renderFill = function(styleData,num){
+    var fillData = styleData.renderedData[num];
+    var styleElem = styleData.style;
+    if(!styleData.renderedFrames[num]){
+        styleData.renderedFrames[num] = {
+            c: fillData.color,
+            o: fillData.opacity
         }
     }
+
+    var c = styleData.renderedFrames[num].c;
+    var o = styleData.renderedFrames[num].o;
+
+    var elements = styleElem.elements;
+    var i, len = elements.length;
+    for(i=0;i<len;i+=1){
+        if(styleData.lastData.c != c){
+            elements[i].setAttribute('fill',c);
+        }
+        if(styleData.lastData.o != o){
+            elements[i].setAttribute('fill-opacity',o);
+        }
+    }
+    styleData.lastData.c = c;
+    styleData.lastData.o = o;
 };
 
-ShapeItemElement.prototype.renderStroke = function(num){
-    var animData = this.currentData;
-    if(animData.stroke){
-        var stroke = animData.stroke;
-        if(this.renderedFrame.stroke.color !== stroke.color){
-            this.renderedFrame.stroke.color = stroke.color;
-            this.shape.setAttribute('stroke',stroke.color);
-        }
-        if(this.renderedFrame.stroke.width !== stroke.width){
-            this.renderedFrame.stroke.width = stroke.width;
-            this.shape.setAttribute('stroke-width',stroke.width);
-        }
-        if(this.data.strokeEnabled!==false){
-            if(this.renderedFrame.stroke.opacity !== stroke.opacity){
-                this.renderedFrame.stroke.opacity = stroke.opacity;
-                this.shape.setAttribute('stroke-opacity',stroke.opacity);
-            }
-        }else{
-            if(this.renderedFrame.stroke.opacity !== 0){
-                this.renderedFrame.stroke.opacity = 0;
-                this.shape.setAttribute('stroke-opacity',0);
-            }
+ShapeItemElement.prototype.renderStroke = function(styleData,num){
+    var fillData = styleData.renderedData[num];
+    var styleElem = styleData.style;
+    if(!styleData.renderedFrames[num]){
+        styleData.renderedFrames[num] = {
+            c: fillData.color,
+            o: fillData.opacity,
+            w: fillData.width
         }
     }
+
+    var c = styleData.renderedFrames[num].c;
+    var o = styleData.renderedFrames[num].o;
+    var w = styleData.renderedFrames[num].w;
+
+    var elements = styleElem.elements;
+    var i, len = elements.length;
+    for(i=0;i<len;i+=1){
+        if(styleData.lastData.c != c){
+            elements[i].setAttribute('stroke',c);
+        }
+        if(styleData.lastData.o != o){
+            elements[i].setAttribute('stroke-opacity',o);
+        }
+        if(styleData.lastData.o != o){
+            elements[i].setAttribute('stroke-width',w);
+        }
+    }
+    styleData.lastData.c = c;
+    styleData.lastData.o = o;
+    styleData.lastData.w = w;
 };
 
 ShapeItemElement.prototype.renderTransform = function(num){
diff --git a/player/js/elements/SolidElement.js b/player/js/elements/SolidElement.js
index f183d3a..7cf3e1a 100644
--- a/player/js/elements/SolidElement.js
+++ b/player/js/elements/SolidElement.js
@@ -1,12 +1,10 @@
-function ISolidElement(data, animationItem){
-    this.parent.constructor.call(this,data, animationItem);
+function ISolidElement(data, animationItem,parentContainer){
+    this.parent.constructor.call(this,data, animationItem,parentContainer);
 }
 createElement(BaseElement, ISolidElement);
 
 ISolidElement.prototype.createElements = function(){
-    this.svgElem = document.createElementNS (svgNS, "g");
     this.parent.createElements.call(this);
-    this.layerElement.appendChild(this.svgElem);
 
     var rect = document.createElementNS(svgNS,'rect');
     rect.setAttribute('width',this.data.width);
@@ -14,10 +12,8 @@
     /*rect.setAttribute('width',1);
     rect.setAttribute('height',1);*/
     rect.setAttribute('fill',this.data.color);
-    this.svgElem.appendChild(rect);
-    styleUnselectableDiv(this.svgElem);
-    styleUnselectableDiv(rect);
+    this.layerElement.appendChild(rect);
 
-    this.maskingGroup = this.svgElem;
+    this.maskingGroup = rect;
     this.maskedElement = rect;
 };
\ No newline at end of file
diff --git a/player/js/elements/TextElement.js b/player/js/elements/TextElement.js
index 0b25e39..5d1b0ec 100644
--- a/player/js/elements/TextElement.js
+++ b/player/js/elements/TextElement.js
@@ -1,5 +1,5 @@
-function ITextElement(data, animationItem){
-    this.parent.constructor.call(this,data, animationItem);
+function ITextElement(data, animationItem,parentContainer){
+    this.parent.constructor.call(this,data, animationItem,parentContainer);
 }
 createElement(BaseElement, ITextElement);
 
diff --git a/player/js/renderers/SVGRenderer.js b/player/js/renderers/SVGRenderer.js
index a2a8f90..5b2d02b 100644
--- a/player/js/renderers/SVGRenderer.js
+++ b/player/js/renderers/SVGRenderer.js
@@ -4,45 +4,45 @@
     this.lastFrame = -1;
 }
 
-SVGRenderer.prototype.buildItems = function(layers){
+SVGRenderer.prototype.buildItems = function(layers,parentContainer){
     var count = 0, i, len = layers.length;
-    for (i = 0; i < len; i++) {
+    for (i = len - 1; i >= 0; i--) {
         if (layers[i].type == 'StillLayer') {
             count++;
-            this.createImage(layers[i]);
+            this.createImage(layers[i],parentContainer);
         } else if (layers[i].type == 'PreCompLayer') {
-            this.createComp(layers[i]);
+            this.createComp(layers[i],parentContainer);
         } else if (layers[i].type == 'SolidLayer') {
-            this.createSolid(layers[i]);
+            this.createSolid(layers[i],parentContainer);
         } else if (layers[i].type == 'ShapeLayer') {
-            this.createShape(layers[i]);
+            this.createShape(layers[i],parentContainer);
         } else if (layers[i].type == 'TextLayer') {
-            this.createText(layers[i]);
+            this.createText(layers[i],parentContainer);
         }else{
             console.log('NO TYPE: ',layers[i]);
         }
     }
 };
 
-SVGRenderer.prototype.createShape = function (data) {
-    data.element = new IShapeElement(data, this.animationItem);
+SVGRenderer.prototype.createShape = function (data,parentContainer) {
+    data.element = new IShapeElement(data, this.animationItem,parentContainer);
 };
 
-SVGRenderer.prototype.createText = function (data) {
-    data.element = new ITextElement(data, this.animationItem);
+SVGRenderer.prototype.createText = function (data,parentContainer) {
+    data.element = new ITextElement(data, this.animationItem,parentContainer);
 };
 
-SVGRenderer.prototype.createImage = function (data) {
-    data.element = new IImageElement(data, this.animationItem);
+SVGRenderer.prototype.createImage = function (data,parentContainer) {
+    data.element = new IImageElement(data, this.animationItem,parentContainer);
 };
 
-SVGRenderer.prototype.createComp = function (data) {
-    data.element = new ICompElement(data, this.animationItem);
-    this.buildItems(data.layers, data.element.getType());
+SVGRenderer.prototype.createComp = function (data,parentContainer) {
+    data.element = new ICompElement(data, this.animationItem,parentContainer);
+    this.buildItems(data.layers,data.element.getDomElement());
 };
 
-SVGRenderer.prototype.createSolid = function (data) {
-    data.element = new ISolidElement(data, this.animationItem);
+SVGRenderer.prototype.createSolid = function (data,parentContainer) {
+    data.element = new ISolidElement(data, this.animationItem,parentContainer);
 };
 
 SVGRenderer.prototype.configAnimation = function(animData){
@@ -76,19 +76,24 @@
 };
 
 SVGRenderer.prototype.buildStage = function (container, layers) {
-    var i, len = layers.length, layerData;
+    var i, len = layers.length, layerData,mainContainer;
     for (i = len - 1; i >= 0; i--) {
         layerData = layers[i];
         if (layerData.parent) {
             this.buildItemParenting(layerData,layers,layerData.parent);
-            var mainContainer = layerData.element.getDomElement();
-            mainContainer.setAttribute("data-layer-name", layerData.layerName);
-            container.appendChild(mainContainer);
+            mainContainer = layerData.element.getDomElement();
+            if(container != mainContainer){
+                mainContainer.setAttribute("data-layer-name", layerData.layerName);
+                container.appendChild(mainContainer);
+            }
             layerData.element.setMainElement(mainContainer);
         } else {
-            layerData.element.getDomElement().setAttribute("data-layer-name", layerData.layerName);
-            container.appendChild(layerData.element.getDomElement());
-            layerData.element.setMainElement(layerData.element.getDomElement());
+            mainContainer = layerData.element.getDomElement();
+            if(container != mainContainer){
+                mainContainer.setAttribute("data-layer-name", layerData.layerName);
+                container.appendChild(mainContainer);
+            }
+            layerData.element.setMainElement(mainContainer);
         }
         if (layerData.type == 'PreCompLayer') {
             this.buildStage(layerData.element.getComposingElement(), layerData.layers, layerData.element.getType());
diff --git a/player/js/utils/DataManager.js b/player/js/utils/DataManager.js
index 9132ee2..87d08e5 100644
--- a/player/js/utils/DataManager.js
+++ b/player/js/utils/DataManager.js
@@ -121,9 +121,9 @@
                 if(arr[i].ks.i){
                     convertPathsToAbsoluteValues(arr[i].ks);
                 }else{
-                    jLen = shapeItem[i].ks.length;
+                    jLen = arr[i].ks.length;
                     for(j=0;j<jLen;j+=1){
-                        if(shapeItem[i].ks[j].s){
+                        if(arr[i].ks[j].s){
                             convertPathsToAbsoluteValues(arr[i].ks[j].s[0]);
                             convertPathsToAbsoluteValues(arr[i].ks[j].e[0]);
                         }
@@ -340,7 +340,7 @@
                 return [keyframes];
             }
             return keyframes;
-        }else if(keyframes[0].t === null){
+        }else if(keyframes[0].t === undefined){
             if(interpolatedParams.type == 'p'){
                 matrixParams.px = keyframes[0];
                 matrixParams.py = keyframes[1];
@@ -383,10 +383,10 @@
         }
         var k, kLen;
         var perc,jLen, j = 0;
+        var fnc;
         if(interpolatedParams.type == 'default'){
             propertyArray = [];
         }
-        var fnc;
         if(keyData.to){
             bezierData = keyData.bezierData;
             if(frameNum >= nextKeyData.t-offsetTime){
@@ -720,8 +720,8 @@
                     }
                 }
                 if(renderType == 'svg'){
-                    //pathData.pathString = createPathString(propertyArray[0],pathData.closed);
-                    pathData.pathNodes = propertyArray[0];
+                    pathData.pathString = createPathString(propertyArray[0],pathData.closed);
+                    //pathData.pathNodes = propertyArray[0];
                 }else{
                     pathData.pathNodes = propertyArray[0];
                 }