linear gradients
diff --git a/extension/jsx/utils/ProjectParser.jsx b/extension/jsx/utils/ProjectParser.jsx
index f8e75a8..8b108b6 100644
--- a/extension/jsx/utils/ProjectParser.jsx
+++ b/extension/jsx/utils/ProjectParser.jsx
@@ -57,14 +57,23 @@
             bm_eventDispatcher.log(colors.toString());
             i = 0;
             len = stops.length();
-            var opacitiesArr = [],op, floats;
+            var opacitiesArr = [],op, floats, nextFloats, midPoint, midPosition;
             while(i<len){
                 floats = stops[i]['prop.list'][0]['prop.pair'][0]['array'][0].float;
                 op = [];
                 op.push(bm_generalUtils.roundNumber(Number(floats[0].toString()),3));
-                op.push(bm_generalUtils.roundNumber(Number(floats[1].toString()),3));
                 op.push(bm_generalUtils.roundNumber(Number(floats[2].toString()),3));
                 opacitiesArr.push(op);
+                midPosition = bm_generalUtils.roundNumber(Number(floats[1].toString()),3);
+                if(i<len-1 && midPosition !== 0.5){
+                    op = [];
+                    nextFloats = stops[i+1]['prop.list'][0]['prop.pair'][0]['array'][0].float;
+                    midPoint = Number(floats[0].toString()) + (Number(nextFloats[0].toString())-Number(floats[0].toString()))*midPosition;
+                    var midPointValue = Number(floats[2].toString()) + (Number(nextFloats[2].toString())-Number(floats[2].toString()))*0.5;
+                    op.push(bm_generalUtils.roundNumber(midPoint,3));
+                    op.push(bm_generalUtils.roundNumber(midPointValue,3));
+                    opacitiesArr.push(op);
+                }
                 i += 1;
             }
             i = 0;
@@ -74,12 +83,24 @@
                 floats = colors[i]['prop.list'][0]['prop.pair'][0]['array'][0].float;
                 op = [];
                 op.push(bm_generalUtils.roundNumber(Number(floats[0].toString()),3));
-                op.push(bm_generalUtils.roundNumber(Number(floats[1].toString()),3));
                 op.push(bm_generalUtils.roundNumber(Number(floats[2].toString()),3));
                 op.push(bm_generalUtils.roundNumber(Number(floats[3].toString()),3));
                 op.push(bm_generalUtils.roundNumber(Number(floats[4].toString()),3));
-                op.push(bm_generalUtils.roundNumber(Number(floats[5].toString()),3));
                 colorsArr.push(op);
+                midPosition = bm_generalUtils.roundNumber(Number(floats[1].toString()),3);
+                if(i<len-1 && midPosition !== 0.5){
+                    op = [];
+                    nextFloats = colors[i+1]['prop.list'][0]['prop.pair'][0]['array'][0].float;
+                    midPoint = Number(floats[0].toString()) + (Number(nextFloats[0].toString())-Number(floats[0].toString()))*midPosition;
+                    var midPointValueR = Number(floats[2].toString()) + (Number(nextFloats[2].toString())-Number(floats[2].toString()))*0.5;
+                    var midPointValueG = Number(floats[3].toString()) + (Number(nextFloats[3].toString())-Number(floats[3].toString()))*0.5;
+                    var midPointValueB = Number(floats[4].toString()) + (Number(nextFloats[4].toString())-Number(floats[4].toString()))*0.5;
+                    op.push(bm_generalUtils.roundNumber(midPoint,3));
+                    op.push(bm_generalUtils.roundNumber(midPointValueR,3));
+                    op.push(bm_generalUtils.roundNumber(midPointValueG,3));
+                    op.push(bm_generalUtils.roundNumber(midPointValueB,3));
+                    colorsArr.push(op);
+                }
                 i += 1;
             }
             bm_eventDispatcher.log(opacitiesArr);
diff --git a/player/index.html b/player/index.html
index c98f15c..2d7b9d9 100644
--- a/player/index.html
+++ b/player/index.html
@@ -9,8 +9,8 @@
             overflow: hidden;
         }
         #bodymovin{
-            background-color:#000;
-            width:800px;
+            background-color:#ddd;
+            width:900px;
             height:600px;
             /*width:800px;
             height:500px;*/
diff --git a/player/js/elements/ShapeElement.js b/player/js/elements/ShapeElement.js
index dd118bd..7b785b7 100644
--- a/player/js/elements/ShapeElement.js
+++ b/player/js/elements/ShapeElement.js
@@ -86,31 +86,47 @@
                 }
 
             }else if(arr[i].ty == 'gf'){
-                var clipperElem = document.createElementNS(svgNS,"clipPath");
-                    pathElement = document.createElementNS(svgNS, "path");
-                clipperElem.appendChild(pathElement);
-                var gfill = document.createElementNS(svgNS,'linearGradient');
+                pathElement = document.createElementNS(svgNS, "path");
+                var mask = document.createElementNS(svgNS,"mask");
+                var maskElement = document.createElementNS(svgNS, "path");
+                mask.appendChild(maskElement);
                 var gradientId = 'gr_'+randomString(10);
+                var opacityId = 'op_'+randomString(10);
+                var maskId = 'mk_'+randomString(10);
+                mask.setAttribute('id',maskId);
+                pathElement.setAttribute('mask','url(#'+maskId+')');
+                var gfill = document.createElementNS(svgNS,'linearGradient');
                 gfill.setAttribute('id',gradientId);
                 gfill.setAttribute('spreadMethod','pad');
                 gfill.setAttribute('gradientUnits','userSpaceOnUse');
-                gfill.setAttribute('x1','0%');
-                gfill.setAttribute('y1','0%');
-                gfill.setAttribute('x2','100%');
-                gfill.setAttribute('y2','0%');
                 var stop;
                 jLen = arr[i].c.length;
                 for(j=0;j<jLen;j+=1){
                     stop = document.createElementNS(svgNS,'stop');
                     stop.setAttribute('offset',Math.round(arr[i].c[j][0]*100)+'%');
-                    stop.setAttribute('style','stop-color:rgb('+Math.round(arr[i].c[j][2]*255)+','+Math.round(arr[i].c[j][3]*255)+','+Math.round(arr[i].c[j][4]*255)+');stop-opacity:1');
+                    stop.setAttribute('style','stop-color:rgb('+Math.round(arr[i].c[j][1]*255)+','+Math.round(arr[i].c[j][2]*255)+','+Math.round(arr[i].c[j][3]*255)+')');
                     gfill.appendChild(stop);
                 }
+                var opFill = document.createElementNS(svgNS,'linearGradient');
+                opFill.setAttribute('id',opacityId);
+                opFill.setAttribute('spreadMethod','pad');
+                opFill.setAttribute('gradientUnits','userSpaceOnUse');
+                jLen = arr[i].y.length;
+                for(j=0;j<jLen;j+=1){
+                    stop = document.createElementNS(svgNS,'stop');
+                    stop.setAttribute('offset',Math.round(arr[i].y[j][0]*100)+'%');
+                    stop.setAttribute('style','stop-color:rgb(255,255,255);stop-opacity:'+arr[i].y[j][1]);
+                    opFill.appendChild(stop);
+                }
                 pathElement.setAttribute('fill','url(#'+gradientId+')');
+                maskElement.setAttribute('fill','url(#'+opacityId+')');
                 this.globalData.defs.appendChild(gfill);
+                this.globalData.defs.appendChild(opFill);
+                this.globalData.defs.appendChild(mask);
                 data[i].s = PropertyFactory.getProp(this,arr[i].s,0,null,dynamicProperties);
                 data[i].e = PropertyFactory.getProp(this,arr[i].e,0,null,dynamicProperties);
-                data[i].g = gfill;
+                data[i].gf = gfill;
+                data[i].of = opFill;
             }else{
                 pathElement = document.createElementNS(svgNS, "path");
                 if(!data[i].c.k) {
@@ -136,6 +152,9 @@
                 ld: '',
                 mdf: false
             });
+            if(maskElement){
+                this.stylesList[this.stylesList.length - 1].maskElement = maskElement;
+            }
             data[i].style = this.stylesList[this.stylesList.length - 1];
             ownArrays.push(data[i].style);
         }else if(arr[i].ty == 'gr'){
@@ -338,6 +357,9 @@
         if(this.stylesList[i].type === 'fl' || this.stylesList[i].type === 'gf'){
             if(this.stylesList[i].mdf || this.firstFrame){
                 this.stylesList[i].pathElement.setAttribute('d',this.stylesList[i].d);
+                if(this.stylesList[i].maskElement){
+                    this.stylesList[i].maskElement.setAttribute('d',this.stylesList[i].d);
+                }
             }
         }
     }
@@ -411,14 +433,19 @@
         styleElem.pathElement.setAttribute('fill-opacity',viewData.o.v*groupTransform.opacity);
         ////styleElem.pathElement.style.fillOpacity = viewData.o.v*groupTransform.opacity;
     }
-    /*var gfill = viewData.g;
-    gfill.setAttribute('x1',viewData.s.v[0]);
-    gfill.setAttribute('y1',viewData.s.v[1]);
-    gfill.setAttribute('x2',viewData.e.v[0]);
-    gfill.setAttribute('y2',viewData.e.v[1]);*/
-    if(viewData.s.mdf || 1 === 1){
-        styleElem.pathElement.setAttribute('offset','');
-        ////styleElem.pathElement.style.fillOpacity = viewData.o.v*groupTransform.opacity;
+    var gfill = viewData.gf;
+    var opFill = viewData.of;
+    if(viewData.s.mdf || this.firstFrame){
+        gfill.setAttribute('x1',viewData.s.v[0]);
+        gfill.setAttribute('y1',viewData.s.v[1]);
+        opFill.setAttribute('x1',viewData.s.v[0]);
+        opFill.setAttribute('y1',viewData.s.v[1]);
+    }
+    if(viewData.e.mdf || this.firstFrame){
+        gfill.setAttribute('x2',viewData.e.v[0]);
+        gfill.setAttribute('y2',viewData.e.v[1]);
+        opFill.setAttribute('x2',viewData.e.v[0]);
+        opFill.setAttribute('y2',viewData.e.v[1]);
     }
 };