123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- import { getLocationHref } from './main';
- import {
- createElementID,
- } from './utils/common';
- import {
- createSizedArray,
- } from './utils/helpers/arrays';
- import PropertyFactory from './utils/PropertyFactory';
- import ShapePropertyFactory from './utils/shapes/ShapeProperty';
- import createNS from './utils/helpers/svg_elements';
- 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;
- var len = this.masksProperties ? this.masksProperties.length : 0;
- this.viewData = createSizedArray(len);
- this.solidPath = '';
- var path;
- var properties = this.masksProperties;
- var count = 0;
- var currentMasks = [];
- var j;
- var jLen;
- var layerId = createElementID();
- var rect;
- var expansor;
- var feMorph;
- var x;
- var maskType = 'clipPath';
- var maskRef = 'clip-path';
- for (i = 0; i < len; i += 1) {
- 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);
- } else {
- 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(' + getLocationHref() + '#' + 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(' + getLocationHref() + '#' + 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;
- var len = this.masksProperties.length;
- for (i = 0; i < len; i += 1) {
- 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(' + getLocationHref() + '#' + 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;
- var 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;
- };
- export default MaskElement;
|