123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521 |
- import {
- degToRads,
- bmFloor,
- } from '../../utils/common';
- import {
- extendPrototype,
- } from '../../utils/functionExtensions';
- import PropertyFactory from '../../utils/PropertyFactory';
- import RenderableElement from '../helpers/RenderableElement';
- import BaseElement from '../BaseElement';
- import TransformElement from '../helpers/TransformElement';
- import HierarchyElement from '../helpers/HierarchyElement';
- import FrameElement from '../helpers/FrameElement';
- import RenderableDOMElement from '../helpers/RenderableDOMElement';
- import ShapeTransformManager from '../helpers/shapes/ShapeTransformManager';
- import CVBaseElement from './CVBaseElement';
- import IShapeElement from '../ShapeElement';
- import GradientProperty from '../../utils/shapes/GradientProperty';
- import DashProperty from '../../utils/shapes/DashProperty';
- import TransformPropertyFactory from '../../utils/TransformProperty';
- import CVShapeData from '../helpers/shapes/CVShapeData';
- import { ShapeModifiers } from '../../utils/shapes/ShapeModifiers';
- import {
- lineCapEnum,
- lineJoinEnum,
- } from '../../utils/helpers/shapeEnums';
- function CVShapeElement(data, globalData, comp) {
- this.shapes = [];
- this.shapesData = data.shapes;
- this.stylesList = [];
- this.itemsData = [];
- this.prevViewData = [];
- this.shapeModifiers = [];
- this.processedElements = [];
- this.transformsManager = new ShapeTransformManager();
- this.initElement(data, globalData, comp);
- }
- extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
- CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
- CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
- CVShapeElement.prototype.dashResetter = [];
- CVShapeElement.prototype.createContent = function () {
- this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
- };
- CVShapeElement.prototype.createStyleElement = function (data, transforms) {
- var styleElem = {
- data: data,
- type: data.ty,
- preTransforms: this.transformsManager.addTransformSequence(transforms),
- transforms: [],
- elements: [],
- closed: data.hd === true,
- };
- var elementData = {};
- if (data.ty === 'fl' || data.ty === 'st') {
- elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
- if (!elementData.c.k) {
- styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
- }
- } else if (data.ty === 'gf' || data.ty === 'gs') {
- elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
- elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
- elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
- elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
- elementData.g = new GradientProperty(this, data.g, this);
- }
- elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
- if (data.ty === 'st' || data.ty === 'gs') {
- styleElem.lc = lineCapEnum[data.lc || 2];
- styleElem.lj = lineJoinEnum[data.lj || 2];
- if (data.lj == 1) { // eslint-disable-line eqeqeq
- styleElem.ml = data.ml;
- }
- elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
- if (!elementData.w.k) {
- styleElem.wi = elementData.w.v;
- }
- if (data.d) {
- var d = new DashProperty(this, data.d, 'canvas', this);
- elementData.d = d;
- if (!elementData.d.k) {
- styleElem.da = elementData.d.dashArray;
- styleElem.do = elementData.d.dashoffset[0];
- }
- }
- } else {
- styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
- }
- this.stylesList.push(styleElem);
- elementData.style = styleElem;
- return elementData;
- };
- CVShapeElement.prototype.createGroupElement = function () {
- var elementData = {
- it: [],
- prevViewData: [],
- };
- return elementData;
- };
- CVShapeElement.prototype.createTransformElement = function (data) {
- var elementData = {
- transform: {
- opacity: 1,
- _opMdf: false,
- key: this.transformsManager.getNewKey(),
- op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
- mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
- },
- };
- return elementData;
- };
- CVShapeElement.prototype.createShapeElement = function (data) {
- var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
- this.shapes.push(elementData);
- this.addShapeToModifiers(elementData);
- return elementData;
- };
- CVShapeElement.prototype.reloadShapes = function () {
- this._isFirstFrame = true;
- var i;
- var len = this.itemsData.length;
- for (i = 0; i < len; i += 1) {
- this.prevViewData[i] = this.itemsData[i];
- }
- this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
- len = this.dynamicProperties.length;
- for (i = 0; i < len; i += 1) {
- this.dynamicProperties[i].getValue();
- }
- this.renderModifiers();
- this.transformsManager.processSequences(this._isFirstFrame);
- };
- CVShapeElement.prototype.addTransformToStyleList = function (transform) {
- var i;
- var len = this.stylesList.length;
- for (i = 0; i < len; i += 1) {
- if (!this.stylesList[i].closed) {
- this.stylesList[i].transforms.push(transform);
- }
- }
- };
- CVShapeElement.prototype.removeTransformFromStyleList = function () {
- var i;
- var len = this.stylesList.length;
- for (i = 0; i < len; i += 1) {
- if (!this.stylesList[i].closed) {
- this.stylesList[i].transforms.pop();
- }
- }
- };
- CVShapeElement.prototype.closeStyles = function (styles) {
- var i;
- var len = styles.length;
- for (i = 0; i < len; i += 1) {
- styles[i].closed = true;
- }
- };
- CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
- var i;
- var len = arr.length - 1;
- var j;
- var jLen;
- var ownStyles = [];
- var ownModifiers = [];
- var processedPos;
- var modifier;
- var currentTransform;
- var ownTransforms = [].concat(transforms);
- for (i = len; i >= 0; i -= 1) {
- processedPos = this.searchProcessedElement(arr[i]);
- if (!processedPos) {
- arr[i]._shouldRender = shouldRender;
- } else {
- itemsData[i] = prevViewData[processedPos - 1];
- }
- if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
- if (!processedPos) {
- itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
- } else {
- itemsData[i].style.closed = false;
- }
- ownStyles.push(itemsData[i].style);
- } else if (arr[i].ty === 'gr') {
- if (!processedPos) {
- itemsData[i] = this.createGroupElement(arr[i]);
- } else {
- jLen = itemsData[i].it.length;
- for (j = 0; j < jLen; j += 1) {
- itemsData[i].prevViewData[j] = itemsData[i].it[j];
- }
- }
- this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
- } else if (arr[i].ty === 'tr') {
- if (!processedPos) {
- currentTransform = this.createTransformElement(arr[i]);
- itemsData[i] = currentTransform;
- }
- ownTransforms.push(itemsData[i]);
- this.addTransformToStyleList(itemsData[i]);
- } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
- if (!processedPos) {
- itemsData[i] = this.createShapeElement(arr[i]);
- }
- } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
- if (!processedPos) {
- modifier = ShapeModifiers.getModifier(arr[i].ty);
- modifier.init(this, arr[i]);
- itemsData[i] = modifier;
- this.shapeModifiers.push(modifier);
- } else {
- modifier = itemsData[i];
- modifier.closed = false;
- }
- ownModifiers.push(modifier);
- } else if (arr[i].ty === 'rp') {
- if (!processedPos) {
- modifier = ShapeModifiers.getModifier(arr[i].ty);
- itemsData[i] = modifier;
- modifier.init(this, arr, i, itemsData);
- this.shapeModifiers.push(modifier);
- shouldRender = false;
- } else {
- modifier = itemsData[i];
- modifier.closed = true;
- }
- ownModifiers.push(modifier);
- }
- this.addProcessedElement(arr[i], i + 1);
- }
- this.removeTransformFromStyleList();
- this.closeStyles(ownStyles);
- len = ownModifiers.length;
- for (i = 0; i < len; i += 1) {
- ownModifiers[i].closed = true;
- }
- };
- CVShapeElement.prototype.renderInnerContent = function () {
- this.transformHelper.opacity = 1;
- this.transformHelper._opMdf = false;
- this.renderModifiers();
- this.transformsManager.processSequences(this._isFirstFrame);
- this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
- };
- CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
- if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
- groupTransform.opacity = parentTransform.opacity;
- groupTransform.opacity *= groupTransform.op.v;
- groupTransform._opMdf = true;
- }
- };
- CVShapeElement.prototype.drawLayer = function () {
- var i;
- var len = this.stylesList.length;
- var j;
- var jLen;
- var k;
- var kLen;
- var elems;
- var nodes;
- var renderer = this.globalData.renderer;
- var ctx = this.globalData.canvasContext;
- var type;
- var currentStyle;
- for (i = 0; i < len; i += 1) {
- currentStyle = this.stylesList[i];
- type = currentStyle.type;
- // Skipping style when
- // Stroke width equals 0
- // style should not be rendered (extra unused repeaters)
- // current opacity equals 0
- // global opacity equals 0
- if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
- renderer.save();
- elems = currentStyle.elements;
- if (type === 'st' || type === 'gs') {
- renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
- // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
- renderer.ctxLineWidth(currentStyle.wi);
- // ctx.lineWidth = currentStyle.wi;
- renderer.ctxLineCap(currentStyle.lc);
- // ctx.lineCap = currentStyle.lc;
- renderer.ctxLineJoin(currentStyle.lj);
- // ctx.lineJoin = currentStyle.lj;
- renderer.ctxMiterLimit(currentStyle.ml || 0);
- // ctx.miterLimit = currentStyle.ml || 0;
- } else {
- renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
- // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
- }
- renderer.ctxOpacity(currentStyle.coOp);
- if (type !== 'st' && type !== 'gs') {
- ctx.beginPath();
- }
- renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
- jLen = elems.length;
- for (j = 0; j < jLen; j += 1) {
- if (type === 'st' || type === 'gs') {
- ctx.beginPath();
- if (currentStyle.da) {
- ctx.setLineDash(currentStyle.da);
- ctx.lineDashOffset = currentStyle.do;
- }
- }
- nodes = elems[j].trNodes;
- kLen = nodes.length;
- for (k = 0; k < kLen; k += 1) {
- if (nodes[k].t === 'm') {
- ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
- } else if (nodes[k].t === 'c') {
- ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
- } else {
- ctx.closePath();
- }
- }
- if (type === 'st' || type === 'gs') {
- // ctx.stroke();
- renderer.ctxStroke();
- if (currentStyle.da) {
- ctx.setLineDash(this.dashResetter);
- }
- }
- }
- if (type !== 'st' && type !== 'gs') {
- // ctx.fill(currentStyle.r);
- this.globalData.renderer.ctxFill(currentStyle.r);
- }
- renderer.restore();
- }
- }
- };
- CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
- var i;
- var len = items.length - 1;
- var groupTransform;
- groupTransform = parentTransform;
- for (i = len; i >= 0; i -= 1) {
- if (items[i].ty === 'tr') {
- groupTransform = data[i].transform;
- this.renderShapeTransform(parentTransform, groupTransform);
- } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
- this.renderPath(items[i], data[i]);
- } else if (items[i].ty === 'fl') {
- this.renderFill(items[i], data[i], groupTransform);
- } else if (items[i].ty === 'st') {
- this.renderStroke(items[i], data[i], groupTransform);
- } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
- this.renderGradientFill(items[i], data[i], groupTransform);
- } else if (items[i].ty === 'gr') {
- this.renderShape(groupTransform, items[i].it, data[i].it);
- } else if (items[i].ty === 'tm') {
- //
- }
- }
- if (isMain) {
- this.drawLayer();
- }
- };
- CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
- if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
- var shapeNodes = styledShape.trNodes;
- var paths = shape.paths;
- var i;
- var len;
- var j;
- var jLen = paths._length;
- shapeNodes.length = 0;
- var groupTransformMat = styledShape.transforms.finalTransform;
- for (j = 0; j < jLen; j += 1) {
- var pathNodes = paths.shapes[j];
- if (pathNodes && pathNodes.v) {
- len = pathNodes._length;
- for (i = 1; i < len; i += 1) {
- if (i === 1) {
- shapeNodes.push({
- t: 'm',
- p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
- });
- }
- shapeNodes.push({
- t: 'c',
- pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
- });
- }
- if (len === 1) {
- shapeNodes.push({
- t: 'm',
- p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
- });
- }
- if (pathNodes.c && len) {
- shapeNodes.push({
- t: 'c',
- pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
- });
- shapeNodes.push({
- t: 'z',
- });
- }
- }
- }
- styledShape.trNodes = shapeNodes;
- }
- };
- CVShapeElement.prototype.renderPath = function (pathData, itemData) {
- if (pathData.hd !== true && pathData._shouldRender) {
- var i;
- var len = itemData.styledShapes.length;
- for (i = 0; i < len; i += 1) {
- this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
- }
- }
- };
- CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
- var styleElem = itemData.style;
- if (itemData.c._mdf || this._isFirstFrame) {
- styleElem.co = 'rgb('
- + bmFloor(itemData.c.v[0]) + ','
- + bmFloor(itemData.c.v[1]) + ','
- + bmFloor(itemData.c.v[2]) + ')';
- }
- if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
- styleElem.coOp = itemData.o.v * groupTransform.opacity;
- }
- };
- CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
- var styleElem = itemData.style;
- var grd;
- if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
- var ctx = this.globalData.canvasContext;
- var pt1 = itemData.s.v;
- var pt2 = itemData.e.v;
- if (styleData.t === 1) {
- grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
- } else {
- var 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];
- grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
- }
- var i;
- var len = styleData.g.p;
- var cValues = itemData.g.c;
- var opacity = 1;
- for (i = 0; i < len; i += 1) {
- if (itemData.g._hasOpacity && itemData.g._collapsable) {
- opacity = itemData.g.o[i * 2 + 1];
- }
- grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
- }
- styleElem.grd = grd;
- }
- styleElem.coOp = itemData.o.v * groupTransform.opacity;
- };
- CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
- var styleElem = itemData.style;
- var d = itemData.d;
- if (d && (d._mdf || this._isFirstFrame)) {
- styleElem.da = d.dashArray;
- styleElem.do = d.dashoffset[0];
- }
- if (itemData.c._mdf || this._isFirstFrame) {
- styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
- }
- if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
- styleElem.coOp = itemData.o.v * groupTransform.opacity;
- }
- if (itemData.w._mdf || this._isFirstFrame) {
- styleElem.wi = itemData.w.v;
- }
- };
- CVShapeElement.prototype.destroy = function () {
- this.shapesData = null;
- this.globalData = null;
- this.canvasContext = null;
- this.stylesList.length = 0;
- this.itemsData.length = 0;
- };
- export default CVShapeElement;
|