element.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var tslib_1 = require("tslib");
  4. var util_1 = require("@antv/util");
  5. var matrix_util_1 = require("@antv/matrix-util");
  6. var util_2 = require("../util/util");
  7. var matrix_1 = require("../util/matrix");
  8. var base_1 = require("./base");
  9. var transform = matrix_util_1.ext.transform;
  10. var MATRIX = 'matrix';
  11. var CLONE_CFGS = ['zIndex', 'capture', 'visible', 'type'];
  12. // 可以在 toAttrs 中设置,但不属于绘图属性的字段
  13. var RESERVED_PORPS = ['repeat'];
  14. var DELEGATION_SPLIT = ':';
  15. var WILDCARD = '*';
  16. // 需要考虑数组嵌套数组的场景
  17. // 数组嵌套对象的场景不考虑
  18. function _cloneArrayAttr(arr) {
  19. var result = [];
  20. for (var i = 0; i < arr.length; i++) {
  21. if (util_1.isArray(arr[i])) {
  22. result.push([].concat(arr[i]));
  23. }
  24. else {
  25. result.push(arr[i]);
  26. }
  27. }
  28. return result;
  29. }
  30. function getFormatFromAttrs(toAttrs, shape) {
  31. var fromAttrs = {};
  32. var attrs = shape.attrs;
  33. for (var k in toAttrs) {
  34. fromAttrs[k] = attrs[k];
  35. }
  36. return fromAttrs;
  37. }
  38. function getFormatToAttrs(props, shape) {
  39. var toAttrs = {};
  40. var attrs = shape.attr();
  41. util_1.each(props, function (v, k) {
  42. if (RESERVED_PORPS.indexOf(k) === -1 && !util_1.isEqual(attrs[k], v)) {
  43. toAttrs[k] = v;
  44. }
  45. });
  46. return toAttrs;
  47. }
  48. function checkExistedAttrs(animations, animation) {
  49. if (animation.onFrame) {
  50. return animations;
  51. }
  52. var startTime = animation.startTime, delay = animation.delay, duration = animation.duration;
  53. var hasOwnProperty = Object.prototype.hasOwnProperty;
  54. util_1.each(animations, function (item) {
  55. // 后一个动画开始执行的时间 < 前一个动画的结束时间 && 后一个动画的执行时间 > 前一个动画的延迟
  56. if (startTime + delay < item.startTime + item.delay + item.duration && duration > item.delay) {
  57. util_1.each(animation.toAttrs, function (v, k) {
  58. if (hasOwnProperty.call(item.toAttrs, k)) {
  59. delete item.toAttrs[k];
  60. delete item.fromAttrs[k];
  61. }
  62. });
  63. }
  64. });
  65. return animations;
  66. }
  67. var Element = /** @class */ (function (_super) {
  68. tslib_1.__extends(Element, _super);
  69. function Element(cfg) {
  70. var _this = _super.call(this, cfg) || this;
  71. /**
  72. * @protected
  73. * 图形属性
  74. * @type {ShapeAttrs}
  75. */
  76. _this.attrs = {};
  77. var attrs = _this.getDefaultAttrs();
  78. util_1.mix(attrs, cfg.attrs);
  79. _this.attrs = attrs;
  80. _this.initAttrs(attrs);
  81. _this.initAnimate(); // 初始化动画
  82. return _this;
  83. }
  84. // override
  85. Element.prototype.getDefaultCfg = function () {
  86. return {
  87. visible: true,
  88. capture: true,
  89. zIndex: 0,
  90. };
  91. };
  92. /**
  93. * @protected
  94. * 获取默认的属相
  95. */
  96. Element.prototype.getDefaultAttrs = function () {
  97. return {
  98. matrix: this.getDefaultMatrix(),
  99. opacity: 1,
  100. };
  101. };
  102. /**
  103. * @protected
  104. * 一些方法调用会引起画布变化
  105. * @param {ChangeType} changeType 改变的类型
  106. */
  107. Element.prototype.onCanvasChange = function (changeType) { };
  108. /**
  109. * @protected
  110. * 初始化属性,有些属性需要加工
  111. * @param {object} attrs 属性值
  112. */
  113. Element.prototype.initAttrs = function (attrs) { };
  114. /**
  115. * @protected
  116. * 初始化动画
  117. */
  118. Element.prototype.initAnimate = function () {
  119. this.set('animable', true);
  120. this.set('animating', false);
  121. };
  122. Element.prototype.isGroup = function () {
  123. return false;
  124. };
  125. Element.prototype.getParent = function () {
  126. return this.get('parent');
  127. };
  128. Element.prototype.getCanvas = function () {
  129. return this.get('canvas');
  130. };
  131. Element.prototype.attr = function () {
  132. var _a;
  133. var args = [];
  134. for (var _i = 0; _i < arguments.length; _i++) {
  135. args[_i] = arguments[_i];
  136. }
  137. var name = args[0], value = args[1];
  138. if (!name)
  139. return this.attrs;
  140. if (util_1.isObject(name)) {
  141. for (var k in name) {
  142. this.setAttr(k, name[k]);
  143. }
  144. this.afterAttrsChange(name);
  145. return this;
  146. }
  147. if (args.length === 2) {
  148. this.setAttr(name, value);
  149. this.afterAttrsChange((_a = {},
  150. _a[name] = value,
  151. _a));
  152. return this;
  153. }
  154. return this.attrs[name];
  155. };
  156. // 是否被裁剪,被裁剪则不显示,不参与拾取
  157. Element.prototype.isClipped = function (refX, refY) {
  158. var clip = this.getClip();
  159. return clip && !clip.isHit(refX, refY);
  160. };
  161. /**
  162. * 内部设置属性值的接口
  163. * @param {string} name 属性名
  164. * @param {any} value 属性值
  165. */
  166. Element.prototype.setAttr = function (name, value) {
  167. var originValue = this.attrs[name];
  168. if (originValue !== value) {
  169. this.attrs[name] = value;
  170. this.onAttrChange(name, value, originValue);
  171. }
  172. };
  173. /**
  174. * @protected
  175. * 属性值发生改变
  176. * @param {string} name 属性名
  177. * @param {any} value 属性值
  178. * @param {any} originValue 属性值
  179. */
  180. Element.prototype.onAttrChange = function (name, value, originValue) {
  181. if (name === 'matrix') {
  182. this.set('totalMatrix', null);
  183. }
  184. };
  185. /**
  186. * 属性更改后需要做的事情
  187. * @protected
  188. */
  189. Element.prototype.afterAttrsChange = function (targetAttrs) {
  190. if (this.cfg.isClipShape) {
  191. var applyTo = this.cfg.applyTo;
  192. if (applyTo) {
  193. applyTo.onCanvasChange('clip');
  194. }
  195. }
  196. else {
  197. this.onCanvasChange('attr');
  198. }
  199. };
  200. Element.prototype.show = function () {
  201. // 不是高频操作直接使用 set
  202. this.set('visible', true);
  203. this.onCanvasChange('show');
  204. return this;
  205. };
  206. Element.prototype.hide = function () {
  207. // 不是高频操作直接使用 set
  208. this.set('visible', false);
  209. this.onCanvasChange('hide');
  210. return this;
  211. };
  212. Element.prototype.setZIndex = function (zIndex) {
  213. this.set('zIndex', zIndex);
  214. var parent = this.getParent();
  215. if (parent) {
  216. // 改变 zIndex 不应该立即触发渲染 (调用 onCanvasChange('zIndex')),需要经过 sort 再触发
  217. parent.sort();
  218. }
  219. return this;
  220. };
  221. Element.prototype.toFront = function () {
  222. var parent = this.getParent();
  223. if (!parent) {
  224. return;
  225. }
  226. var children = parent.getChildren();
  227. var el = this.get('el');
  228. var index = children.indexOf(this);
  229. children.splice(index, 1);
  230. children.push(this);
  231. this.onCanvasChange('zIndex');
  232. };
  233. Element.prototype.toBack = function () {
  234. var parent = this.getParent();
  235. if (!parent) {
  236. return;
  237. }
  238. var children = parent.getChildren();
  239. var el = this.get('el');
  240. var index = children.indexOf(this);
  241. children.splice(index, 1);
  242. children.unshift(this);
  243. this.onCanvasChange('zIndex');
  244. };
  245. Element.prototype.remove = function (destroy) {
  246. if (destroy === void 0) { destroy = true; }
  247. var parent = this.getParent();
  248. if (parent) {
  249. util_2.removeFromArray(parent.getChildren(), this);
  250. if (!parent.get('clearing')) {
  251. // 如果父元素正在清理,当前元素不触发 remove
  252. this.onCanvasChange('remove');
  253. }
  254. }
  255. else {
  256. this.onCanvasChange('remove');
  257. }
  258. if (destroy) {
  259. this.destroy();
  260. }
  261. };
  262. Element.prototype.resetMatrix = function () {
  263. this.attr(MATRIX, this.getDefaultMatrix());
  264. this.onCanvasChange('matrix');
  265. };
  266. Element.prototype.getMatrix = function () {
  267. return this.attr(MATRIX);
  268. };
  269. Element.prototype.setMatrix = function (m) {
  270. this.attr(MATRIX, m);
  271. this.onCanvasChange('matrix');
  272. };
  273. // 获取总的 matrix
  274. Element.prototype.getTotalMatrix = function () {
  275. var totalMatrix = this.cfg.totalMatrix;
  276. if (!totalMatrix) {
  277. var currentMatrix = this.attr('matrix');
  278. var parentMatrix = this.cfg.parentMatrix;
  279. if (parentMatrix && currentMatrix) {
  280. totalMatrix = matrix_1.multiplyMatrix(parentMatrix, currentMatrix);
  281. }
  282. else {
  283. totalMatrix = currentMatrix || parentMatrix;
  284. }
  285. this.set('totalMatrix', totalMatrix);
  286. }
  287. return totalMatrix;
  288. };
  289. // 上层分组设置 matrix
  290. Element.prototype.applyMatrix = function (matrix) {
  291. var currentMatrix = this.attr('matrix');
  292. var totalMatrix = null;
  293. if (matrix && currentMatrix) {
  294. totalMatrix = matrix_1.multiplyMatrix(matrix, currentMatrix);
  295. }
  296. else {
  297. totalMatrix = currentMatrix || matrix;
  298. }
  299. this.set('totalMatrix', totalMatrix);
  300. this.set('parentMatrix', matrix);
  301. };
  302. /**
  303. * @protected
  304. * 获取默认的矩阵
  305. * @returns {number[]|null} 默认的矩阵
  306. */
  307. Element.prototype.getDefaultMatrix = function () {
  308. return null;
  309. };
  310. // 将向量应用设置的矩阵
  311. Element.prototype.applyToMatrix = function (v) {
  312. var matrix = this.attr('matrix');
  313. if (matrix) {
  314. return matrix_1.multiplyVec2(matrix, v);
  315. }
  316. return v;
  317. };
  318. // 根据设置的矩阵,将向量转换相对于图形/分组的位置
  319. Element.prototype.invertFromMatrix = function (v) {
  320. var matrix = this.attr('matrix');
  321. if (matrix) {
  322. var invertMatrix = matrix_1.invert(matrix);
  323. if (invertMatrix) {
  324. return matrix_1.multiplyVec2(invertMatrix, v);
  325. }
  326. }
  327. return v;
  328. };
  329. // 设置 clip
  330. Element.prototype.setClip = function (clipCfg) {
  331. var canvas = this.getCanvas();
  332. // 应该只设置当前元素的 clip,不应该去修改 clip 本身,方便 clip 被复用
  333. // TODO: setClip 的传参既 shape 配置,也支持 shape 对象
  334. // const preShape = this.get('clipShape');
  335. // if (preShape) {
  336. // // 将之前的 clipShape 销毁
  337. // preShape.destroy();
  338. // }
  339. var clipShape = null;
  340. // 如果配置项为 null,则不移除 clipShape
  341. if (clipCfg) {
  342. var ShapeBase = this.getShapeBase();
  343. var shapeType = util_1.upperFirst(clipCfg.type);
  344. var Cons = ShapeBase[shapeType];
  345. if (Cons) {
  346. clipShape = new Cons({
  347. type: clipCfg.type,
  348. isClipShape: true,
  349. applyTo: this,
  350. attrs: clipCfg.attrs,
  351. canvas: canvas,
  352. });
  353. }
  354. }
  355. this.set('clipShape', clipShape);
  356. this.onCanvasChange('clip');
  357. return clipShape;
  358. };
  359. Element.prototype.getClip = function () {
  360. // 高频率调用的地方直接使用 this.cfg.xxx
  361. var clipShape = this.cfg.clipShape;
  362. // 未设置时返回 Null,保证一致性
  363. if (!clipShape) {
  364. return null;
  365. }
  366. return clipShape;
  367. };
  368. Element.prototype.clone = function () {
  369. var _this = this;
  370. var originAttrs = this.attrs;
  371. var attrs = {};
  372. util_1.each(originAttrs, function (i, k) {
  373. if (util_1.isArray(originAttrs[k])) {
  374. attrs[k] = _cloneArrayAttr(originAttrs[k]);
  375. }
  376. else {
  377. attrs[k] = originAttrs[k];
  378. }
  379. });
  380. var cons = this.constructor;
  381. // @ts-ignore
  382. var clone = new cons({ attrs: attrs });
  383. util_1.each(CLONE_CFGS, function (cfgName) {
  384. clone.set(cfgName, _this.get(cfgName));
  385. });
  386. return clone;
  387. };
  388. Element.prototype.destroy = function () {
  389. var destroyed = this.destroyed;
  390. if (destroyed) {
  391. return;
  392. }
  393. this.attrs = {};
  394. _super.prototype.destroy.call(this);
  395. // this.onCanvasChange('destroy');
  396. };
  397. /**
  398. * 是否处于动画暂停状态
  399. * @return {boolean} 是否处于动画暂停状态
  400. */
  401. Element.prototype.isAnimatePaused = function () {
  402. return this.get('_pause').isPaused;
  403. };
  404. /**
  405. * 执行动画,支持多种函数签名
  406. * 1. animate(toAttrs: ElementAttrs, duration: number, easing?: string, callback?: () => void, delay?: number)
  407. * 2. animate(onFrame: OnFrame, duration: number, easing?: string, callback?: () => void, delay?: number)
  408. * 3. animate(toAttrs: ElementAttrs, cfg: AnimateCfg)
  409. * 4. animate(onFrame: OnFrame, cfg: AnimateCfg)
  410. * 各个参数的含义为:
  411. * toAttrs 动画最终状态
  412. * onFrame 自定义帧动画函数
  413. * duration 动画执行时间
  414. * easing 动画缓动效果
  415. * callback 动画执行后的回调
  416. * delay 动画延迟时间
  417. */
  418. Element.prototype.animate = function () {
  419. var args = [];
  420. for (var _i = 0; _i < arguments.length; _i++) {
  421. args[_i] = arguments[_i];
  422. }
  423. if (!this.get('timeline') && !this.get('canvas')) {
  424. return;
  425. }
  426. this.set('animating', true);
  427. var timeline = this.get('timeline');
  428. if (!timeline) {
  429. timeline = this.get('canvas').get('timeline');
  430. this.set('timeline', timeline);
  431. }
  432. var animations = this.get('animations') || [];
  433. // 初始化 tick
  434. if (!timeline.timer) {
  435. timeline.initTimer();
  436. }
  437. var toAttrs = args[0], duration = args[1], _a = args[2], easing = _a === void 0 ? 'easeLinear' : _a, _b = args[3], callback = _b === void 0 ? util_1.noop : _b, _c = args[4], delay = _c === void 0 ? 0 : _c;
  438. var onFrame;
  439. var repeat;
  440. var pauseCallback;
  441. var resumeCallback;
  442. var animateCfg;
  443. // 第二个参数,既可以是动画最终状态 toAttrs,也可以是自定义帧动画函数 onFrame
  444. if (util_1.isFunction(toAttrs)) {
  445. onFrame = toAttrs;
  446. toAttrs = {};
  447. }
  448. else if (util_1.isObject(toAttrs) && toAttrs.onFrame) {
  449. // 兼容 3.0 中的写法,onFrame 和 repeat 可在 toAttrs 中设置
  450. onFrame = toAttrs.onFrame;
  451. repeat = toAttrs.repeat;
  452. }
  453. // 第二个参数,既可以是执行时间 duration,也可以是动画参数 animateCfg
  454. if (util_1.isObject(duration)) {
  455. animateCfg = duration;
  456. duration = animateCfg.duration;
  457. easing = animateCfg.easing || 'easeLinear';
  458. delay = animateCfg.delay || 0;
  459. // animateCfg 中的设置优先级更高
  460. repeat = animateCfg.repeat || repeat || false;
  461. callback = animateCfg.callback || util_1.noop;
  462. pauseCallback = animateCfg.pauseCallback || util_1.noop;
  463. resumeCallback = animateCfg.resumeCallback || util_1.noop;
  464. }
  465. else {
  466. // 第四个参数,既可以是回调函数 callback,也可以是延迟时间 delay
  467. if (util_1.isNumber(callback)) {
  468. delay = callback;
  469. callback = null;
  470. }
  471. // 第三个参数,既可以是缓动参数 easing,也可以是回调函数 callback
  472. if (util_1.isFunction(easing)) {
  473. callback = easing;
  474. easing = 'easeLinear';
  475. }
  476. else {
  477. easing = easing || 'easeLinear';
  478. }
  479. }
  480. var formatToAttrs = getFormatToAttrs(toAttrs, this);
  481. var animation = {
  482. fromAttrs: getFormatFromAttrs(formatToAttrs, this),
  483. toAttrs: formatToAttrs,
  484. duration: duration,
  485. easing: easing,
  486. repeat: repeat,
  487. callback: callback,
  488. pauseCallback: pauseCallback,
  489. resumeCallback: resumeCallback,
  490. delay: delay,
  491. startTime: timeline.getTime(),
  492. id: util_1.uniqueId(),
  493. onFrame: onFrame,
  494. pathFormatted: false,
  495. };
  496. // 如果动画元素队列中已经有这个图形了
  497. if (animations.length > 0) {
  498. // 先检查是否需要合并属性。若有相同的动画,将该属性从前一个动画中删除,直接用后一个动画中
  499. animations = checkExistedAttrs(animations, animation);
  500. }
  501. else {
  502. // 否则将图形添加到动画元素队列
  503. timeline.addAnimator(this);
  504. }
  505. animations.push(animation);
  506. this.set('animations', animations);
  507. this.set('_pause', { isPaused: false });
  508. };
  509. /**
  510. * 停止动画
  511. * @param {boolean} toEnd 是否到动画的最终状态
  512. */
  513. Element.prototype.stopAnimate = function (toEnd) {
  514. var _this = this;
  515. if (toEnd === void 0) { toEnd = true; }
  516. var animations = this.get('animations');
  517. util_1.each(animations, function (animation) {
  518. // 将动画执行到最后一帧
  519. if (toEnd) {
  520. if (animation.onFrame) {
  521. _this.attr(animation.onFrame(1));
  522. }
  523. else {
  524. _this.attr(animation.toAttrs);
  525. }
  526. }
  527. if (animation.callback) {
  528. // 动画停止时的回调
  529. animation.callback();
  530. }
  531. });
  532. this.set('animating', false);
  533. this.set('animations', []);
  534. };
  535. /**
  536. * 暂停动画
  537. */
  538. Element.prototype.pauseAnimate = function () {
  539. var timeline = this.get('timeline');
  540. var animations = this.get('animations');
  541. var pauseTime = timeline.getTime();
  542. util_1.each(animations, function (animation) {
  543. animation._paused = true;
  544. animation._pauseTime = pauseTime;
  545. if (animation.pauseCallback) {
  546. // 动画暂停时的回调
  547. animation.pauseCallback();
  548. }
  549. });
  550. // 记录下是在什么时候暂停的
  551. this.set('_pause', {
  552. isPaused: true,
  553. pauseTime: pauseTime,
  554. });
  555. return this;
  556. };
  557. /**
  558. * 恢复动画
  559. */
  560. Element.prototype.resumeAnimate = function () {
  561. var timeline = this.get('timeline');
  562. var current = timeline.getTime();
  563. var animations = this.get('animations');
  564. var pauseTime = this.get('_pause').pauseTime;
  565. // 之后更新属性需要计算动画已经执行的时长,如果暂停了,就把初始时间调后
  566. util_1.each(animations, function (animation) {
  567. animation.startTime = animation.startTime + (current - pauseTime);
  568. animation._paused = false;
  569. animation._pauseTime = null;
  570. if (animation.resumeCallback) {
  571. animation.resumeCallback();
  572. }
  573. });
  574. this.set('_pause', {
  575. isPaused: false,
  576. });
  577. this.set('animations', animations);
  578. return this;
  579. };
  580. /**
  581. * 触发委托事件
  582. * @param {string} type 事件类型
  583. * @param {GraphEvent} eventObj 事件对象
  584. */
  585. Element.prototype.emitDelegation = function (type, eventObj) {
  586. var _this = this;
  587. var paths = eventObj.propagationPath;
  588. var events = this.getEvents();
  589. var relativeShape;
  590. if (type === 'mouseenter') {
  591. relativeShape = eventObj.fromShape;
  592. }
  593. else if (type === 'mouseleave') {
  594. relativeShape = eventObj.toShape;
  595. }
  596. var _loop_1 = function (i) {
  597. var element = paths[i];
  598. // 暂定跟 name 绑定
  599. var name_1 = element.get('name');
  600. if (name_1) {
  601. // 第一个 mouseenter 和 mouseleave 的停止即可,因为后面的都是前面的 Parent
  602. if (
  603. // 只有 element 是 Group 或者 Canvas 的时候,才需要判断 isParent
  604. (element.isGroup() || (element.isCanvas && element.isCanvas())) &&
  605. relativeShape &&
  606. util_2.isParent(element, relativeShape)) {
  607. return "break";
  608. }
  609. if (util_1.isArray(name_1)) {
  610. util_1.each(name_1, function (subName) {
  611. _this.emitDelegateEvent(element, subName, eventObj);
  612. });
  613. }
  614. else {
  615. this_1.emitDelegateEvent(element, name_1, eventObj);
  616. }
  617. }
  618. };
  619. var this_1 = this;
  620. // 至少有一个对象,且第一个对象为 shape
  621. for (var i = 0; i < paths.length; i++) {
  622. var state_1 = _loop_1(i);
  623. if (state_1 === "break")
  624. break;
  625. }
  626. };
  627. Element.prototype.emitDelegateEvent = function (element, name, eventObj) {
  628. var events = this.getEvents();
  629. // 事件委托的形式 name:type
  630. var eventName = name + DELEGATION_SPLIT + eventObj.type;
  631. if (events[eventName] || events[WILDCARD]) {
  632. // 对于通配符 *,事件名称 = 委托事件名称
  633. eventObj.name = eventName;
  634. eventObj.currentTarget = element;
  635. eventObj.delegateTarget = this;
  636. // 将委托事件的监听对象 delegateObject 挂载到事件对象上
  637. eventObj.delegateObject = element.get('delegateObject');
  638. this.emit(eventName, eventObj);
  639. }
  640. };
  641. /**
  642. * 移动元素
  643. * @param {number} translateX 水平移动距离
  644. * @param {number} translateY 垂直移动距离
  645. * @return {IElement} 元素
  646. */
  647. Element.prototype.translate = function (translateX, translateY) {
  648. if (translateX === void 0) { translateX = 0; }
  649. if (translateY === void 0) { translateY = 0; }
  650. var matrix = this.getMatrix();
  651. var newMatrix = transform(matrix, [['t', translateX, translateY]]);
  652. this.setMatrix(newMatrix);
  653. return this;
  654. };
  655. /**
  656. * 移动元素到目标位置
  657. * @param {number} targetX 目标位置的水平坐标
  658. * @param {number} targetX 目标位置的垂直坐标
  659. * @return {IElement} 元素
  660. */
  661. Element.prototype.move = function (targetX, targetY) {
  662. var x = this.attr('x') || 0;
  663. var y = this.attr('y') || 0;
  664. this.translate(targetX - x, targetY - y);
  665. return this;
  666. };
  667. /**
  668. * 移动元素到目标位置,等价于 move 方法。由于 moveTo 的语义性更强,因此在文档中推荐使用 moveTo 方法
  669. * @param {number} targetX 目标位置的 x 轴坐标
  670. * @param {number} targetY 目标位置的 y 轴坐标
  671. * @return {IElement} 元素
  672. */
  673. Element.prototype.moveTo = function (targetX, targetY) {
  674. return this.move(targetX, targetY);
  675. };
  676. /**
  677. * 缩放元素
  678. * @param {number} ratioX 水平缩放比例
  679. * @param {number} ratioY 垂直缩放比例
  680. * @return {IElement} 元素
  681. */
  682. Element.prototype.scale = function (ratioX, ratioY) {
  683. var matrix = this.getMatrix();
  684. var newMatrix = transform(matrix, [['s', ratioX, ratioY || ratioX]]);
  685. this.setMatrix(newMatrix);
  686. return this;
  687. };
  688. /**
  689. * 以画布左上角 (0, 0) 为中心旋转元素
  690. * @param {number} radian 旋转角度(弧度值)
  691. * @return {IElement} 元素
  692. */
  693. Element.prototype.rotate = function (radian) {
  694. var matrix = this.getMatrix();
  695. var newMatrix = transform(matrix, [['r', radian]]);
  696. this.setMatrix(newMatrix);
  697. return this;
  698. };
  699. /**
  700. * 以起始点为中心旋转元素
  701. * @param {number} radian 旋转角度(弧度值)
  702. * @return {IElement} 元素
  703. */
  704. Element.prototype.rotateAtStart = function (rotate) {
  705. var _a = this.attr(), x = _a.x, y = _a.y;
  706. var matrix = this.getMatrix();
  707. var newMatrix = transform(matrix, [
  708. ['t', -x, -y],
  709. ['r', rotate],
  710. ['t', x, y],
  711. ]);
  712. this.setMatrix(newMatrix);
  713. return this;
  714. };
  715. /**
  716. * 以任意点 (x, y) 为中心旋转元素
  717. * @param {number} radian 旋转角度(弧度值)
  718. * @return {IElement} 元素
  719. */
  720. Element.prototype.rotateAtPoint = function (x, y, rotate) {
  721. var matrix = this.getMatrix();
  722. var newMatrix = transform(matrix, [
  723. ['t', -x, -y],
  724. ['r', rotate],
  725. ['t', x, y],
  726. ]);
  727. this.setMatrix(newMatrix);
  728. return this;
  729. };
  730. return Element;
  731. }(base_1.default));
  732. exports.default = Element;
  733. //# sourceMappingURL=element.js.map