240 lines
7.8 KiB
JavaScript
240 lines
7.8 KiB
JavaScript
import Matrix from '../../../3rd_party/transformation-matrix';
|
|
import buildShapeString from '../../../utils/shapes/shapePathBuilder';
|
|
import { bmFloor } from '../../../utils/common';
|
|
|
|
const SVGElementsRenderer = (function () {
|
|
var _identityMatrix = new Matrix();
|
|
var _matrixHelper = new Matrix();
|
|
|
|
var ob = {
|
|
createRenderFunction: createRenderFunction,
|
|
};
|
|
|
|
function createRenderFunction(data) {
|
|
switch (data.ty) {
|
|
case 'fl':
|
|
return renderFill;
|
|
case 'gf':
|
|
return renderGradient;
|
|
case 'gs':
|
|
return renderGradientStroke;
|
|
case 'st':
|
|
return renderStroke;
|
|
case 'sh':
|
|
case 'el':
|
|
case 'rc':
|
|
case 'sr':
|
|
return renderPath;
|
|
case 'tr':
|
|
return renderContentTransform;
|
|
case 'no':
|
|
return renderNoop;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function renderContentTransform(styleData, itemData, isFirstFrame) {
|
|
if (isFirstFrame || itemData.transform.op._mdf) {
|
|
itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
|
|
}
|
|
if (isFirstFrame || itemData.transform.mProps._mdf) {
|
|
itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
|
|
}
|
|
}
|
|
|
|
function renderNoop() {
|
|
|
|
}
|
|
|
|
function renderPath(styleData, itemData, isFirstFrame) {
|
|
var j;
|
|
var jLen;
|
|
var pathStringTransformed;
|
|
var redraw;
|
|
var pathNodes;
|
|
var l;
|
|
var lLen = itemData.styles.length;
|
|
var lvl = itemData.lvl;
|
|
var paths;
|
|
var mat;
|
|
var iterations;
|
|
var k;
|
|
for (l = 0; l < lLen; l += 1) {
|
|
redraw = itemData.sh._mdf || isFirstFrame;
|
|
if (itemData.styles[l].lvl < lvl) {
|
|
mat = _matrixHelper.reset();
|
|
iterations = lvl - itemData.styles[l].lvl;
|
|
k = itemData.transformers.length - 1;
|
|
while (!redraw && iterations > 0) {
|
|
redraw = itemData.transformers[k].mProps._mdf || redraw;
|
|
iterations -= 1;
|
|
k -= 1;
|
|
}
|
|
if (redraw) {
|
|
iterations = lvl - itemData.styles[l].lvl;
|
|
k = itemData.transformers.length - 1;
|
|
while (iterations > 0) {
|
|
mat.multiply(itemData.transformers[k].mProps.v);
|
|
iterations -= 1;
|
|
k -= 1;
|
|
}
|
|
}
|
|
} else {
|
|
mat = _identityMatrix;
|
|
}
|
|
paths = itemData.sh.paths;
|
|
jLen = paths._length;
|
|
if (redraw) {
|
|
pathStringTransformed = '';
|
|
for (j = 0; j < jLen; j += 1) {
|
|
pathNodes = paths.shapes[j];
|
|
if (pathNodes && pathNodes._length) {
|
|
pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
|
|
}
|
|
}
|
|
itemData.caches[l] = pathStringTransformed;
|
|
} else {
|
|
pathStringTransformed = itemData.caches[l];
|
|
}
|
|
itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
|
|
itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
|
|
}
|
|
}
|
|
|
|
function renderFill(styleData, itemData, isFirstFrame) {
|
|
var styleElem = itemData.style;
|
|
|
|
if (itemData.c._mdf || isFirstFrame) {
|
|
styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
|
|
}
|
|
if (itemData.o._mdf || isFirstFrame) {
|
|
styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
|
|
}
|
|
}
|
|
|
|
function renderGradientStroke(styleData, itemData, isFirstFrame) {
|
|
renderGradient(styleData, itemData, isFirstFrame);
|
|
renderStroke(styleData, itemData, isFirstFrame);
|
|
}
|
|
|
|
function renderGradient(styleData, itemData, isFirstFrame) {
|
|
var gfill = itemData.gf;
|
|
var hasOpacity = itemData.g._hasOpacity;
|
|
var pt1 = itemData.s.v;
|
|
var pt2 = itemData.e.v;
|
|
|
|
if (itemData.o._mdf || isFirstFrame) {
|
|
var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
|
|
itemData.style.pElem.setAttribute(attr, itemData.o.v);
|
|
}
|
|
if (itemData.s._mdf || isFirstFrame) {
|
|
var attr1 = styleData.t === 1 ? 'x1' : 'cx';
|
|
var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
|
|
gfill.setAttribute(attr1, pt1[0]);
|
|
gfill.setAttribute(attr2, pt1[1]);
|
|
if (hasOpacity && !itemData.g._collapsable) {
|
|
itemData.of.setAttribute(attr1, pt1[0]);
|
|
itemData.of.setAttribute(attr2, pt1[1]);
|
|
}
|
|
}
|
|
var stops;
|
|
var i;
|
|
var len;
|
|
var stop;
|
|
if (itemData.g._cmdf || isFirstFrame) {
|
|
stops = itemData.cst;
|
|
var cValues = itemData.g.c;
|
|
len = stops.length;
|
|
for (i = 0; i < len; i += 1) {
|
|
stop = stops[i];
|
|
stop.setAttribute('offset', cValues[i * 4] + '%');
|
|
stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
|
|
}
|
|
}
|
|
if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
|
|
var oValues = itemData.g.o;
|
|
if (itemData.g._collapsable) {
|
|
stops = itemData.cst;
|
|
} else {
|
|
stops = itemData.ost;
|
|
}
|
|
len = stops.length;
|
|
for (i = 0; i < len; i += 1) {
|
|
stop = stops[i];
|
|
if (!itemData.g._collapsable) {
|
|
stop.setAttribute('offset', oValues[i * 2] + '%');
|
|
}
|
|
stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
|
|
}
|
|
}
|
|
if (styleData.t === 1) {
|
|
if (itemData.e._mdf || isFirstFrame) {
|
|
gfill.setAttribute('x2', pt2[0]);
|
|
gfill.setAttribute('y2', pt2[1]);
|
|
if (hasOpacity && !itemData.g._collapsable) {
|
|
itemData.of.setAttribute('x2', pt2[0]);
|
|
itemData.of.setAttribute('y2', pt2[1]);
|
|
}
|
|
}
|
|
} else {
|
|
var rad;
|
|
if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
|
|
rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
|
|
gfill.setAttribute('r', rad);
|
|
if (hasOpacity && !itemData.g._collapsable) {
|
|
itemData.of.setAttribute('r', rad);
|
|
}
|
|
}
|
|
if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
|
|
if (!rad) {
|
|
rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
|
|
}
|
|
var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
|
|
|
|
var percent = itemData.h.v;
|
|
if (percent >= 1) {
|
|
percent = 0.99;
|
|
} else if (percent <= -1) {
|
|
percent = -0.99;
|
|
}
|
|
var dist = rad * percent;
|
|
var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
|
|
var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
|
|
gfill.setAttribute('fx', x);
|
|
gfill.setAttribute('fy', y);
|
|
if (hasOpacity && !itemData.g._collapsable) {
|
|
itemData.of.setAttribute('fx', x);
|
|
itemData.of.setAttribute('fy', y);
|
|
}
|
|
}
|
|
// gfill.setAttribute('fy','200');
|
|
}
|
|
}
|
|
|
|
function renderStroke(styleData, itemData, isFirstFrame) {
|
|
var styleElem = itemData.style;
|
|
var d = itemData.d;
|
|
if (d && (d._mdf || isFirstFrame) && d.dashStr) {
|
|
styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
|
|
styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
|
|
}
|
|
if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
|
|
styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
|
|
}
|
|
if (itemData.o._mdf || isFirstFrame) {
|
|
styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
|
|
}
|
|
if (itemData.w._mdf || isFirstFrame) {
|
|
styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
|
|
if (styleElem.msElem) {
|
|
styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
|
|
}
|
|
}
|
|
}
|
|
|
|
return ob;
|
|
}());
|
|
|
|
export default SVGElementsRenderer;
|