Source: aftereffect/shapes/shapes/ShapeProperty.js

  1. import BezierFactory from '../lib/BezierEaser';
  2. import shape_pool from '../pooling/shape_pool';
  3. import shapeCollection_pool from '../pooling/shapeCollection_pool';
  4. import DynamicPropertyContainer from '../helpers/dynamicProperties';
  5. import PropertyFactory from '../PropertyFactory';
  6. const initFrame = -999999;
  7. const degToRads = Math.PI/180;
  8. /**
  9. * a
  10. */
  11. class BaseShapeProperty {
  12. /**
  13. * a
  14. * @param {*} frameNum a
  15. * @param {*} previousValue a
  16. * @param {*} caching a
  17. */
  18. interpolateShape(frameNum, previousValue, caching) {
  19. let iterationIndex = caching.lastIndex;
  20. let keyPropS;
  21. let keyPropE;
  22. let isHold;
  23. let perc;
  24. const kf = this.keyframes;
  25. if (frameNum < kf[0].t-this.offsetTime) {
  26. keyPropS = kf[0].s[0];
  27. isHold = true;
  28. iterationIndex = 0;
  29. } else if (frameNum >= kf[kf.length - 1].t-this.offsetTime) {
  30. keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
  31. // /*if(kf[kf.length - 1].s){
  32. // keyPropS = kf[kf.length - 1].s[0];
  33. // }else{
  34. // keyPropS = kf[kf.length - 2].e[0];
  35. // }*/
  36. isHold = true;
  37. } else {
  38. let i = iterationIndex;
  39. const len = kf.length- 1;
  40. let flag = true;
  41. let keyData;
  42. let nextKeyData;
  43. while (flag) {
  44. keyData = kf[i];
  45. nextKeyData = kf[i+1];
  46. if ((nextKeyData.t - this.offsetTime) > frameNum) {
  47. break;
  48. }
  49. if (i < len - 1) {
  50. i += 1;
  51. } else {
  52. flag = false;
  53. }
  54. }
  55. isHold = keyData.h === 1;
  56. iterationIndex = i;
  57. if (!isHold) {
  58. if (frameNum >= nextKeyData.t-this.offsetTime) {
  59. perc = 1;
  60. } else if (frameNum < keyData.t-this.offsetTime) {
  61. perc = 0;
  62. } else {
  63. let fnc;
  64. if (keyData.__fnct) {
  65. fnc = keyData.__fnct;
  66. } else {
  67. fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
  68. keyData.__fnct = fnc;
  69. }
  70. perc = fnc((frameNum-(keyData.t-this.offsetTime))/((nextKeyData.t-this.offsetTime)-(keyData.t-this.offsetTime)));
  71. }
  72. keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
  73. }
  74. keyPropS = keyData.s[0];
  75. }
  76. const jLen = previousValue._length;
  77. const kLen = keyPropS.i[0].length;
  78. let vertexValue;
  79. caching.lastIndex = iterationIndex;
  80. for (let j = 0; j < jLen; j++) {
  81. for (let k = 0; k < kLen; k++) {
  82. vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k]+(keyPropE.i[j][k]-keyPropS.i[j][k])*perc;
  83. previousValue.i[j][k] = vertexValue;
  84. vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k]+(keyPropE.o[j][k]-keyPropS.o[j][k])*perc;
  85. previousValue.o[j][k] = vertexValue;
  86. vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k]+(keyPropE.v[j][k]-keyPropS.v[j][k])*perc;
  87. previousValue.v[j][k] = vertexValue;
  88. }
  89. }
  90. }
  91. /**
  92. * a
  93. * @return {*}
  94. */
  95. interpolateShapeCurrentTime(_frameNum) {
  96. const frameNum = _frameNum - this.offsetTime;
  97. const initTime = this.keyframes[0].t - this.offsetTime;
  98. const endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
  99. const lastFrame = this._caching.lastFrame;
  100. if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
  101. this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
  102. this.interpolateShape(frameNum, this.pv, this._caching);
  103. }
  104. this._caching.lastFrame = frameNum;
  105. return this.pv;
  106. }
  107. /**
  108. * a
  109. */
  110. resetShape() {
  111. this.paths = this.localShapeCollection;
  112. }
  113. /**
  114. * a
  115. * @param {*} shape1 a
  116. * @param {*} shape2 a
  117. * @return {*}
  118. */
  119. shapesEqual(shape1, shape2) {
  120. if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
  121. return false;
  122. }
  123. const len = shape1._length;
  124. for (let i = 0; i < len; i += 1) {
  125. if (shape1.v[i][0] !== shape2.v[i][0]
  126. || shape1.v[i][1] !== shape2.v[i][1]
  127. || shape1.o[i][0] !== shape2.o[i][0]
  128. || shape1.o[i][1] !== shape2.o[i][1]
  129. || shape1.i[i][0] !== shape2.i[i][0]
  130. || shape1.i[i][1] !== shape2.i[i][1]) {
  131. return false;
  132. }
  133. }
  134. return true;
  135. }
  136. /**
  137. * a
  138. * @param {*} newPath a
  139. */
  140. setVValue(newPath) {
  141. if (!this.shapesEqual(this.v, newPath)) {
  142. this.v = shape_pool.clone(newPath);
  143. this.localShapeCollection.releaseShapes();
  144. this.localShapeCollection.addShape(this.v);
  145. this._mdf = true;
  146. this.paths = this.localShapeCollection;
  147. }
  148. }
  149. /**
  150. * a
  151. */
  152. processEffectsSequence() {
  153. if (!this.effectsSequence.length) {
  154. return;
  155. }
  156. if (this.lock) {
  157. this.setVValue(this.pv);
  158. return;
  159. }
  160. this.lock = true;
  161. this._mdf = false;
  162. let finalValue = this.kf ? this.pv : this.data.ks ? this.data.ks.k : this.data.pt.k;
  163. const len = this.effectsSequence.length;
  164. for (let i = 0; i < len; i += 1) {
  165. finalValue = this.effectsSequence[i](finalValue);
  166. }
  167. this.setVValue(finalValue);
  168. this.lock = false;
  169. }
  170. }
  171. /**
  172. * a
  173. */
  174. class ShapeProperty extends BaseShapeProperty {
  175. /**
  176. * a
  177. * @param {*} elem a
  178. * @param {*} data a
  179. * @param {*} type a
  180. */
  181. constructor(elem, data, type) {
  182. super();
  183. this.propType = 'shape';
  184. this.container = elem;
  185. this.elem = elem;
  186. this.data = data;
  187. this.k = false;
  188. this.kf = false;
  189. this._mdf = false;
  190. const pathData = type === 3 ? data.pt.k : data.ks.k;
  191. this.v = shape_pool.clone(pathData);
  192. this.pv = shape_pool.clone(this.v);
  193. this.localShapeCollection = shapeCollection_pool.newShapeCollection();
  194. this.paths = this.localShapeCollection;
  195. this.paths.addShape(this.v);
  196. this.reset = this.resetShape;
  197. this.effectsSequence = [];
  198. this.getValue = this.processEffectsSequence;
  199. }
  200. /**
  201. * a
  202. * @param {*} effectFunction a
  203. */
  204. addEffect(effectFunction) {
  205. this.effectsSequence.push(effectFunction);
  206. this.container.addDynamicProperty(this);
  207. }
  208. }
  209. /**
  210. * a
  211. */
  212. class KeyframedShapeProperty extends BaseShapeProperty {
  213. /**
  214. * a
  215. * @param {*} elem a
  216. * @param {*} data a
  217. * @param {*} type a
  218. */
  219. constructor(elem, data, type) {
  220. super();
  221. this.propType = 'shape';
  222. this.elem = elem;
  223. this.container = elem;
  224. this.offsetTime = elem.data.st;
  225. this.keyframes = type === 3 ? data.pt.k : data.ks.k;
  226. this.k = true;
  227. this.kf = true;
  228. const len = this.keyframes[0].s[0].i.length;
  229. this.v = shape_pool.newElement();
  230. this.v.setPathData(this.keyframes[0].s[0].c, len);
  231. this.pv = shape_pool.clone(this.v);
  232. this.localShapeCollection = shapeCollection_pool.newShapeCollection();
  233. this.paths = this.localShapeCollection;
  234. this.paths.addShape(this.v);
  235. this.lastFrame = initFrame;
  236. this.reset = this.resetShape;
  237. this._caching = { lastFrame: initFrame, lastIndex: 0 };
  238. this.effectsSequence = [this.interpolateShapeCurrentTime.bind(this)];
  239. this.getValue = this.processEffectsSequence;
  240. }
  241. /**
  242. * a
  243. * @param {*} effectFunction a
  244. */
  245. addEffect(effectFunction) {
  246. this.effectsSequence.push(effectFunction);
  247. this.container.addDynamicProperty(this);
  248. }
  249. }
  250. const roundCorner = 0.5519;
  251. const cPoint = roundCorner;
  252. /**
  253. * a
  254. */
  255. class EllShapeProperty extends DynamicPropertyContainer {
  256. /**
  257. * a
  258. * @param {*} elem a
  259. * @param {*} data a
  260. */
  261. constructor(elem, data) {
  262. super();
  263. // /*this.v = {
  264. // v: createSizedArray(4),
  265. // i: createSizedArray(4),
  266. // o: createSizedArray(4),
  267. // c: true
  268. // };*/
  269. this.v = shape_pool.newElement();
  270. this.v.setPathData(true, 4);
  271. this.localShapeCollection = shapeCollection_pool.newShapeCollection();
  272. this.paths = this.localShapeCollection;
  273. this.localShapeCollection.addShape(this.v);
  274. this.d = data.d;
  275. this.elem = elem;
  276. this.initDynamicPropertyContainer(elem);
  277. this.p = PropertyFactory(elem, data.p, 1, 0, this);
  278. this.s = PropertyFactory(elem, data.s, 1, 0, this);
  279. if (this.dynamicProperties.length) {
  280. this.k = true;
  281. } else {
  282. this.k = false;
  283. this.convertEllToPath();
  284. }
  285. }
  286. /**
  287. * a
  288. */
  289. reset() {
  290. this.paths = this.localShapeCollection;
  291. }
  292. /**
  293. * a
  294. */
  295. getValue(frameNum) {
  296. this.iterateDynamicProperties(frameNum);
  297. if (this._mdf) {
  298. this.convertEllToPath();
  299. }
  300. }
  301. /**
  302. * a
  303. */
  304. convertEllToPath() {
  305. const p0 = this.p.v[0];
  306. const p1 = this.p.v[1];
  307. const s0 = this.s.v[0]/2;
  308. const s1 = this.s.v[1]/2;
  309. const _cw = this.d !== 3;
  310. const _v = this.v;
  311. _v.v[0][0] = p0;
  312. _v.v[0][1] = p1 - s1;
  313. _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
  314. _v.v[1][1] = p1;
  315. _v.v[2][0] = p0;
  316. _v.v[2][1] = p1 + s1;
  317. _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
  318. _v.v[3][1] = p1;
  319. _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
  320. _v.i[0][1] = p1 - s1;
  321. _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
  322. _v.i[1][1] = p1 - s1 * cPoint;
  323. _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
  324. _v.i[2][1] = p1 + s1;
  325. _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
  326. _v.i[3][1] = p1 + s1 * cPoint;
  327. _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
  328. _v.o[0][1] = p1 - s1;
  329. _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
  330. _v.o[1][1] = p1 + s1 * cPoint;
  331. _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
  332. _v.o[2][1] = p1 + s1;
  333. _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
  334. _v.o[3][1] = p1 - s1 * cPoint;
  335. }
  336. }
  337. /**
  338. * a
  339. */
  340. class StarShapeProperty extends DynamicPropertyContainer {
  341. /**
  342. * a
  343. * @param {*} elem a
  344. * @param {*} data a
  345. */
  346. constructor(elem, data) {
  347. super();
  348. this.v = shape_pool.newElement();
  349. this.v.setPathData(true, 0);
  350. this.elem = elem;
  351. this.data = data;
  352. this.d = data.d;
  353. this.initDynamicPropertyContainer(elem);
  354. if (data.sy === 1) {
  355. this.ir = PropertyFactory(elem, data.ir, 0, 0, this);
  356. this.is = PropertyFactory(elem, data.is, 0, 0.01, this);
  357. this.convertToPath = this.convertStarToPath;
  358. } else {
  359. this.convertToPath = this.convertPolygonToPath;
  360. }
  361. this.pt = PropertyFactory(elem, data.pt, 0, 0, this);
  362. this.p = PropertyFactory(elem, data.p, 1, 0, this);
  363. this.r = PropertyFactory(elem, data.r, 0, degToRads, this);
  364. this.or = PropertyFactory(elem, data.or, 0, 0, this);
  365. this.os = PropertyFactory(elem, data.os, 0, 0.01, this);
  366. this.localShapeCollection = shapeCollection_pool.newShapeCollection();
  367. this.localShapeCollection.addShape(this.v);
  368. this.paths = this.localShapeCollection;
  369. if (this.dynamicProperties.length) {
  370. this.k = true;
  371. } else {
  372. this.k = false;
  373. this.convertToPath();
  374. }
  375. }
  376. /**
  377. * a
  378. */
  379. reset() {
  380. this.paths = this.localShapeCollection;
  381. }
  382. /**
  383. * a
  384. */
  385. getValue(frameNum) {
  386. this.iterateDynamicProperties(frameNum);
  387. if (this._mdf) {
  388. this.convertToPath();
  389. }
  390. }
  391. /**
  392. * a
  393. */
  394. convertStarToPath() {
  395. const numPts = Math.floor(this.pt.v)*2;
  396. const angle = Math.PI*2/numPts;
  397. // /*this.v.v.length = numPts;
  398. // this.v.i.length = numPts;
  399. // this.v.o.length = numPts;*/
  400. let longFlag = true;
  401. const longRad = this.or.v;
  402. const shortRad = this.ir.v;
  403. const longRound = this.os.v;
  404. const shortRound = this.is.v;
  405. const longPerimSegment = 2*Math.PI*longRad/(numPts*2);
  406. const shortPerimSegment = 2*Math.PI*shortRad/(numPts*2);
  407. let currentAng = -Math.PI/ 2;
  408. currentAng += this.r.v;
  409. const dir = this.data.d === 3 ? -1 : 1;
  410. this.v._length = 0;
  411. for (let i = 0; i < numPts; i++) {
  412. const rad = longFlag ? longRad : shortRad;
  413. const roundness = longFlag ? longRound : shortRound;
  414. const perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
  415. let x = rad * Math.cos(currentAng);
  416. let y = rad * Math.sin(currentAng);
  417. const ox = x === 0 && y === 0 ? 0 : y/Math.sqrt(x*x + y*y);
  418. const oy = x === 0 && y === 0 ? 0 : -x/Math.sqrt(x*x + y*y);
  419. x += + this.p.v[0];
  420. y += + this.p.v[1];
  421. this.v.setTripleAt(x, y, x-ox*perimSegment*roundness*dir, y-oy*perimSegment*roundness*dir, x+ox*perimSegment*roundness*dir, y+oy*perimSegment*roundness*dir, i, true);
  422. // /*this.v.v[i] = [x,y];
  423. // this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
  424. // this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
  425. // this.v._length = numPts;*/
  426. longFlag = !longFlag;
  427. currentAng += angle*dir;
  428. }
  429. }
  430. /**
  431. * a
  432. */
  433. convertPolygonToPath() {
  434. const numPts = Math.floor(this.pt.v);
  435. const angle = Math.PI*2/numPts;
  436. const rad = this.or.v;
  437. const roundness = this.os.v;
  438. const perimSegment = 2*Math.PI*rad/(numPts*4);
  439. let currentAng = -Math.PI/ 2;
  440. const dir = this.data.d === 3 ? -1 : 1;
  441. currentAng += this.r.v;
  442. this.v._length = 0;
  443. for (let i = 0; i < numPts; i++) {
  444. let x = rad * Math.cos(currentAng);
  445. let y = rad * Math.sin(currentAng);
  446. const ox = x === 0 && y === 0 ? 0 : y/Math.sqrt(x*x + y*y);
  447. const oy = x === 0 && y === 0 ? 0 : -x/Math.sqrt(x*x + y*y);
  448. x += + this.p.v[0];
  449. y += + this.p.v[1];
  450. this.v.setTripleAt(x, y, x-ox*perimSegment*roundness*dir, y-oy*perimSegment*roundness*dir, x+ox*perimSegment*roundness*dir, y+oy*perimSegment*roundness*dir, i, true);
  451. currentAng += angle*dir;
  452. }
  453. this.paths.length = 0;
  454. this.paths[0] = this.v;
  455. }
  456. }
  457. /**
  458. * a
  459. */
  460. class RectShapeProperty extends DynamicPropertyContainer {
  461. /**
  462. * a
  463. * @param {*} elem a
  464. * @param {*} data a
  465. */
  466. constructor(elem, data) {
  467. super();
  468. this.v = shape_pool.newElement();
  469. this.v.c = true;
  470. this.localShapeCollection = shapeCollection_pool.newShapeCollection();
  471. this.localShapeCollection.addShape(this.v);
  472. this.paths = this.localShapeCollection;
  473. this.elem = elem;
  474. this.d = data.d;
  475. this.initDynamicPropertyContainer(elem);
  476. this.p = PropertyFactory(elem, data.p, 1, 0, this);
  477. this.s = PropertyFactory(elem, data.s, 1, 0, this);
  478. this.r = PropertyFactory(elem, data.r, 0, 0, this);
  479. if (this.dynamicProperties.length) {
  480. this.k = true;
  481. } else {
  482. this.k = false;
  483. this.convertRectToPath();
  484. }
  485. }
  486. /**
  487. * a
  488. */
  489. reset() {
  490. this.paths = this.localShapeCollection;
  491. }
  492. /**
  493. * a
  494. */
  495. convertRectToPath() {
  496. const p0 = this.p.v[0];
  497. const p1 = this.p.v[1];
  498. const v0 = this.s.v[0]/2;
  499. const v1 = this.s.v[1]/2;
  500. const round = Math.min(v0, v1, this.r.v);
  501. const cPoint = round*(1-roundCorner);
  502. this.v._length = 0;
  503. if (this.d === 2 || this.d === 1) {
  504. this.v.setTripleAt(p0+v0, p1-v1+round, p0+v0, p1-v1+round, p0+v0, p1-v1+cPoint, 0, true);
  505. this.v.setTripleAt(p0+v0, p1+v1-round, p0+v0, p1+v1-cPoint, p0+v0, p1+v1-round, 1, true);
  506. if (round!== 0) {
  507. this.v.setTripleAt(p0+v0-round, p1+v1, p0+v0-round, p1+v1, p0+v0-cPoint, p1+v1, 2, true);
  508. this.v.setTripleAt(p0-v0+round, p1+v1, p0-v0+cPoint, p1+v1, p0-v0+round, p1+v1, 3, true);
  509. this.v.setTripleAt(p0-v0, p1+v1-round, p0-v0, p1+v1-round, p0-v0, p1+v1-cPoint, 4, true);
  510. this.v.setTripleAt(p0-v0, p1-v1+round, p0-v0, p1-v1+cPoint, p0-v0, p1-v1+round, 5, true);
  511. this.v.setTripleAt(p0-v0+round, p1-v1, p0-v0+round, p1-v1, p0-v0+cPoint, p1-v1, 6, true);
  512. this.v.setTripleAt(p0+v0-round, p1-v1, p0+v0-cPoint, p1-v1, p0+v0-round, p1-v1, 7, true);
  513. } else {
  514. this.v.setTripleAt(p0-v0, p1+v1, p0-v0+cPoint, p1+v1, p0-v0, p1+v1, 2);
  515. this.v.setTripleAt(p0-v0, p1-v1, p0-v0, p1-v1+cPoint, p0-v0, p1-v1, 3);
  516. }
  517. } else {
  518. this.v.setTripleAt(p0+v0, p1-v1+round, p0+v0, p1-v1+cPoint, p0+v0, p1-v1+round, 0, true);
  519. if (round!== 0) {
  520. this.v.setTripleAt(p0+v0-round, p1-v1, p0+v0-round, p1-v1, p0+v0-cPoint, p1-v1, 1, true);
  521. this.v.setTripleAt(p0-v0+round, p1-v1, p0-v0+cPoint, p1-v1, p0-v0+round, p1-v1, 2, true);
  522. this.v.setTripleAt(p0-v0, p1-v1+round, p0-v0, p1-v1+round, p0-v0, p1-v1+cPoint, 3, true);
  523. this.v.setTripleAt(p0-v0, p1+v1-round, p0-v0, p1+v1-cPoint, p0-v0, p1+v1-round, 4, true);
  524. this.v.setTripleAt(p0-v0+round, p1+v1, p0-v0+round, p1+v1, p0-v0+cPoint, p1+v1, 5, true);
  525. this.v.setTripleAt(p0+v0-round, p1+v1, p0+v0-cPoint, p1+v1, p0+v0-round, p1+v1, 6, true);
  526. this.v.setTripleAt(p0+v0, p1+v1-round, p0+v0, p1+v1-round, p0+v0, p1+v1-cPoint, 7, true);
  527. } else {
  528. this.v.setTripleAt(p0-v0, p1-v1, p0-v0+cPoint, p1-v1, p0-v0, p1-v1, 1, true);
  529. this.v.setTripleAt(p0-v0, p1+v1, p0-v0, p1+v1-cPoint, p0-v0, p1+v1, 2, true);
  530. this.v.setTripleAt(p0+v0, p1+v1, p0+v0-cPoint, p1+v1, p0+v0, p1+v1, 3, true);
  531. }
  532. }
  533. }
  534. /**
  535. * a
  536. * @param {*} frameNum a
  537. */
  538. getValue(frameNum) {
  539. this.iterateDynamicProperties(frameNum);
  540. if (this._mdf) {
  541. this.convertRectToPath();
  542. }
  543. }
  544. }
  545. /**
  546. * a
  547. * @param {*} elem a
  548. * @param {*} data a
  549. * @param {*} type a
  550. * @return {*}
  551. */
  552. function getShapeProp(elem, data, type) {
  553. let prop;
  554. if (type === 3 || type === 4) {
  555. const dataProp = type === 3 ? data.pt : data.ks;
  556. const keys = dataProp.k;
  557. if (keys.length) {
  558. prop = new KeyframedShapeProperty(elem, data, type);
  559. } else {
  560. prop = new ShapeProperty(elem, data, type);
  561. }
  562. } else if (type === 5) {
  563. prop = new RectShapeProperty(elem, data);
  564. } else if (type === 6) {
  565. prop = new EllShapeProperty(elem, data);
  566. } else if (type === 7) {
  567. prop = new StarShapeProperty(elem, data);
  568. }
  569. if (prop.k) {
  570. elem.addDynamicProperty(prop);
  571. }
  572. return prop;
  573. }
  574. /**
  575. * a
  576. * @return {*}
  577. */
  578. function getConstructorFunction() {
  579. return ShapeProperty;
  580. }
  581. /**
  582. * a
  583. * @return {*}
  584. */
  585. function getKeyframedConstructorFunction() {
  586. return KeyframedShapeProperty;
  587. }
  588. export default { getShapeProp, getConstructorFunction, getKeyframedConstructorFunction };