gradient fills finnished
diff --git a/extension/jsx/utils/ProjectParser.jsx b/extension/jsx/utils/ProjectParser.jsx index 8b108b6..11ae643 100644 --- a/extension/jsx/utils/ProjectParser.jsx +++ b/extension/jsx/utils/ProjectParser.jsx
@@ -54,15 +54,17 @@ //bm_eventDispatcher.log(XML_Ob['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair'].length()); var stops = XML_Ob['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair']; var colors = XML_Ob['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair'][1]['prop.list'][0]['prop.pair'][0]['prop.list'][0]['prop.pair']; - bm_eventDispatcher.log(colors.toString()); i = 0; len = stops.length(); - var opacitiesArr = [],op, floats, nextFloats, midPoint, midPosition; + var opacitiesArr = [],op, floats, nextFloats, midPoint, midPosition, hasOpacity = false; 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[2].toString()),3)); + if(op[1] !== 1){ + hasOpacity = true; + } opacitiesArr.push(op); midPosition = bm_generalUtils.roundNumber(Number(floats[1].toString()),3); if(i<len-1 && midPosition !== 0.5){ @@ -76,6 +78,9 @@ } i += 1; } + if(!hasOpacity){ + opacitiesArr.length = 0; + } i = 0; len = colors.length(); var colorsArr = []; @@ -103,8 +108,6 @@ } i += 1; } - bm_eventDispatcher.log(opacitiesArr); - bm_eventDispatcher.log(colorsArr); gradientData.c = colorsArr; gradientData.o = opacitiesArr; //var jsonData = bm_xml2json(XML_Ob);
diff --git a/extension/jsx/utils/shapeHelper.jsx b/extension/jsx/utils/shapeHelper.jsx index fc7e4c9..cdd3b37 100644 --- a/extension/jsx/utils/shapeHelper.jsx +++ b/extension/jsx/utils/shapeHelper.jsx
@@ -9,6 +9,7 @@ star: 'sr', fill: 'fl', gfill: 'gf', + gStroke: 'sf', stroke: 'st', merge: 'mm', trim: 'tm', @@ -43,6 +44,8 @@ return shapeItemTypes.group; case 'ADBE Vector Graphic - G-Fill': return shapeItemTypes.gfill; + case 'ADBE Vector Graphic - G-Stroke': + return shapeItemTypes.gStroke; default: bm_eventDispatcher.log(matchName); return ''; @@ -154,6 +157,28 @@ ob.e = bm_keyframeHelper.exportKeyframes(prop.property('End Point'), frameRate); ob.o = bm_keyframeHelper.exportKeyframes(prop.property('Opacity'), frameRate); ob.t = prop.property('Type').value; + if(ob.t === 2){ + ob.h = bm_keyframeHelper.exportKeyframes(prop.property('Highlight Length'), frameRate); + ob.a = bm_keyframeHelper.exportKeyframes(prop.property('Highlight Angle'), frameRate); + } + + } else if (itemType === shapeItemTypes.gStroke) { + ob = {}; + ob.ty = itemType; + var gradientData = bm_ProjectHelper.getGradientData(navigationShapeTree); + ob.c = gradientData.c; + ob.y = gradientData.o; + ob.s = bm_keyframeHelper.exportKeyframes(prop.property('Start Point'), frameRate); + ob.e = bm_keyframeHelper.exportKeyframes(prop.property('End Point'), frameRate); + ob.o = bm_keyframeHelper.exportKeyframes(prop.property('Opacity'), frameRate); + ob.w = bm_keyframeHelper.exportKeyframes(prop.property('Stroke Width'), frameRate); + ob.lc = prop.property('Line Cap').value; + ob.lj = prop.property('Line Join').value; + ob.t = prop.property('Type').value; + if(ob.t === 2){ + ob.h = bm_keyframeHelper.exportKeyframes(prop.property('Highlight Length'), frameRate); + ob.a = bm_keyframeHelper.exportKeyframes(prop.property('Highlight Angle'), frameRate); + } } else if (itemType === shapeItemTypes.stroke) { ob = {};
diff --git a/player/index.html b/player/index.html index 2d7b9d9..336da80 100644 --- a/player/index.html +++ b/player/index.html
@@ -10,8 +10,8 @@ } #bodymovin{ background-color:#ddd; - width:900px; - height:600px; + width:1000px; + height:400px; /*width:800px; height:500px;*/ display:block;
diff --git a/player/js/elements/ShapeElement.js b/player/js/elements/ShapeElement.js index 7b785b7..cc01bcd 100644 --- a/player/js/elements/ShapeElement.js +++ b/player/js/elements/ShapeElement.js
@@ -87,15 +87,15 @@ }else if(arr[i].ty == 'gf'){ 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'); + var gfill,opFill; + if(arr[i].t === 1){ + gfill = document.createElementNS(svgNS,'linearGradient'); + } else { + gfill = document.createElementNS(svgNS,'radialGradient'); + data[i].h = PropertyFactory.getProp(this,arr[i].h,1,0.01,dynamicProperties); + data[i].a = PropertyFactory.getProp(this,arr[i].a,1,degToRads,dynamicProperties); + } gfill.setAttribute('id',gradientId); gfill.setAttribute('spreadMethod','pad'); gfill.setAttribute('gradientUnits','userSpaceOnUse'); @@ -107,26 +107,39 @@ 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); + if(arr[i].y.length){ + var mask = document.createElementNS(svgNS,"mask"); + var maskElement = document.createElementNS(svgNS, "path"); + mask.appendChild(maskElement); + var opacityId = 'op_'+randomString(10); + var maskId = 'mk_'+randomString(10); + mask.setAttribute('id',maskId); + pathElement.setAttribute('mask','url(#'+maskId+')'); + if(arr[i].t === 1){ + opFill = document.createElementNS(svgNS,'linearGradient'); + } else { + opFill = document.createElementNS(svgNS,'radialGradient'); + } + 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); + } + maskElement.setAttribute('fill','url(#'+opacityId+')'); + this.globalData.defs.appendChild(opFill); + this.globalData.defs.appendChild(mask); + data[i].of = opFill; + } + data[i].s = PropertyFactory.getProp(this,arr[i].s,1,null,dynamicProperties); + data[i].e = PropertyFactory.getProp(this,arr[i].e,1,null,dynamicProperties); data[i].gf = gfill; - data[i].of = opFill; }else{ pathElement = document.createElementNS(svgNS, "path"); if(!data[i].c.k) { @@ -435,17 +448,58 @@ } 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]); + if(styleData.t === 1){ + if(viewData.s.mdf || this.firstFrame){ + gfill.setAttribute('x1',viewData.s.v[0]); + gfill.setAttribute('y1',viewData.s.v[1]); + if(opFill){ + 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]); + if(opFill){ + opFill.setAttribute('x2',viewData.e.v[0]); + opFill.setAttribute('y2',viewData.e.v[1]); + } + } + } else { + if(viewData.s.mdf || this.firstFrame){ + gfill.setAttribute('cx',viewData.s.v[0]); + gfill.setAttribute('cy',viewData.s.v[1]); + if(opFill){ + opFill.setAttribute('cx',viewData.s.v[0]); + opFill.setAttribute('cy',viewData.s.v[1]); + } + } + var rad; + if(viewData.s.mdf || viewData.e.mdf || this.firstFrame){ + rad = Math.sqrt(Math.pow(viewData.s.v[0]-viewData.e.v[0],2)+Math.pow(viewData.s.v[1]-viewData.e.v[1],2)); + gfill.setAttribute('r',rad); + if(opFill){ + opFill.setAttribute('r',rad); + } + } + if(viewData.e.mdf || viewData.h.mdf || viewData.a.mdf || this.firstFrame){ + if(!rad){ + rad = Math.sqrt(Math.pow(viewData.s.v[0]-viewData.e.v[0],2)+Math.pow(viewData.s.v[1]-viewData.e.v[1],2)); + } + var ang = Math.atan2(viewData.e.v[1]-viewData.s.v[1], viewData.e.v[0]-viewData.s.v[0]); + + var percent = viewData.h.v >= 1 ? 0.99 : viewData.h.v; + var dist = rad*percent; + var x = Math.cos(ang + viewData.a.v)*dist + viewData.s.v[0]; + var y = Math.sin(ang + viewData.a.v)*dist + viewData.s.v[1]; + gfill.setAttribute('fx',x); + gfill.setAttribute('fy',y); + if(opFill){ + opFill.setAttribute('fx',x); + opFill.setAttribute('fy',y); + } + } + //gfill.setAttribute('fy','200'); } };
diff --git a/player/js/elements/canvasElements/CVShapeElement.js b/player/js/elements/canvasElements/CVShapeElement.js index f141134..14de064 100644 --- a/player/js/elements/canvasElements/CVShapeElement.js +++ b/player/js/elements/canvasElements/CVShapeElement.js
@@ -34,15 +34,17 @@ var j, jLen; var ownArrays = [], ownModifiers = [], styleElem; for(i=len;i>=0;i-=1){ - if(arr[i].ty == 'fl' || arr[i].ty == 'st'){ + if(arr[i].ty == 'fl' || arr[i].ty == 'st' || arr[i].ty == 'gf'){ styleElem = { type: arr[i].ty, elements: [] }; data[i] = {}; - data[i].c = PropertyFactory.getProp(this,arr[i].c,1,255,dynamicProperties); - if(!data[i].c.k){ - styleElem.co = 'rgb('+bm_floor(data[i].c.v[0])+','+bm_floor(data[i].c.v[1])+','+bm_floor(data[i].c.v[2])+')'; + if(arr[i].ty == 'fl' || arr[i].ty == 'st'){ + data[i].c = PropertyFactory.getProp(this,arr[i].c,1,255,dynamicProperties); + if(!data[i].c.k){ + styleElem.co = 'rgb('+bm_floor(data[i].c.v[0])+','+bm_floor(data[i].c.v[1])+','+bm_floor(data[i].c.v[2])+')'; + } } data[i].o = PropertyFactory.getProp(this,arr[i].o,0,0.01,dynamicProperties); if(arr[i].ty == 'st') { @@ -64,6 +66,15 @@ } } + } else if(arr[i].ty == 'gf') { + data[i].s = PropertyFactory.getProp(this,arr[i].s,1,null,dynamicProperties); + data[i].e = PropertyFactory.getProp(this,arr[i].e,1,null,dynamicProperties); + if(arr[i].t === 2){ + data[i].h = PropertyFactory.getProp(this,arr[i].h,1,0.01,dynamicProperties); + data[i].a = PropertyFactory.getProp(this,arr[i].a,1,degToRads,dynamicProperties); + } + styleElem.c = arr[i].c; + } this.stylesList.push(styleElem); data[i].style = styleElem; @@ -213,6 +224,8 @@ this.renderPath(items[i],data[i],groupTransform); }else if(items[i].ty == 'fl'){ this.renderFill(items[i],data[i],groupTransform); + }else if(items[i].ty == 'gf'){ + this.renderGFill(items[i],data[i],groupTransform); }else if(items[i].ty == 'st'){ this.renderStroke(items[i],data[i],groupTransform); }else if(items[i].ty == 'gr'){ @@ -230,18 +243,30 @@ renderer.ctxTransform(this.finalTransform.mat.props); for(i=0;i<len;i+=1){ type = this.stylesList[i].type; + if(type === 'gf'){ + ctx.save(); + + } if(type === 'st' && this.stylesList[i].wi === 0){ continue; } renderer.save(); elems = this.stylesList[i].elements; - jLen = elems.length; if(type === 'st'){ ctx.strokeStyle = this.stylesList[i].co; ctx.lineWidth = this.stylesList[i].wi; ctx.lineCap = this.stylesList[i].lc; ctx.lineJoin = this.stylesList[i].lj; ctx.miterLimit = this.stylesList[i].ml || 0; + }else if(type === 'gf'){ + var grad = ctx.createLinearGradient(this.stylesList[i].x1,this.stylesList[i].y1,this.stylesList[i].x2,this.stylesList[i].y2); + jLen = this.stylesList[i].c.length; + j = 0; + while(j<jLen){ + grad.addColorStop(this.stylesList[i].c[j][0],"rgb("+Math.round(this.stylesList[i].c[j][1]*255)+","+Math.round(this.stylesList[i].c[j][2]*255)+","+Math.round(this.stylesList[i].c[j][3]*255)+")"); + j += 1; + } + ctx.fillStyle = grad; }else{ ctx.fillStyle = this.stylesList[i].co; } @@ -249,6 +274,7 @@ if(type !== 'st'){ ctx.beginPath(); } + jLen = elems.length; for(j=0;j<jLen;j+=1){ if(type === 'st'){ ctx.beginPath(); @@ -280,6 +306,29 @@ if(type !== 'st'){ ctx.fill(); } + if(type === 'gf'){ + ctx.globalCompositeOperation = 'destination-in'; + jLen = elems.length; + for(j=0;j<jLen;j+=1){ + nodes = elems[j].trNodes; + kLen = nodes.length; + + for(k=0;k<kLen;k+=1){ + if(nodes[k].t == 'm'){ + ctx.moveTo(nodes[k].p[0],nodes[k].p[1]); + }else if(nodes[k].t == 'c'){ + ctx.bezierCurveTo(nodes[k].p1[0],nodes[k].p1[1],nodes[k].p2[0],nodes[k].p2[1],nodes[k].p3[0],nodes[k].p3[1]); + }else{ + ctx.closePath(); + } + } + if(type === 'st'){ + ctx.stroke(); + } + } + ctx.restore(); + + } renderer.restore(); } renderer.restore(); @@ -358,6 +407,17 @@ } }; +CVShapeElement.prototype.renderGFill = function(styleData,viewData, groupTransform){ + var styleElem = viewData.style; + if(viewData.s.mdf || viewData.e.mdf || this.firstFrame){ + styleElem.x1 = viewData.s.v[0]; + styleElem.y1 = viewData.s.v[1]; + styleElem.x2 = viewData.e.v[0]; + styleElem.y2 = viewData.e.v[1]; + } + +}; + CVShapeElement.prototype.renderStroke = function(styleData,viewData, groupTransform){ var styleElem = viewData.style; //TODO fix dashes