blob: 7ac9bc6a2eb24750cf1db9bb11ceb809b0aa9278 [file] [log] [blame]
function CVShapeItemElement(data,renderer){
this.data = data;
this.renderer = renderer;
this.frameNum = -1;
this.renderedPaths = {};
this.trims = [];
this.trimPos = 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.renderShape = function(){
var num = this.frameNum;
var ctx = this.renderer.canvasContext;
var flag = this.renderTransform(num);
if(this.data.type=="pathShape"){
if(this.data.trim){
this.renderTrimPath(num);
}else{
this.renderPath(num);
}
}else if(this.data.type=="rectShape"){
this.renderRect(num);
}else if(this.data.type=="ellipseShape"){
this.pathLength = this.renderEllipse(num);
}
this.renderFill(num);
this.renderStroke(num);
this.renderer.canvasContext.lineCap = 'round';
this.renderer.canvasContext.lineJoin = 'round';
if(this.renderedPaths[num]){
if(supportsPath2D){
this.renderer.canvasContext.fill(this.renderedPaths[num]);
this.renderer.canvasContext.stroke(this.renderedPaths[num]);
}else{
this.renderedPaths[num].drawToContext(this.renderer.canvasContext);
this.renderer.canvasContext.fill();
this.renderer.canvasContext.stroke();
}
}else{
this.renderer.canvasContext.fill();
this.renderer.canvasContext.stroke();
}
if(flag){
ctx.restore();
}
};
CVShapeItemElement.prototype.prepareFrame = function(num){
this.frameNum = num;
};
CVShapeItemElement.prototype.renderTransform = function(num){
var animData = this.data.an;
if(animData.tr){
var ctx = this.renderer.canvasContext;
var tr = animData.tr[animData.tr[num].forwardFrame];
animData.renderedFrame.tr = tr.forwardFrame;
var matrixValue = tr.mtArr;
if(matrixValue[0] == 1 && matrixValue[1] == 0 && matrixValue[2] == 0 && matrixValue[3] == 1 && matrixValue[4] == 0 && matrixValue[5] == 0){
return false;
}
ctx.save();
ctx.transform(matrixValue[0], matrixValue[1], matrixValue[2], matrixValue[3], matrixValue[4], matrixValue[5]);
ctx.translate(-tr.a[0],-tr.a[1]);
return true;
}
};
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.data.trim.an[this.data.trim.an[num].forwardFrame];
if(trimData.e == trimData.s){
return;
}
if(this.renderedPaths[num]){
return;
}
var path2d = new Path2D();
var animData = this.data.an;
var path = animData.path[animData.path[num].forwardFrame];
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[len - 1],pathNodes.v[0],pathNodes.o[len - 1],pathNodes.i[0]));
totalLength += segments[i].segmentLength;
}
len = segments.length;
var segmentLength = totalLength*(trimData.e - trimData.s)/100;
var offset = ((trimData.s/100 + (trimData.o%360)/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;
}
for(j = 0; j < jLen-1 ; j += 1){
if(ended){
break;
}
kLen = this.trims.length;
addedLength += segments[i].points[j].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 + segments[i].points[j+1].partialLength){
perc = ( this.trims[k].s - addedLength)/segments[i].points[j+1].partialLength;
path2d.moveTo(segments[i].points[j].point[0]+(segments[i].points[j+1].point[0] - segments[i].points[j].point[0])*perc
,segments[i].points[j].point[1]+(segments[i].points[j+1].point[1] - segments[i].points[j].point[1])*perc);
}
if(this.trims[k].e > addedLength && this.trims[k].e <= addedLength + segments[i].points[j+1].partialLength){
perc = ( this.trims[k].e - addedLength)/segments[i].points[j+1].partialLength;
path2d.lineTo(segments[i].points[j].point[0]+(segments[i].points[j+1].point[0] - segments[i].points[j].point[0])*perc
,segments[i].points[j].point[1]+(segments[i].points[j+1].point[1] - segments[i].points[j].point[1])*perc);
endedCount -= 1;
this.trims[k].ended = false;
if(endedCount == 0){
ended = true;
break;
}
}else if(addedLength > this.trims[k].s && addedLength < this.trims[k].e){
path2d.lineTo(segments[i].points[j].point[0],segments[i].points[j].point[1]);
}
}
}
this.renderedPaths[num] = path2d;
}
};
CVShapeItemElement.prototype.renderPath = function(num){
var animData = this.data.an;
var path = animData.path[animData.path[num].forwardFrame];
if(this.renderedPaths[num]){
return;
}
var path2d = new Path2D();
animData.renderedFrame.path = path.pathString;
var ctx = this.renderer.canvasContext;
var pathNodes = path.pathNodes;
if(pathNodes instanceof Array){
pathNodes = pathNodes[0];
}
var i,len = pathNodes.i.length;
ctx.beginPath();
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.v[i-1][0],pathNodes.o[i-1][1]+pathNodes.v[i-1][1]
,pathNodes.i[i][0]+pathNodes.v[i][0],pathNodes.i[i][1]+pathNodes.v[i][1]
,pathNodes.v[i][0],pathNodes.v[i][1]);
}
if(path.closed){
path2d.bezierCurveTo(pathNodes.o[i-1][0]+pathNodes.v[i-1][0],pathNodes.o[i-1][1]+pathNodes.v[i-1][1]
,pathNodes.i[0][0]+pathNodes.v[0][0],pathNodes.i[0][1]+pathNodes.v[0][1]
,pathNodes.v[0][0],pathNodes.v[0][1]);
}
this.renderedPaths[num] = path2d;
};
CVShapeItemElement.prototype.renderEllipse = function(num){
var animData = this.data.an;
var ell = animData.ell[animData.ell[num].forwardFrame];
animData.renderedFrame.ell = ell.forwardFrame;
var ctx = this.renderer.canvasContext;
ctx.beginPath();
ctx.ellipse(ell.p[0], ell.p[1], ell.size[0]/2, ell.size[1]/2, 0, 0, Math.PI*2, true);
ctx.closePath();
};
CVShapeItemElement.prototype.renderRect = function(num){
var animData = this.data.an;
var rect = animData.rect[animData.rect[num].forwardFrame];
var roundness = rect.roundness;
var ctx = this.renderer.canvasContext;
ctx.beginPath();
if(roundness == 0){
ctx.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];
ctx.moveTo(x + roundness, y);
ctx.lineTo(x + w - roundness, y);
ctx.quadraticCurveTo(x+w, y, x+w, y+roundness);
ctx.lineTo(x+w, y+h-roundness);
ctx.quadraticCurveTo(x+w, y+h, x+w-roundness, y+h);
ctx.lineTo(x+roundness, y+h);
ctx.quadraticCurveTo(x, y+h, x, y+h-roundness);
ctx.lineTo(x, y+roundness);
ctx.quadraticCurveTo(x, y, x+roundness, y);
}
};
CVShapeItemElement.prototype.renderFill = function(num){
var animData = this.data.an;
if(animData.fill){
var fill = animData.fill[animData.fill[num].forwardFrame];
animData.renderedFrame.fill = {color:fill.color,opacity:fill.opacity};
if(this.data.fillEnabled!==false){
if(fill.opacity < 1){
this.renderer.canvasContext.fillStyle=fillToRgba(fill.color, fill.opacity);
}else{
this.renderer.canvasContext.fillStyle=fill.color;
}
return;
}
}
this.renderer.canvasContext.fillStyle='rgba(0,0,0,0)';
};
CVShapeItemElement.prototype.renderStroke = function(num){
var animData = this.data.an;
if(animData.stroke){
var stroke = animData.stroke[animData.stroke[num].forwardFrame];
animData.renderedFrame.stroke = stroke.forwardFrame;
/*ctx.strokeStyle="red";
*/
this.renderer.canvasContext.lineWidth=stroke.width;
if(this.data.strokeEnabled!==false){
if(stroke.opacity < 1){
this.renderer.canvasContext.strokeStyle=fillToRgba(stroke.color, stroke.opacity);
}else{
this.renderer.canvasContext.strokeStyle=stroke.color;
}
return;
}
}
this.renderer.canvasContext.strokeStyle = 'rgba(0,0,0,0)';
};