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