- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs
Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
733 lines
25 KiB
JavaScript
733 lines
25 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
var tslib_1 = require("tslib");
|
||
var util_1 = require("@antv/util");
|
||
var matrix_util_1 = require("@antv/matrix-util");
|
||
var util_2 = require("../util/util");
|
||
var matrix_1 = require("../util/matrix");
|
||
var base_1 = require("./base");
|
||
var transform = matrix_util_1.ext.transform;
|
||
var MATRIX = 'matrix';
|
||
var CLONE_CFGS = ['zIndex', 'capture', 'visible', 'type'];
|
||
// 可以在 toAttrs 中设置,但不属于绘图属性的字段
|
||
var RESERVED_PORPS = ['repeat'];
|
||
var DELEGATION_SPLIT = ':';
|
||
var WILDCARD = '*';
|
||
// 需要考虑数组嵌套数组的场景
|
||
// 数组嵌套对象的场景不考虑
|
||
function _cloneArrayAttr(arr) {
|
||
var result = [];
|
||
for (var i = 0; i < arr.length; i++) {
|
||
if (util_1.isArray(arr[i])) {
|
||
result.push([].concat(arr[i]));
|
||
}
|
||
else {
|
||
result.push(arr[i]);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
function getFormatFromAttrs(toAttrs, shape) {
|
||
var fromAttrs = {};
|
||
var attrs = shape.attrs;
|
||
for (var k in toAttrs) {
|
||
fromAttrs[k] = attrs[k];
|
||
}
|
||
return fromAttrs;
|
||
}
|
||
function getFormatToAttrs(props, shape) {
|
||
var toAttrs = {};
|
||
var attrs = shape.attr();
|
||
util_1.each(props, function (v, k) {
|
||
if (RESERVED_PORPS.indexOf(k) === -1 && !util_1.isEqual(attrs[k], v)) {
|
||
toAttrs[k] = v;
|
||
}
|
||
});
|
||
return toAttrs;
|
||
}
|
||
function checkExistedAttrs(animations, animation) {
|
||
if (animation.onFrame) {
|
||
return animations;
|
||
}
|
||
var startTime = animation.startTime, delay = animation.delay, duration = animation.duration;
|
||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||
util_1.each(animations, function (item) {
|
||
// 后一个动画开始执行的时间 < 前一个动画的结束时间 && 后一个动画的执行时间 > 前一个动画的延迟
|
||
if (startTime + delay < item.startTime + item.delay + item.duration && duration > item.delay) {
|
||
util_1.each(animation.toAttrs, function (v, k) {
|
||
if (hasOwnProperty.call(item.toAttrs, k)) {
|
||
delete item.toAttrs[k];
|
||
delete item.fromAttrs[k];
|
||
}
|
||
});
|
||
}
|
||
});
|
||
return animations;
|
||
}
|
||
var Element = /** @class */ (function (_super) {
|
||
tslib_1.__extends(Element, _super);
|
||
function Element(cfg) {
|
||
var _this = _super.call(this, cfg) || this;
|
||
/**
|
||
* @protected
|
||
* 图形属性
|
||
* @type {ShapeAttrs}
|
||
*/
|
||
_this.attrs = {};
|
||
var attrs = _this.getDefaultAttrs();
|
||
util_1.mix(attrs, cfg.attrs);
|
||
_this.attrs = attrs;
|
||
_this.initAttrs(attrs);
|
||
_this.initAnimate(); // 初始化动画
|
||
return _this;
|
||
}
|
||
// override
|
||
Element.prototype.getDefaultCfg = function () {
|
||
return {
|
||
visible: true,
|
||
capture: true,
|
||
zIndex: 0,
|
||
};
|
||
};
|
||
/**
|
||
* @protected
|
||
* 获取默认的属相
|
||
*/
|
||
Element.prototype.getDefaultAttrs = function () {
|
||
return {
|
||
matrix: this.getDefaultMatrix(),
|
||
opacity: 1,
|
||
};
|
||
};
|
||
/**
|
||
* @protected
|
||
* 一些方法调用会引起画布变化
|
||
* @param {ChangeType} changeType 改变的类型
|
||
*/
|
||
Element.prototype.onCanvasChange = function (changeType) { };
|
||
/**
|
||
* @protected
|
||
* 初始化属性,有些属性需要加工
|
||
* @param {object} attrs 属性值
|
||
*/
|
||
Element.prototype.initAttrs = function (attrs) { };
|
||
/**
|
||
* @protected
|
||
* 初始化动画
|
||
*/
|
||
Element.prototype.initAnimate = function () {
|
||
this.set('animable', true);
|
||
this.set('animating', false);
|
||
};
|
||
Element.prototype.isGroup = function () {
|
||
return false;
|
||
};
|
||
Element.prototype.getParent = function () {
|
||
return this.get('parent');
|
||
};
|
||
Element.prototype.getCanvas = function () {
|
||
return this.get('canvas');
|
||
};
|
||
Element.prototype.attr = function () {
|
||
var _a;
|
||
var args = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
args[_i] = arguments[_i];
|
||
}
|
||
var name = args[0], value = args[1];
|
||
if (!name)
|
||
return this.attrs;
|
||
if (util_1.isObject(name)) {
|
||
for (var k in name) {
|
||
this.setAttr(k, name[k]);
|
||
}
|
||
this.afterAttrsChange(name);
|
||
return this;
|
||
}
|
||
if (args.length === 2) {
|
||
this.setAttr(name, value);
|
||
this.afterAttrsChange((_a = {},
|
||
_a[name] = value,
|
||
_a));
|
||
return this;
|
||
}
|
||
return this.attrs[name];
|
||
};
|
||
// 是否被裁剪,被裁剪则不显示,不参与拾取
|
||
Element.prototype.isClipped = function (refX, refY) {
|
||
var clip = this.getClip();
|
||
return clip && !clip.isHit(refX, refY);
|
||
};
|
||
/**
|
||
* 内部设置属性值的接口
|
||
* @param {string} name 属性名
|
||
* @param {any} value 属性值
|
||
*/
|
||
Element.prototype.setAttr = function (name, value) {
|
||
var originValue = this.attrs[name];
|
||
if (originValue !== value) {
|
||
this.attrs[name] = value;
|
||
this.onAttrChange(name, value, originValue);
|
||
}
|
||
};
|
||
/**
|
||
* @protected
|
||
* 属性值发生改变
|
||
* @param {string} name 属性名
|
||
* @param {any} value 属性值
|
||
* @param {any} originValue 属性值
|
||
*/
|
||
Element.prototype.onAttrChange = function (name, value, originValue) {
|
||
if (name === 'matrix') {
|
||
this.set('totalMatrix', null);
|
||
}
|
||
};
|
||
/**
|
||
* 属性更改后需要做的事情
|
||
* @protected
|
||
*/
|
||
Element.prototype.afterAttrsChange = function (targetAttrs) {
|
||
if (this.cfg.isClipShape) {
|
||
var applyTo = this.cfg.applyTo;
|
||
if (applyTo) {
|
||
applyTo.onCanvasChange('clip');
|
||
}
|
||
}
|
||
else {
|
||
this.onCanvasChange('attr');
|
||
}
|
||
};
|
||
Element.prototype.show = function () {
|
||
// 不是高频操作直接使用 set
|
||
this.set('visible', true);
|
||
this.onCanvasChange('show');
|
||
return this;
|
||
};
|
||
Element.prototype.hide = function () {
|
||
// 不是高频操作直接使用 set
|
||
this.set('visible', false);
|
||
this.onCanvasChange('hide');
|
||
return this;
|
||
};
|
||
Element.prototype.setZIndex = function (zIndex) {
|
||
this.set('zIndex', zIndex);
|
||
var parent = this.getParent();
|
||
if (parent) {
|
||
// 改变 zIndex 不应该立即触发渲染 (调用 onCanvasChange('zIndex')),需要经过 sort 再触发
|
||
parent.sort();
|
||
}
|
||
return this;
|
||
};
|
||
Element.prototype.toFront = function () {
|
||
var parent = this.getParent();
|
||
if (!parent) {
|
||
return;
|
||
}
|
||
var children = parent.getChildren();
|
||
var el = this.get('el');
|
||
var index = children.indexOf(this);
|
||
children.splice(index, 1);
|
||
children.push(this);
|
||
this.onCanvasChange('zIndex');
|
||
};
|
||
Element.prototype.toBack = function () {
|
||
var parent = this.getParent();
|
||
if (!parent) {
|
||
return;
|
||
}
|
||
var children = parent.getChildren();
|
||
var el = this.get('el');
|
||
var index = children.indexOf(this);
|
||
children.splice(index, 1);
|
||
children.unshift(this);
|
||
this.onCanvasChange('zIndex');
|
||
};
|
||
Element.prototype.remove = function (destroy) {
|
||
if (destroy === void 0) { destroy = true; }
|
||
var parent = this.getParent();
|
||
if (parent) {
|
||
util_2.removeFromArray(parent.getChildren(), this);
|
||
if (!parent.get('clearing')) {
|
||
// 如果父元素正在清理,当前元素不触发 remove
|
||
this.onCanvasChange('remove');
|
||
}
|
||
}
|
||
else {
|
||
this.onCanvasChange('remove');
|
||
}
|
||
if (destroy) {
|
||
this.destroy();
|
||
}
|
||
};
|
||
Element.prototype.resetMatrix = function () {
|
||
this.attr(MATRIX, this.getDefaultMatrix());
|
||
this.onCanvasChange('matrix');
|
||
};
|
||
Element.prototype.getMatrix = function () {
|
||
return this.attr(MATRIX);
|
||
};
|
||
Element.prototype.setMatrix = function (m) {
|
||
this.attr(MATRIX, m);
|
||
this.onCanvasChange('matrix');
|
||
};
|
||
// 获取总的 matrix
|
||
Element.prototype.getTotalMatrix = function () {
|
||
var totalMatrix = this.cfg.totalMatrix;
|
||
if (!totalMatrix) {
|
||
var currentMatrix = this.attr('matrix');
|
||
var parentMatrix = this.cfg.parentMatrix;
|
||
if (parentMatrix && currentMatrix) {
|
||
totalMatrix = matrix_1.multiplyMatrix(parentMatrix, currentMatrix);
|
||
}
|
||
else {
|
||
totalMatrix = currentMatrix || parentMatrix;
|
||
}
|
||
this.set('totalMatrix', totalMatrix);
|
||
}
|
||
return totalMatrix;
|
||
};
|
||
// 上层分组设置 matrix
|
||
Element.prototype.applyMatrix = function (matrix) {
|
||
var currentMatrix = this.attr('matrix');
|
||
var totalMatrix = null;
|
||
if (matrix && currentMatrix) {
|
||
totalMatrix = matrix_1.multiplyMatrix(matrix, currentMatrix);
|
||
}
|
||
else {
|
||
totalMatrix = currentMatrix || matrix;
|
||
}
|
||
this.set('totalMatrix', totalMatrix);
|
||
this.set('parentMatrix', matrix);
|
||
};
|
||
/**
|
||
* @protected
|
||
* 获取默认的矩阵
|
||
* @returns {number[]|null} 默认的矩阵
|
||
*/
|
||
Element.prototype.getDefaultMatrix = function () {
|
||
return null;
|
||
};
|
||
// 将向量应用设置的矩阵
|
||
Element.prototype.applyToMatrix = function (v) {
|
||
var matrix = this.attr('matrix');
|
||
if (matrix) {
|
||
return matrix_1.multiplyVec2(matrix, v);
|
||
}
|
||
return v;
|
||
};
|
||
// 根据设置的矩阵,将向量转换相对于图形/分组的位置
|
||
Element.prototype.invertFromMatrix = function (v) {
|
||
var matrix = this.attr('matrix');
|
||
if (matrix) {
|
||
var invertMatrix = matrix_1.invert(matrix);
|
||
if (invertMatrix) {
|
||
return matrix_1.multiplyVec2(invertMatrix, v);
|
||
}
|
||
}
|
||
return v;
|
||
};
|
||
// 设置 clip
|
||
Element.prototype.setClip = function (clipCfg) {
|
||
var canvas = this.getCanvas();
|
||
// 应该只设置当前元素的 clip,不应该去修改 clip 本身,方便 clip 被复用
|
||
// TODO: setClip 的传参既 shape 配置,也支持 shape 对象
|
||
// const preShape = this.get('clipShape');
|
||
// if (preShape) {
|
||
// // 将之前的 clipShape 销毁
|
||
// preShape.destroy();
|
||
// }
|
||
var clipShape = null;
|
||
// 如果配置项为 null,则不移除 clipShape
|
||
if (clipCfg) {
|
||
var ShapeBase = this.getShapeBase();
|
||
var shapeType = util_1.upperFirst(clipCfg.type);
|
||
var Cons = ShapeBase[shapeType];
|
||
if (Cons) {
|
||
clipShape = new Cons({
|
||
type: clipCfg.type,
|
||
isClipShape: true,
|
||
applyTo: this,
|
||
attrs: clipCfg.attrs,
|
||
canvas: canvas,
|
||
});
|
||
}
|
||
}
|
||
this.set('clipShape', clipShape);
|
||
this.onCanvasChange('clip');
|
||
return clipShape;
|
||
};
|
||
Element.prototype.getClip = function () {
|
||
// 高频率调用的地方直接使用 this.cfg.xxx
|
||
var clipShape = this.cfg.clipShape;
|
||
// 未设置时返回 Null,保证一致性
|
||
if (!clipShape) {
|
||
return null;
|
||
}
|
||
return clipShape;
|
||
};
|
||
Element.prototype.clone = function () {
|
||
var _this = this;
|
||
var originAttrs = this.attrs;
|
||
var attrs = {};
|
||
util_1.each(originAttrs, function (i, k) {
|
||
if (util_1.isArray(originAttrs[k])) {
|
||
attrs[k] = _cloneArrayAttr(originAttrs[k]);
|
||
}
|
||
else {
|
||
attrs[k] = originAttrs[k];
|
||
}
|
||
});
|
||
var cons = this.constructor;
|
||
// @ts-ignore
|
||
var clone = new cons({ attrs: attrs });
|
||
util_1.each(CLONE_CFGS, function (cfgName) {
|
||
clone.set(cfgName, _this.get(cfgName));
|
||
});
|
||
return clone;
|
||
};
|
||
Element.prototype.destroy = function () {
|
||
var destroyed = this.destroyed;
|
||
if (destroyed) {
|
||
return;
|
||
}
|
||
this.attrs = {};
|
||
_super.prototype.destroy.call(this);
|
||
// this.onCanvasChange('destroy');
|
||
};
|
||
/**
|
||
* 是否处于动画暂停状态
|
||
* @return {boolean} 是否处于动画暂停状态
|
||
*/
|
||
Element.prototype.isAnimatePaused = function () {
|
||
return this.get('_pause').isPaused;
|
||
};
|
||
/**
|
||
* 执行动画,支持多种函数签名
|
||
* 1. animate(toAttrs: ElementAttrs, duration: number, easing?: string, callback?: () => void, delay?: number)
|
||
* 2. animate(onFrame: OnFrame, duration: number, easing?: string, callback?: () => void, delay?: number)
|
||
* 3. animate(toAttrs: ElementAttrs, cfg: AnimateCfg)
|
||
* 4. animate(onFrame: OnFrame, cfg: AnimateCfg)
|
||
* 各个参数的含义为:
|
||
* toAttrs 动画最终状态
|
||
* onFrame 自定义帧动画函数
|
||
* duration 动画执行时间
|
||
* easing 动画缓动效果
|
||
* callback 动画执行后的回调
|
||
* delay 动画延迟时间
|
||
*/
|
||
Element.prototype.animate = function () {
|
||
var args = [];
|
||
for (var _i = 0; _i < arguments.length; _i++) {
|
||
args[_i] = arguments[_i];
|
||
}
|
||
if (!this.get('timeline') && !this.get('canvas')) {
|
||
return;
|
||
}
|
||
this.set('animating', true);
|
||
var timeline = this.get('timeline');
|
||
if (!timeline) {
|
||
timeline = this.get('canvas').get('timeline');
|
||
this.set('timeline', timeline);
|
||
}
|
||
var animations = this.get('animations') || [];
|
||
// 初始化 tick
|
||
if (!timeline.timer) {
|
||
timeline.initTimer();
|
||
}
|
||
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;
|
||
var onFrame;
|
||
var repeat;
|
||
var pauseCallback;
|
||
var resumeCallback;
|
||
var animateCfg;
|
||
// 第二个参数,既可以是动画最终状态 toAttrs,也可以是自定义帧动画函数 onFrame
|
||
if (util_1.isFunction(toAttrs)) {
|
||
onFrame = toAttrs;
|
||
toAttrs = {};
|
||
}
|
||
else if (util_1.isObject(toAttrs) && toAttrs.onFrame) {
|
||
// 兼容 3.0 中的写法,onFrame 和 repeat 可在 toAttrs 中设置
|
||
onFrame = toAttrs.onFrame;
|
||
repeat = toAttrs.repeat;
|
||
}
|
||
// 第二个参数,既可以是执行时间 duration,也可以是动画参数 animateCfg
|
||
if (util_1.isObject(duration)) {
|
||
animateCfg = duration;
|
||
duration = animateCfg.duration;
|
||
easing = animateCfg.easing || 'easeLinear';
|
||
delay = animateCfg.delay || 0;
|
||
// animateCfg 中的设置优先级更高
|
||
repeat = animateCfg.repeat || repeat || false;
|
||
callback = animateCfg.callback || util_1.noop;
|
||
pauseCallback = animateCfg.pauseCallback || util_1.noop;
|
||
resumeCallback = animateCfg.resumeCallback || util_1.noop;
|
||
}
|
||
else {
|
||
// 第四个参数,既可以是回调函数 callback,也可以是延迟时间 delay
|
||
if (util_1.isNumber(callback)) {
|
||
delay = callback;
|
||
callback = null;
|
||
}
|
||
// 第三个参数,既可以是缓动参数 easing,也可以是回调函数 callback
|
||
if (util_1.isFunction(easing)) {
|
||
callback = easing;
|
||
easing = 'easeLinear';
|
||
}
|
||
else {
|
||
easing = easing || 'easeLinear';
|
||
}
|
||
}
|
||
var formatToAttrs = getFormatToAttrs(toAttrs, this);
|
||
var animation = {
|
||
fromAttrs: getFormatFromAttrs(formatToAttrs, this),
|
||
toAttrs: formatToAttrs,
|
||
duration: duration,
|
||
easing: easing,
|
||
repeat: repeat,
|
||
callback: callback,
|
||
pauseCallback: pauseCallback,
|
||
resumeCallback: resumeCallback,
|
||
delay: delay,
|
||
startTime: timeline.getTime(),
|
||
id: util_1.uniqueId(),
|
||
onFrame: onFrame,
|
||
pathFormatted: false,
|
||
};
|
||
// 如果动画元素队列中已经有这个图形了
|
||
if (animations.length > 0) {
|
||
// 先检查是否需要合并属性。若有相同的动画,将该属性从前一个动画中删除,直接用后一个动画中
|
||
animations = checkExistedAttrs(animations, animation);
|
||
}
|
||
else {
|
||
// 否则将图形添加到动画元素队列
|
||
timeline.addAnimator(this);
|
||
}
|
||
animations.push(animation);
|
||
this.set('animations', animations);
|
||
this.set('_pause', { isPaused: false });
|
||
};
|
||
/**
|
||
* 停止动画
|
||
* @param {boolean} toEnd 是否到动画的最终状态
|
||
*/
|
||
Element.prototype.stopAnimate = function (toEnd) {
|
||
var _this = this;
|
||
if (toEnd === void 0) { toEnd = true; }
|
||
var animations = this.get('animations');
|
||
util_1.each(animations, function (animation) {
|
||
// 将动画执行到最后一帧
|
||
if (toEnd) {
|
||
if (animation.onFrame) {
|
||
_this.attr(animation.onFrame(1));
|
||
}
|
||
else {
|
||
_this.attr(animation.toAttrs);
|
||
}
|
||
}
|
||
if (animation.callback) {
|
||
// 动画停止时的回调
|
||
animation.callback();
|
||
}
|
||
});
|
||
this.set('animating', false);
|
||
this.set('animations', []);
|
||
};
|
||
/**
|
||
* 暂停动画
|
||
*/
|
||
Element.prototype.pauseAnimate = function () {
|
||
var timeline = this.get('timeline');
|
||
var animations = this.get('animations');
|
||
var pauseTime = timeline.getTime();
|
||
util_1.each(animations, function (animation) {
|
||
animation._paused = true;
|
||
animation._pauseTime = pauseTime;
|
||
if (animation.pauseCallback) {
|
||
// 动画暂停时的回调
|
||
animation.pauseCallback();
|
||
}
|
||
});
|
||
// 记录下是在什么时候暂停的
|
||
this.set('_pause', {
|
||
isPaused: true,
|
||
pauseTime: pauseTime,
|
||
});
|
||
return this;
|
||
};
|
||
/**
|
||
* 恢复动画
|
||
*/
|
||
Element.prototype.resumeAnimate = function () {
|
||
var timeline = this.get('timeline');
|
||
var current = timeline.getTime();
|
||
var animations = this.get('animations');
|
||
var pauseTime = this.get('_pause').pauseTime;
|
||
// 之后更新属性需要计算动画已经执行的时长,如果暂停了,就把初始时间调后
|
||
util_1.each(animations, function (animation) {
|
||
animation.startTime = animation.startTime + (current - pauseTime);
|
||
animation._paused = false;
|
||
animation._pauseTime = null;
|
||
if (animation.resumeCallback) {
|
||
animation.resumeCallback();
|
||
}
|
||
});
|
||
this.set('_pause', {
|
||
isPaused: false,
|
||
});
|
||
this.set('animations', animations);
|
||
return this;
|
||
};
|
||
/**
|
||
* 触发委托事件
|
||
* @param {string} type 事件类型
|
||
* @param {GraphEvent} eventObj 事件对象
|
||
*/
|
||
Element.prototype.emitDelegation = function (type, eventObj) {
|
||
var _this = this;
|
||
var paths = eventObj.propagationPath;
|
||
var events = this.getEvents();
|
||
var relativeShape;
|
||
if (type === 'mouseenter') {
|
||
relativeShape = eventObj.fromShape;
|
||
}
|
||
else if (type === 'mouseleave') {
|
||
relativeShape = eventObj.toShape;
|
||
}
|
||
var _loop_1 = function (i) {
|
||
var element = paths[i];
|
||
// 暂定跟 name 绑定
|
||
var name_1 = element.get('name');
|
||
if (name_1) {
|
||
// 第一个 mouseenter 和 mouseleave 的停止即可,因为后面的都是前面的 Parent
|
||
if (
|
||
// 只有 element 是 Group 或者 Canvas 的时候,才需要判断 isParent
|
||
(element.isGroup() || (element.isCanvas && element.isCanvas())) &&
|
||
relativeShape &&
|
||
util_2.isParent(element, relativeShape)) {
|
||
return "break";
|
||
}
|
||
if (util_1.isArray(name_1)) {
|
||
util_1.each(name_1, function (subName) {
|
||
_this.emitDelegateEvent(element, subName, eventObj);
|
||
});
|
||
}
|
||
else {
|
||
this_1.emitDelegateEvent(element, name_1, eventObj);
|
||
}
|
||
}
|
||
};
|
||
var this_1 = this;
|
||
// 至少有一个对象,且第一个对象为 shape
|
||
for (var i = 0; i < paths.length; i++) {
|
||
var state_1 = _loop_1(i);
|
||
if (state_1 === "break")
|
||
break;
|
||
}
|
||
};
|
||
Element.prototype.emitDelegateEvent = function (element, name, eventObj) {
|
||
var events = this.getEvents();
|
||
// 事件委托的形式 name:type
|
||
var eventName = name + DELEGATION_SPLIT + eventObj.type;
|
||
if (events[eventName] || events[WILDCARD]) {
|
||
// 对于通配符 *,事件名称 = 委托事件名称
|
||
eventObj.name = eventName;
|
||
eventObj.currentTarget = element;
|
||
eventObj.delegateTarget = this;
|
||
// 将委托事件的监听对象 delegateObject 挂载到事件对象上
|
||
eventObj.delegateObject = element.get('delegateObject');
|
||
this.emit(eventName, eventObj);
|
||
}
|
||
};
|
||
/**
|
||
* 移动元素
|
||
* @param {number} translateX 水平移动距离
|
||
* @param {number} translateY 垂直移动距离
|
||
* @return {IElement} 元素
|
||
*/
|
||
Element.prototype.translate = function (translateX, translateY) {
|
||
if (translateX === void 0) { translateX = 0; }
|
||
if (translateY === void 0) { translateY = 0; }
|
||
var matrix = this.getMatrix();
|
||
var newMatrix = transform(matrix, [['t', translateX, translateY]]);
|
||
this.setMatrix(newMatrix);
|
||
return this;
|
||
};
|
||
/**
|
||
* 移动元素到目标位置
|
||
* @param {number} targetX 目标位置的水平坐标
|
||
* @param {number} targetX 目标位置的垂直坐标
|
||
* @return {IElement} 元素
|
||
*/
|
||
Element.prototype.move = function (targetX, targetY) {
|
||
var x = this.attr('x') || 0;
|
||
var y = this.attr('y') || 0;
|
||
this.translate(targetX - x, targetY - y);
|
||
return this;
|
||
};
|
||
/**
|
||
* 移动元素到目标位置,等价于 move 方法。由于 moveTo 的语义性更强,因此在文档中推荐使用 moveTo 方法
|
||
* @param {number} targetX 目标位置的 x 轴坐标
|
||
* @param {number} targetY 目标位置的 y 轴坐标
|
||
* @return {IElement} 元素
|
||
*/
|
||
Element.prototype.moveTo = function (targetX, targetY) {
|
||
return this.move(targetX, targetY);
|
||
};
|
||
/**
|
||
* 缩放元素
|
||
* @param {number} ratioX 水平缩放比例
|
||
* @param {number} ratioY 垂直缩放比例
|
||
* @return {IElement} 元素
|
||
*/
|
||
Element.prototype.scale = function (ratioX, ratioY) {
|
||
var matrix = this.getMatrix();
|
||
var newMatrix = transform(matrix, [['s', ratioX, ratioY || ratioX]]);
|
||
this.setMatrix(newMatrix);
|
||
return this;
|
||
};
|
||
/**
|
||
* 以画布左上角 (0, 0) 为中心旋转元素
|
||
* @param {number} radian 旋转角度(弧度值)
|
||
* @return {IElement} 元素
|
||
*/
|
||
Element.prototype.rotate = function (radian) {
|
||
var matrix = this.getMatrix();
|
||
var newMatrix = transform(matrix, [['r', radian]]);
|
||
this.setMatrix(newMatrix);
|
||
return this;
|
||
};
|
||
/**
|
||
* 以起始点为中心旋转元素
|
||
* @param {number} radian 旋转角度(弧度值)
|
||
* @return {IElement} 元素
|
||
*/
|
||
Element.prototype.rotateAtStart = function (rotate) {
|
||
var _a = this.attr(), x = _a.x, y = _a.y;
|
||
var matrix = this.getMatrix();
|
||
var newMatrix = transform(matrix, [
|
||
['t', -x, -y],
|
||
['r', rotate],
|
||
['t', x, y],
|
||
]);
|
||
this.setMatrix(newMatrix);
|
||
return this;
|
||
};
|
||
/**
|
||
* 以任意点 (x, y) 为中心旋转元素
|
||
* @param {number} radian 旋转角度(弧度值)
|
||
* @return {IElement} 元素
|
||
*/
|
||
Element.prototype.rotateAtPoint = function (x, y, rotate) {
|
||
var matrix = this.getMatrix();
|
||
var newMatrix = transform(matrix, [
|
||
['t', -x, -y],
|
||
['r', rotate],
|
||
['t', x, y],
|
||
]);
|
||
this.setMatrix(newMatrix);
|
||
return this;
|
||
};
|
||
return Element;
|
||
}(base_1.default));
|
||
exports.default = Element;
|
||
//# sourceMappingURL=element.js.map
|