blob: 8f3a10cc36bc7aea017e992135cebccd4f6d6e46 [file] [log] [blame]
function CVShapeItemElement(data,mainFlag,globalData){
this.lcEnum = {
'1': 'butt',
'2': 'round',
'3': 'butt'
};
this.ljEnum = {
'1': 'miter',
'2': 'round',
'3': 'bevel'
};
this.data = data;
this.globalData = globalData;
this.canvasContext = globalData.canvasContext;
this.frameNum = -1;
this.dataLength = this.data.length;
this.mainFlag = mainFlag;
this.stylesList = [];
this.ownStylesList = [];
this.stylesPool = [];
this.currentStylePoolPos = 0;
this.transform = {
opacity: 1,
mat: new Matrix()
};
this.mat = new Matrix();
var i,len=this.dataLength-1;
this.renderedPaths = new Array(this.globalData.totalFrames);
var styleData;
for(i=len;i>=0;i-=1){
if(this.data[i].ty == 'gr'){
this.data[i].item = new CVShapeItemElement(this.data[i].it,false,this.globalData);
}else if(this.data[i].ty == 'st' || this.data[i].ty == 'fl'){
styleData = {
type:'fill',
/*path: new BM_Path2D(),*/
styleOpacity: 0,
opacity: 0,
value:'rgba(0,0,0,0)',
closed: false
};
if(this.data[i].ty == 'fl'){
styleData.type = 'fill';
}else{
styleData.type = 'stroke';
styleData.width = 0;
styleData.lc = this.lcEnum[this.data[i].lc] || 'round';
styleData.lj = this.ljEnum[this.data[i].lj] || 'round';
if(this.data[i].lj == 1) {
styleData.ml = this.data[i].ml;
}
}
this.stylesPool.push(styleData);
}
}
}
CVShapeItemElement.prototype.drawPaths = function(cacheFlag){
var stylesList,cache;
if(cacheFlag){
cache = [];
stylesList = this.stylesList;
}else{
stylesList = this.renderedPaths[this.globalData.frameNum];
}
var i, len = stylesList.length;
var ctx = this.canvasContext;
this.globalData.renderer.save();
for(i=0;i<len;i+=1){
if(stylesList[i].type == 'stroke'){
if(stylesList[i].opacity != 1){
this.globalData.renderer.save();
this.globalData.renderer.ctxOpacity(stylesList[i].opacity);
///ctx.globalAlpha *= stylesList[i].opacity;
}
ctx.lineCap = stylesList[i].lc;
ctx.lineJoin = stylesList[i].lj;
ctx.miterLimit = stylesList[i].ml;
ctx.strokeStyle = stylesList[i].value;
ctx.lineWidth = stylesList[i].width;
if(stylesList[i].dasharray){
ctx.setLineDash(stylesList[i].dasharray);
ctx.lineDashOffset = stylesList[i].dashoffset;
}else{
ctx.setLineDash([]);
ctx.lineDashOffset = 0;
}
this.globalData.bmCtx.stroke(stylesList[i].path);
if(stylesList[i].opacity != 1){
this.globalData.renderer.restore();
}
if(cacheFlag){
cache.push({
type: stylesList[i].type,
opacity: stylesList[i].opacity,
value: stylesList[i].value,
width: stylesList[i].width,
path: stylesList[i].path
});
if(stylesList[i].dasharray){
cache[cache.length-1].dasharray = stylesList[i].dasharray;
cache[cache.length-1].dashoffset = stylesList[i].dashoffset;
}
}
}else if(stylesList[i].type == 'fill'){
if(stylesList[i].opacity != 1){
this.globalData.renderer.save();
this.globalData.renderer.ctxOpacity(stylesList[i].opacity);
///ctx.globalAlpha *= stylesList[i].opacity;
}
ctx.fillStyle = stylesList[i].value;
this.globalData.bmCtx.fill(stylesList[i].path);
if(stylesList[i].opacity != 1){
this.globalData.renderer.restore();
}
if(cacheFlag){
cache.push({
type: stylesList[i].type,
opacity: stylesList[i].opacity,
value: stylesList[i].value,
path: stylesList[i].path
});
}
}
}
this.globalData.renderer.restore();
if(cacheFlag){
this.renderedPaths[this.globalData.frameNum] = cache;
}
};
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(parentTransform,parentStylesList){
if(this.renderedPaths[this.globalData.frameNum]){
this.drawPaths(false);
return;
}
this.transform.opacity = 1;
var i, len;
this.ownStylesList.length = 0;
this.currentStylePoolPos = 0;
if(!parentStylesList){
this.stylesList.length = 0;
}else{
this.stylesList = parentStylesList;
}
if(parentTransform){
this.transform.mat.props[0] = parentTransform.mat.props[0];
this.transform.mat.props[1] = parentTransform.mat.props[1];
this.transform.mat.props[2] = parentTransform.mat.props[2];
this.transform.mat.props[3] = parentTransform.mat.props[3];
this.transform.mat.props[4] = parentTransform.mat.props[4];
this.transform.mat.props[5] = parentTransform.mat.props[5];
this.transform.opacity *= parentTransform.opacity;
}else{
this.transform.mat.props[0] = this.transform.mat.props[3] = 1;
this.transform.mat.props[1] = this.transform.mat.props[2] = this.transform.mat.props[4] = this.transform.mat.props[5] = 0;
}
len = this.dataLength - 1;
for(i=len;i>=0;i-=1){
if(this.data[i].ty == 'gr'){
this.data[i].item.renderShape(this.transform,this.stylesList);
}else if(this.data[i].ty == 'tr'){
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'){
if(this.data[i].trimmed){
this.renderPath(this.data[i]);
}else{
this.renderRect(this.data[i]);
}
}else if(this.data[i].ty == 'fl'){
this.renderFill(this.data[i]);
}else if(this.data[i].ty == 'st'){
this.renderStroke(this.data[i]);
}else{
//console.log(this.data[i].ty);
}
}
if(this.mainFlag){
this.drawPaths(true);
}else{
len = this.ownStylesList.length;
for(i=0;i<len;i+=1){
this.ownStylesList[i].closed = true;
}
}
};
CVShapeItemElement.prototype.renderTransform = function(animData){
var tr = animData.renderedData[this.frameNum];
var matrixValue = tr.mtArr;
this.transform.mat.transform(matrixValue[0],matrixValue[1],matrixValue[2],matrixValue[3],matrixValue[4],matrixValue[5]).translate(-tr.a[0],-tr.a[1]);
this.transform.opacity *= tr.o;
};
CVShapeItemElement.prototype.renderPath = function(data){
if(data.trimmed){
var ctx = this.canvasContext;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
}
var path = data.renderedData[this.frameNum].path;
var path2d = new BM_Path2D();
var pathNodes = path.pathNodes;
if(pathNodes instanceof Array){
pathNodes = pathNodes[0];
}
if(!pathNodes.v){
return;
}
var i,len = pathNodes.v.length;
var stops = pathNodes.s ? pathNodes.s : [];
for(i=1;i<len;i+=1){
if(stops[i-1]){
path2d.moveTo(bm_rnd(stops[i-1][0]),bm_rnd(stops[i-1][1]));
//path2d.moveTo(stops[i-1][0],stops[i-1][1]);
}else if(i==1){
path2d.moveTo(bm_rnd(pathNodes.v[0][0]),bm_rnd(pathNodes.v[0][1]));
//path2d.moveTo(pathNodes.v[0][0],pathNodes.v[0][1]);
}
path2d.bezierCurveTo(bm_rnd(pathNodes.o[i-1][0]),bm_rnd(pathNodes.o[i-1][1]),bm_rnd(pathNodes.i[i][0]),bm_rnd(pathNodes.i[i][1]),bm_rnd(pathNodes.v[i][0]),bm_rnd(pathNodes.v[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(len == 1){
if(stops[0]){
path2d.moveTo(bm_rnd(stops[0][0]),bm_rnd(stops[0][1]));
//path2d.moveTo(stops[0][0],stops[0][1]);
}else{
path2d.moveTo(bm_rnd(pathNodes.v[0][0]),bm_rnd(pathNodes.v[0][1]));
//path2d.moveTo(pathNodes.v[0][0],pathNodes.v[0][1]);
}
}
if(data.closed && !(data.trimmed && !pathNodes.c)){
path2d.bezierCurveTo(bm_rnd(pathNodes.o[i-1][0]),bm_rnd(pathNodes.o[i-1][1]),bm_rnd(pathNodes.i[0][0]),bm_rnd(pathNodes.i[0][1]),bm_rnd(pathNodes.v[0][0]),bm_rnd(pathNodes.v[0][1]));
//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]);
}
this.addPathToStyles(path2d);
};
CVShapeItemElement.prototype.renderEllipse = function(animData){
var path2d = new BM_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);
this.addPathToStyles(path2d);
};
CVShapeItemElement.prototype.renderRect = function(animData){
var path2d = new BM_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);
}
this.addPathToStyles(path2d);
};
CVShapeItemElement.prototype.addPathToStyles = function(path2d){
var i, len = this.stylesList.length;
var canFill = true, strokeWidth = 0;
for(i=len-1;i>=0;i-=1){
if(!this.stylesList[i].closed){
if(this.stylesList[i].type == 'stroke'){
if(this.stylesList[i].width > strokeWidth){
this.stylesList[i].path.addPath(path2d, this.transform.mat.props);
}
if(this.stylesList[i].styleOpacity == 1 && this.stylesList[i].opacity == 1){
strokeWidth = this.stylesList[i].width;
}
}else if(canFill && this.stylesList[i].type == 'fill'){
this.stylesList[i].path.addPath(path2d, this.transform.mat.props);
if(this.stylesList[i].styleOpacity == 1 && this.stylesList[i].opacity == 1){
canFill = false;
}
}
}
}
};
CVShapeItemElement.prototype.renderFill = function(animData){
var fill = animData.renderedData[this.frameNum];
if(animData.fillEnabled!==false){
this.stylesPool[this.currentStylePoolPos].path = new BM_Path2D();
this.stylesPool[this.currentStylePoolPos].closed = false;
this.stylesPool[this.currentStylePoolPos].styleOpacity = fill.opacity < 1 ? fill.opacity : 1;
this.stylesPool[this.currentStylePoolPos].opacity = this.transform.opacity;
this.stylesPool[this.currentStylePoolPos].value = fill.opacity < 1 ? fillColorToString(fill.color, fill.opacity) : fillColorToString(fill.color);
this.stylesList.push(this.stylesPool[this.currentStylePoolPos]);
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
this.currentStylePoolPos += 1;
return;
}
this.stylesList.push(this.stylesPool[this.currentStylePoolPos]);
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
this.currentStylePoolPos += 1;
};
CVShapeItemElement.prototype.renderStroke = function(animData){
var stroke = animData.renderedData[this.frameNum];
if(this.data.strokeEnabled!==false){
this.stylesPool[this.currentStylePoolPos].path = new BM_Path2D();
this.stylesPool[this.currentStylePoolPos].closed = false;
this.stylesPool[this.currentStylePoolPos].styleOpacity = stroke.opacity < 1 ? stroke.opacity : 1;
this.stylesPool[this.currentStylePoolPos].width = stroke.width;
this.stylesPool[this.currentStylePoolPos].opacity = this.transform.opacity;
this.stylesPool[this.currentStylePoolPos].value = stroke.opacity < 1 ? fillColorToString(stroke.color, stroke.opacity) : fillColorToString(stroke.color);
if(stroke.dashes){
var d = stroke.dashes;
var j, jLen = d.length;
var dasharray = [];
var dashoffset = '';
for(j=0;j<jLen;j+=1){
if(d[j].n != 'o'){
dasharray.push(d[j].v);
}else{
dashoffset = d[j].v;
}
}
this.stylesPool[this.currentStylePoolPos].dasharray = dasharray;
this.stylesPool[this.currentStylePoolPos].dashoffset = dashoffset;
}
this.stylesList.push(this.stylesPool[this.currentStylePoolPos]);
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
this.currentStylePoolPos += 1;
return;
}
this.stylesList.push(this.stylesPool[this.currentStylePoolPos]);
this.ownStylesList.push(this.stylesList[this.stylesList.length -1]);
this.currentStylePoolPos += 1;
};
CVShapeItemElement.prototype.destroy = function(){
this.data = null;
this.globalData = null;
this.canvasContext = null;
};