| function MaskElement(data,element,globalData) { |
| this.data = data; |
| this.element = element; |
| this.globalData = globalData; |
| this.storedData = []; |
| this.masksProperties = this.data.masksProperties || []; |
| this.maskElement = null; |
| var defs = this.globalData.defs; |
| var i, len = this.masksProperties ? this.masksProperties.length : 0; |
| this.viewData = createSizedArray(len); |
| this.solidPath = ''; |
| |
| |
| var path, properties = this.masksProperties; |
| var count = 0; |
| var currentMasks = []; |
| var j, jLen; |
| var layerId = createElementID(); |
| var rect, expansor, feMorph,x; |
| var maskType = 'clipPath', maskRef = 'clip-path'; |
| for (i = 0; i < len; i++) { |
| if((properties[i].mode !== 'a' && properties[i].mode !== 'n')|| properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x){ |
| maskType = 'mask'; |
| maskRef = 'mask'; |
| } |
| |
| if((properties[i].mode == 's' || properties[i].mode == 'i') && count === 0){ |
| rect = createNS( 'rect'); |
| rect.setAttribute('fill', '#ffffff'); |
| rect.setAttribute('width', this.element.comp.data.w || 0); |
| rect.setAttribute('height', this.element.comp.data.h || 0); |
| currentMasks.push(rect); |
| } else { |
| rect = null; |
| } |
| |
| path = createNS( 'path'); |
| if(properties[i].mode == 'n') { |
| // TODO move this to a factory or to a constructor |
| this.viewData[i] = { |
| op: PropertyFactory.getProp(this.element,properties[i].o,0,0.01,this.element), |
| prop: ShapePropertyFactory.getShapeProp(this.element,properties[i],3), |
| elem: path, |
| lastPath: '' |
| }; |
| defs.appendChild(path); |
| continue; |
| } |
| count += 1; |
| |
| path.setAttribute('fill', properties[i].mode === 's' ? '#000000':'#ffffff'); |
| path.setAttribute('clip-rule','nonzero'); |
| var filterID; |
| |
| if (properties[i].x.k !== 0) { |
| maskType = 'mask'; |
| maskRef = 'mask'; |
| x = PropertyFactory.getProp(this.element,properties[i].x,0,null,this.element); |
| filterID = createElementID(); |
| expansor = createNS('filter'); |
| expansor.setAttribute('id',filterID); |
| feMorph = createNS('feMorphology'); |
| feMorph.setAttribute('operator','erode'); |
| feMorph.setAttribute('in','SourceGraphic'); |
| feMorph.setAttribute('radius','0'); |
| expansor.appendChild(feMorph); |
| defs.appendChild(expansor); |
| path.setAttribute('stroke', properties[i].mode === 's' ? '#000000':'#ffffff'); |
| } else { |
| feMorph = null; |
| x = null; |
| } |
| |
| // TODO move this to a factory or to a constructor |
| this.storedData[i] = { |
| elem: path, |
| x: x, |
| expan: feMorph, |
| lastPath: '', |
| lastOperator:'', |
| filterId:filterID, |
| lastRadius:0 |
| }; |
| if(properties[i].mode == 'i'){ |
| jLen = currentMasks.length; |
| var g = createNS('g'); |
| for(j=0;j<jLen;j+=1){ |
| g.appendChild(currentMasks[j]); |
| } |
| var mask = createNS('mask'); |
| mask.setAttribute('mask-type','alpha'); |
| mask.setAttribute('id',layerId+'_'+count); |
| mask.appendChild(path); |
| defs.appendChild(mask); |
| g.setAttribute('mask','url(' + locationHref + '#'+layerId+'_'+count+')'); |
| |
| currentMasks.length = 0; |
| currentMasks.push(g); |
| }else{ |
| currentMasks.push(path); |
| } |
| if(properties[i].inv && !this.solidPath){ |
| this.solidPath = this.createLayerSolidPath(); |
| } |
| // TODO move this to a factory or to a constructor |
| this.viewData[i] = { |
| elem: path, |
| lastPath: '', |
| op: PropertyFactory.getProp(this.element,properties[i].o,0,0.01,this.element), |
| prop:ShapePropertyFactory.getShapeProp(this.element,properties[i],3), |
| invRect: rect |
| }; |
| if(!this.viewData[i].prop.k){ |
| this.drawPath(properties[i],this.viewData[i].prop.v,this.viewData[i]); |
| } |
| } |
| |
| this.maskElement = createNS( maskType); |
| |
| len = currentMasks.length; |
| for(i=0;i<len;i+=1){ |
| this.maskElement.appendChild(currentMasks[i]); |
| } |
| |
| if(count > 0){ |
| this.maskElement.setAttribute('id', layerId); |
| this.element.maskedElement.setAttribute(maskRef, "url(" + locationHref + "#" + layerId + ")"); |
| defs.appendChild(this.maskElement); |
| } |
| if (this.viewData.length) { |
| this.element.addRenderableComponent(this); |
| } |
| |
| } |
| |
| MaskElement.prototype.getMaskProperty = function(pos){ |
| return this.viewData[pos].prop; |
| }; |
| |
| MaskElement.prototype.renderFrame = function (isFirstFrame) { |
| var finalMat = this.element.finalTransform.mat; |
| var i, len = this.masksProperties.length; |
| for (i = 0; i < len; i++) { |
| if(this.viewData[i].prop._mdf || isFirstFrame){ |
| this.drawPath(this.masksProperties[i],this.viewData[i].prop.v,this.viewData[i]); |
| } |
| if(this.viewData[i].op._mdf || isFirstFrame){ |
| this.viewData[i].elem.setAttribute('fill-opacity',this.viewData[i].op.v); |
| } |
| if(this.masksProperties[i].mode !== 'n'){ |
| if(this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)){ |
| this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS()) |
| } |
| if(this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)){ |
| var feMorph = this.storedData[i].expan; |
| if(this.storedData[i].x.v < 0){ |
| if(this.storedData[i].lastOperator !== 'erode'){ |
| this.storedData[i].lastOperator = 'erode'; |
| this.storedData[i].elem.setAttribute('filter','url(' + locationHref + '#'+this.storedData[i].filterId+')'); |
| } |
| feMorph.setAttribute('radius',-this.storedData[i].x.v); |
| }else{ |
| if(this.storedData[i].lastOperator !== 'dilate'){ |
| this.storedData[i].lastOperator = 'dilate'; |
| this.storedData[i].elem.setAttribute('filter',null); |
| } |
| this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v*2); |
| |
| } |
| } |
| } |
| } |
| }; |
| |
| MaskElement.prototype.getMaskelement = function () { |
| return this.maskElement; |
| }; |
| |
| MaskElement.prototype.createLayerSolidPath = function(){ |
| var path = 'M0,0 '; |
| path += ' h' + this.globalData.compSize.w ; |
| path += ' v' + this.globalData.compSize.h ; |
| path += ' h-' + this.globalData.compSize.w ; |
| path += ' v-' + this.globalData.compSize.h + ' '; |
| return path; |
| }; |
| |
| MaskElement.prototype.drawPath = function(pathData,pathNodes,viewData){ |
| var pathString = " M"+pathNodes.v[0][0]+','+pathNodes.v[0][1]; |
| var i, len; |
| len = pathNodes._length; |
| for(i=1;i<len;i+=1){ |
| //pathString += " C"+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]; |
| pathString += " C"+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]; |
| } |
| //pathString += " C"+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]; |
| if(pathNodes.c && len > 1){ |
| pathString += " C"+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]; |
| } |
| //pathNodes.__renderedString = pathString; |
| |
| if(viewData.lastPath !== pathString){ |
| var pathShapeValue = ''; |
| if(viewData.elem){ |
| if(pathNodes.c){ |
| pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString; |
| } |
| viewData.elem.setAttribute('d',pathShapeValue); |
| } |
| viewData.lastPath = pathString; |
| } |
| }; |
| |
| MaskElement.prototype.destroy = function(){ |
| this.element = null; |
| this.globalData = null; |
| this.maskElement = null; |
| this.data = null; |
| this.masksProperties = null; |
| }; |