blob: b9c4373e7f75c584f6364df8a5f44d43aa87fdaf [file] [log] [blame]
function CVShapeItemElement(data,renderer,mainFlag){
this.data = data;
this.renderer = renderer;
this.frameNum = -1;
this.trims = [];
this.dataLength = this.data.length;
this.mainFlag = mainFlag;
this.currentPath = null;
this.stylesList = [];
this.ownStylesList = [];
this.pathsList = [];
this.currentMatrix = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix();
var i,len=this.dataLength;
this.renderedPaths = [];
for(i=0;i<len;i+=1){
if(this.data[i].ty == 'gr'){
this.data[i].item = new CVShapeItemElement(this.data[i].it, this.renderer,false);
}
}
}
CVShapeItemElement.prototype.getCurrentPath = function(){
if(!this.currentPath){
this.currentPath = new Path2D();
this.pathsList.push(this.currentPath);
}
return this.currentPath;
};
CVShapeItemElement.prototype.checkDrawing = function(){
var i, len = this.stylesList.length;
for(i=0;i<len;i+=1){
if((this.stylesList[i].type == 'stroke' || this.stylesList[i].type == 'fill') && this.stylesList[i].context == this){
this.stylesList[i].paths.push(this.currentPath);
}
/*if(this.stylesList[i].type == 'stroke'){
this.renderer.canvasContext.strokeStyle=this.stylesList[i].value;
this.renderer.canvasContext.stroke(this.currentPath);
}else{
this.renderer.canvasContext.fillStyle=this.stylesList[i].value;
this.renderer.canvasContext.fill(this.currentPath);
}*/
}
this.currentPath = null;
};
CVShapeItemElement.prototype.drawPaths = function(){
var i, len = this.stylesList.length;
for(i=0;i<len;i+=1){
if(this.stylesList[i].type == 'stroke'){
this.renderer.canvasContext.strokeStyle = this.stylesList[i].value;
this.renderer.canvasContext.lineWidth = this.stylesList[i].width;
this.renderer.canvasContext.stroke(this.stylesList[i].path);
}else if(this.stylesList[i].type == 'fill'){
this.renderer.canvasContext.fillStyle=this.stylesList[i].value;
this.renderer.canvasContext.fill(this.stylesList[i].path);
}
}
};
CVShapeItemElement.prototype.prepareFrame = function(num){
this.frameNum = num;
var i,len=this.dataLength-1;
for(i=len;i>=0;i-=1){
if(this.data[i].ty == 'gr'){
this.data[i].item.prepareFrame(num);
}
}
};
CVShapeItemElement.prototype.renderShape = function(parentStylesList, parentMatrix){
var i, len;
this.ownStylesList.length = 0;
if(!parentStylesList){
this.stylesList.length = 0;
}else{
this.stylesList = parentStylesList;
}
if(parentMatrix){
this.currentMatrix = parentMatrix;
}else{
this.currentMatrix.a = this.currentMatrix.d = 1;
this.currentMatrix.b = this.currentMatrix.c = this.currentMatrix.e = this.currentMatrix.f = 0;
}
len = this.dataLength - 1;
var ctx = this.renderer.canvasContext;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
var flag;
for(i=len;i>=0;i-=1){
if(this.data[i].ty == 'gr'){
//this.checkDrawing();
this.data[i].item.renderShape(this.stylesList,this.currentMatrix);
}else if(this.data[i].ty == 'tr'){
flag = this.renderTransform(this.data[i]);
}else if(this.data[i].ty == 'sh'){
this.renderPath(this.data[i]);
}else if(this.data[i].ty == 'el'){
this.renderEllipse(this.data[i]);
}else if(this.data[i].ty == 'rc'){
this.renderRect(this.data[i]);
}else if(this.data[i].ty == 'fl'){
//this.checkDrawing();
this.renderFill(this.data[i]);
}else if(this.data[i].ty == 'st'){
//this.checkDrawing();
this.renderStroke(this.data[i]);
}else{
console.log(this.data[i].ty);
}
}
//this.checkDrawing();
if(this.mainFlag){
this.drawPaths();
}else{
len = this.ownStylesList.length;
for(i=0;i<len;i+=1){
this.ownStylesList[i].open = false;
}
}
if(flag){
this.stylesList.push({
type:'restore'
});
//ctx.restore();
}
};
CVShapeItemElement.prototype.renderTransform = function(animData){
var flag = false;
var tr = animData.renderedData[this.frameNum];
var matrixValue = tr.mtArr;
var mat = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix();
mat.a = matrixValue[0];
mat.b = matrixValue[1];
mat.c = matrixValue[2];
mat.d = matrixValue[3];
mat.e = matrixValue[4];
mat.f = matrixValue[5];
mat = mat.translate(-tr.a[0],-tr.a[1]);
this.currentMatrix = this.currentMatrix.multiply(mat);
return;
var dataOb;
if(matrixValue[0] !== 1 || matrixValue[1] !== 0 || matrixValue[2] !== 0 || matrixValue[3] !== 1 || matrixValue[4] !== 0 || matrixValue[5] !== 0){
//ctx.save();
//ctx.transform(matrixValue[0], matrixValue[1], matrixValue[2], matrixValue[3], matrixValue[4], matrixValue[5]);
flag = true;
dataOb = {
type: 'transform',
matrix:matrixValue
};
}
if(tr.a[0] != 0 || tr.a[1] != 0){
if(!flag){
//ctx.save();
flag = true;
dataOb = {
type: 'transform'
};
}
dataOb.translate = tr.a;
//ctx.translate(-tr.a[0],-tr.a[1]);
}
if(tr.o < 1){
if(!flag){
//ctx.save();
dataOb = {
type: 'transform'
};
flag = true;
}
dataOb.alpha = tr.o;
//ctx.globalAlpha *= tr.o;
}
if(dataOb){
this.stylesList.push(dataOb);
}
return flag;
};
CVShapeItemElement.prototype.renderPath = function(data){
var path = data.renderedData[this.frameNum].path;
var path2d = new Path2D();
var pathNodes = path.pathNodes;
if(pathNodes instanceof Array){
pathNodes = pathNodes[0];
}
var i,len = pathNodes.i.length;
path2d.moveTo(pathNodes.v[0][0],pathNodes.v[0][1]);
for(i=1;i<len;i+=1){
path2d.bezierCurveTo(pathNodes.o[i-1][0],pathNodes.o[i-1][1]
,pathNodes.i[i][0],pathNodes.i[i][1]
,pathNodes.v[i][0],pathNodes.v[i][1]);
}
if(path.closed){
path2d.bezierCurveTo(pathNodes.o[i-1][0],pathNodes.o[i-1][1]
,pathNodes.i[0][0],pathNodes.i[0][1]
,pathNodes.v[0][0],pathNodes.v[0][1]);
}
var i, len = this.stylesList.length;
for(i=0;i<len;i+=1){
if(this.stylesList[i].open){
this.stylesList[i].path.addPath(path2d, this.currentMatrix);
}
}
};
CVShapeItemElement.prototype.renderEllipse = function(animData){
var path2d = new Path2D();
var ell = animData.renderedData[this.frameNum];
path2d.moveTo(ell.p[0]+ell.size[0]/2,ell.p[1]);
path2d.ellipse(ell.p[0], ell.p[1], ell.size[0]/2, ell.size[1]/2, 0, 0, Math.PI*2, false);
var i, len = this.stylesList.length;
for(i=0;i<len;i+=1){
if(this.stylesList[i].open){
this.stylesList[i].path.addPath(path2d, this.currentMatrix);
}
}
};
CVShapeItemElement.prototype.renderRect = function(animData){
var path2d = new Path2D();
var rect = animData.renderedData[this.frameNum];
var roundness = rect.roundness;
if(roundness == 0){
path2d.rect(rect.position[0] - rect.size[0]/2,rect.position[1] - rect.size[1]/2,rect.size[0],rect.size[1]);
}else{
var x = rect.position[0] - rect.size[0]/2;
var y = rect.position[1] - rect.size[1]/2;
var w = rect.size[0];
var h = rect.size[1];
if(roundness instanceof Array){
roundness = roundness[0];
}
if(roundness > w/2){
roundness = w/2;
}
if(roundness > h/2){
roundness = h/2;
}
path2d.moveTo(x + roundness, y);
path2d.lineTo(x + w - roundness, y);
path2d.quadraticCurveTo(x+w, y, x+w, y+roundness);
path2d.lineTo(x+w, y+h-roundness);
path2d.quadraticCurveTo(x+w, y+h, x+w-roundness, y+h);
path2d.lineTo(x+roundness, y+h);
path2d.quadraticCurveTo(x, y+h, x, y+h-roundness);
path2d.lineTo(x, y+roundness);
path2d.quadraticCurveTo(x, y, x+roundness, y);
}
var i, len = this.stylesList.length;
for(i=0;i<len;i+=1){
if(this.stylesList[i].open){
this.stylesList[i].path.addPath(path2d, this.currentMatrix);
}
}
};
CVShapeItemElement.prototype.renderFill = function(animData){
var fill = animData.renderedData[this.frameNum];
if(animData.fillEnabled!==false){
if(fill.opacity < 1){
//this.renderer.canvasContext.fillStyle=fillColorToString(fill.color, fill.opacity);
this.stylesList.push({
type:'fill',
value:fillColorToString(fill.color, fill.opacity),
path: new Path2D(),
open: true
})
}else{
///this.renderer.canvasContext.fillStyle='rgba('+fill.color.join(',')+')';
//this.renderer.canvasContext.fillStyle=fillColorToString(fill.color);
this.stylesList.push({
type:'fill',
value:fillColorToString(fill.color),
path: new Path2D(),
open: true
})
}
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
return;
}
this.stylesList.push({
type:'fill',
value:'rgba(0,0,0,0)',
path: new Path2D(),
open: true
});
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
//this.renderer.canvasContext.fillStyle='rgba(0,0,0,0)';
};
CVShapeItemElement.prototype.renderStroke = function(animData){
var stroke = animData.renderedData[this.frameNum];
//this.renderer.canvasContext.lineWidth=stroke.width;
if(this.data.strokeEnabled!==false){
if(stroke.opacity < 1){
//this.renderer.canvasContext.strokeStyle=fillColorToString(stroke.color, stroke.opacity);
this.stylesList.push({
type:'stroke',
value:fillColorToString(stroke.color, stroke.opacity),
width:stroke.width,
path: new Path2D(),
open: true
});
}else{
//this.renderer.canvasContext.strokeStyle=fillColorToString(stroke.color);
this.stylesList.push({
type:'stroke',
value:fillColorToString(stroke.color),
width:stroke.width,
path: new Path2D(),
open: true
});
}
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
return;
}
this.stylesList.push({
type:'stroke',
value:'rgba(0,0,0,0)',
width:stroke.width,
path: new Path2D(),
open: true
});
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
//this.renderer.canvasContext.strokeStyle = 'rgba(0,0,0,0)';
};
CVShapeItemElement.prototype.adjustTrim = function(){
var trimData = this.data.trim;
var i, len = trimData.length;
for(i=0;i<len;i+=1){
if(trimData[i].o){
trimData[i].o -= 90;
}
}
};
CVShapeItemElement.prototype.addToTrim = function(pos,s,e){
if(!this.trims[pos]){
this.trims.push({});
}
this.trims[pos].s = s;
this.trims[pos].e = e;
this.trims[pos].ended = false;
};
CVShapeItemElement.prototype.renderTrimPath = function(num){
var trimData = this.currentData.trim;
if(trimData.e == trimData.s){
return;
}
if(this.renderedPaths[num]){
return;
}
var path2d = new Path2D();
var path = this.currentData.path;
var pathNodes = path.pathNodes;
var segments = [];
var totalLength = 0;
var i, len = pathNodes.v.length;
for(i = 0; i < len - 1; i += 1){
segments.push(bez.drawBezierCurve(pathNodes.v[i],pathNodes.v[i+1],pathNodes.o[i],pathNodes.i[i+1]));
totalLength += segments[i].segmentLength;
}
if(path.closed){
segments.push(bez.drawBezierCurve(pathNodes.v[i],pathNodes.v[0],pathNodes.o[i],pathNodes.i[0]));
totalLength += segments[i].segmentLength;
}
len = segments.length;
var segmentLength = totalLength*(trimData.e - trimData.s)/100;
trimData.o = trimData.o%360;
if(trimData.o<0){
trimData.o += 360;
}
//this.trims.length = 0;
var offset = ((trimData.s/100 + trimData.o/360)%1)*totalLength;
var endedCount = 0;
if(offset + segmentLength - totalLength > 0.00001){
var secondarySegment = offset + segmentLength - totalLength;
this.addToTrim(0,offset,offset + segmentLength - secondarySegment);
this.addToTrim(1,0,offset + segmentLength - totalLength);
endedCount += 2;
}else{
this.addToTrim(0,offset,offset + segmentLength);
endedCount += 1;
}
var addedLength = 0;
var j, jLen,perc,flag, ended = false;
var k, kLen = this.trims.length;
for(i = 0; i < len; i += 1){
if(ended){
break;
}
jLen = segments[i].points.length;
flag = true;
for(k = 0; k < kLen; k+=1){
if(addedLength + segments[i].segmentLength > this.trims[k].s){
flag = false;
}
}
if(flag){
addedLength += segments[i].segmentLength;
continue;
}
var currentPt, nextPt;
for(j = 0; j < jLen-1 ; j += 1){
if(ended){
break;
}
kLen = this.trims.length;
currentPt = segments[i].points[j];
nextPt = segments[i].points[j+1];
addedLength += currentPt.partialLength;
for(k = 0; k < kLen; k+=1){
if(this.trims[k].ended){
continue;
}
if(this.trims[k].s >= addedLength && this.trims[k].s < addedLength + nextPt.partialLength){
perc = ( this.trims[k].s - addedLength)/nextPt.partialLength;
path2d.moveTo(currentPt.point[0]+(nextPt.point[0] - currentPt.point[0])*perc
,currentPt.point[1]+(nextPt.point[1] - currentPt.point[1])*perc);
}
if(this.trims[k].e > addedLength && this.trims[k].e <= addedLength + nextPt.partialLength){
perc = ( this.trims[k].e - addedLength)/nextPt.partialLength;
path2d.lineTo(currentPt.point[0]+(nextPt.point[0] - currentPt.point[0])*perc
,currentPt.point[1]+(nextPt.point[1] - currentPt.point[1])*perc);
endedCount -= 1;
this.trims[k].ended = true;
if(endedCount == 0){
ended = true;
break;
}
}else if(addedLength > this.trims[k].s && addedLength < this.trims[k].e){
path2d.lineTo(currentPt.point[0],currentPt.point[1]);
}
}
}
this.renderedPaths[num] = path2d;
}
};