first commit

This commit is contained in:
jefferyzhao
2025-07-31 17:44:12 +08:00
commit b9bdc8598b
42390 changed files with 4467935 additions and 0 deletions

275
node_modules/zrender/lib/mixin/Animatable.js generated vendored Normal file
View File

@ -0,0 +1,275 @@
var Animator = require("../animation/Animator");
var logError = require("../core/log");
var _util = require("../core/util");
var isString = _util.isString;
var isFunction = _util.isFunction;
var isObject = _util.isObject;
var isArrayLike = _util.isArrayLike;
var indexOf = _util.indexOf;
/**
* @alias module:zrender/mixin/Animatable
* @constructor
*/
var Animatable = function () {
/**
* @type {Array.<module:zrender/animation/Animator>}
* @readOnly
*/
this.animators = [];
};
Animatable.prototype = {
constructor: Animatable,
/**
* 动画
*
* @param {string} path The path to fetch value from object, like 'a.b.c'.
* @param {boolean} [loop] Whether to loop animation.
* @return {module:zrender/animation/Animator}
* @example:
* el.animate('style', false)
* .when(1000, {x: 10} )
* .done(function(){ // Animation done })
* .start()
*/
animate: function (path, loop) {
var target;
var animatingShape = false;
var el = this;
var zr = this.__zr;
if (path) {
var pathSplitted = path.split('.');
var prop = el; // If animating shape
animatingShape = pathSplitted[0] === 'shape';
for (var i = 0, l = pathSplitted.length; i < l; i++) {
if (!prop) {
continue;
}
prop = prop[pathSplitted[i]];
}
if (prop) {
target = prop;
}
} else {
target = el;
}
if (!target) {
logError('Property "' + path + '" is not existed in element ' + el.id);
return;
}
var animators = el.animators;
var animator = new Animator(target, loop);
animator.during(function (target) {
el.dirty(animatingShape);
}).done(function () {
// FIXME Animator will not be removed if use `Animator#stop` to stop animation
animators.splice(indexOf(animators, animator), 1);
});
animators.push(animator); // If animate after added to the zrender
if (zr) {
zr.animation.addAnimator(animator);
}
return animator;
},
/**
* 停止动画
* @param {boolean} forwardToLast If move to last frame before stop
*/
stopAnimation: function (forwardToLast) {
var animators = this.animators;
var len = animators.length;
for (var i = 0; i < len; i++) {
animators[i].stop(forwardToLast);
}
animators.length = 0;
return this;
},
/**
* Caution: this method will stop previous animation.
* So do not use this method to one element twice before
* animation starts, unless you know what you are doing.
* @param {Object} target
* @param {number} [time=500] Time in ms
* @param {string} [easing='linear']
* @param {number} [delay=0]
* @param {Function} [callback]
* @param {Function} [forceAnimate] Prevent stop animation and callback
* immediently when target values are the same as current values.
*
* @example
* // Animate position
* el.animateTo({
* position: [10, 10]
* }, function () { // done })
*
* // Animate shape, style and position in 100ms, delayed 100ms, with cubicOut easing
* el.animateTo({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100, 'cubicOut', function () { // done })
*/
// TODO Return animation key
animateTo: function (target, time, delay, easing, callback, forceAnimate) {
animateTo(this, target, time, delay, easing, callback, forceAnimate);
},
/**
* Animate from the target state to current state.
* The params and the return value are the same as `this.animateTo`.
*/
animateFrom: function (target, time, delay, easing, callback, forceAnimate) {
animateTo(this, target, time, delay, easing, callback, forceAnimate, true);
}
};
function animateTo(animatable, target, time, delay, easing, callback, forceAnimate, reverse) {
// animateTo(target, time, easing, callback);
if (isString(delay)) {
callback = easing;
easing = delay;
delay = 0;
} // animateTo(target, time, delay, callback);
else if (isFunction(easing)) {
callback = easing;
easing = 'linear';
delay = 0;
} // animateTo(target, time, callback);
else if (isFunction(delay)) {
callback = delay;
delay = 0;
} // animateTo(target, callback)
else if (isFunction(time)) {
callback = time;
time = 500;
} // animateTo(target)
else if (!time) {
time = 500;
} // Stop all previous animations
animatable.stopAnimation();
animateToShallow(animatable, '', animatable, target, time, delay, reverse); // Animators may be removed immediately after start
// if there is nothing to animate
var animators = animatable.animators.slice();
var count = animators.length;
function done() {
count--;
if (!count) {
callback && callback();
}
} // No animators. This should be checked before animators[i].start(),
// because 'done' may be executed immediately if no need to animate.
if (!count) {
callback && callback();
} // Start after all animators created
// Incase any animator is done immediately when all animation properties are not changed
for (var i = 0; i < animators.length; i++) {
animators[i].done(done).start(easing, forceAnimate);
}
}
/**
* @param {string} path=''
* @param {Object} source=animatable
* @param {Object} target
* @param {number} [time=500]
* @param {number} [delay=0]
* @param {boolean} [reverse] If `true`, animate
* from the `target` to current state.
*
* @example
* // Animate position
* el._animateToShallow({
* position: [10, 10]
* })
*
* // Animate shape, style and position in 100ms, delayed 100ms
* el._animateToShallow({
* shape: {
* width: 500
* },
* style: {
* fill: 'red'
* }
* position: [10, 10]
* }, 100, 100)
*/
function animateToShallow(animatable, path, source, target, time, delay, reverse) {
var objShallow = {};
var propertyCount = 0;
for (var name in target) {
if (!target.hasOwnProperty(name)) {
continue;
}
if (source[name] != null) {
if (isObject(target[name]) && !isArrayLike(target[name])) {
animateToShallow(animatable, path ? path + '.' + name : name, source[name], target[name], time, delay, reverse);
} else {
if (reverse) {
objShallow[name] = source[name];
setAttrByPath(animatable, path, name, target[name]);
} else {
objShallow[name] = target[name];
}
propertyCount++;
}
} else if (target[name] != null && !reverse) {
setAttrByPath(animatable, path, name, target[name]);
}
}
if (propertyCount > 0) {
animatable.animate(path, false).when(time == null ? 500 : time, objShallow).delay(delay || 0);
}
}
function setAttrByPath(el, path, name, value) {
// Attr directly if not has property
// FIXME, if some property not needed for element ?
if (!path) {
el.attr(name, value);
} else {
// Only support set shape or style
var props = {};
props[path] = {};
props[path][name] = value;
el.attr(props);
}
}
var _default = Animatable;
module.exports = _default;

86
node_modules/zrender/lib/mixin/Draggable.js generated vendored Normal file
View File

@ -0,0 +1,86 @@
// TODO Draggable for group
// FIXME Draggable on element which has parent rotation or scale
function Draggable() {
this.on('mousedown', this._dragStart, this);
this.on('mousemove', this._drag, this);
this.on('mouseup', this._dragEnd, this); // `mosuemove` and `mouseup` can be continue to fire when dragging.
// See [Drag outside] in `Handler.js`. So we do not need to trigger
// `_dragEnd` when globalout. That would brings better user experience.
// this.on('globalout', this._dragEnd, this);
// this._dropTarget = null;
// this._draggingTarget = null;
// this._x = 0;
// this._y = 0;
}
Draggable.prototype = {
constructor: Draggable,
_dragStart: function (e) {
var draggingTarget = e.target; // Find if there is draggable in the ancestor
while (draggingTarget && !draggingTarget.draggable) {
draggingTarget = draggingTarget.parent;
}
if (draggingTarget) {
this._draggingTarget = draggingTarget;
draggingTarget.dragging = true;
this._x = e.offsetX;
this._y = e.offsetY;
this.dispatchToElement(param(draggingTarget, e), 'dragstart', e.event);
}
},
_drag: function (e) {
var draggingTarget = this._draggingTarget;
if (draggingTarget) {
var x = e.offsetX;
var y = e.offsetY;
var dx = x - this._x;
var dy = y - this._y;
this._x = x;
this._y = y;
draggingTarget.drift(dx, dy, e);
this.dispatchToElement(param(draggingTarget, e), 'drag', e.event);
var dropTarget = this.findHover(x, y, draggingTarget).target;
var lastDropTarget = this._dropTarget;
this._dropTarget = dropTarget;
if (draggingTarget !== dropTarget) {
if (lastDropTarget && dropTarget !== lastDropTarget) {
this.dispatchToElement(param(lastDropTarget, e), 'dragleave', e.event);
}
if (dropTarget && dropTarget !== lastDropTarget) {
this.dispatchToElement(param(dropTarget, e), 'dragenter', e.event);
}
}
}
},
_dragEnd: function (e) {
var draggingTarget = this._draggingTarget;
if (draggingTarget) {
draggingTarget.dragging = false;
}
this.dispatchToElement(param(draggingTarget, e), 'dragend', e.event);
if (this._dropTarget) {
this.dispatchToElement(param(this._dropTarget, e), 'drop', e.event);
}
this._draggingTarget = null;
this._dropTarget = null;
}
};
function param(target, e) {
return {
target: target,
topTarget: e && e.topTarget
};
}
var _default = Draggable;
module.exports = _default;

371
node_modules/zrender/lib/mixin/Eventful.js generated vendored Normal file
View File

@ -0,0 +1,371 @@
/**
* Event Mixin
* @module zrender/mixin/Eventful
* @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
* pissang (https://www.github.com/pissang)
*/
var arrySlice = Array.prototype.slice;
/**
* Event dispatcher.
*
* @alias module:zrender/mixin/Eventful
* @constructor
* @param {Object} [eventProcessor] The object eventProcessor is the scope when
* `eventProcessor.xxx` called.
* @param {Function} [eventProcessor.normalizeQuery]
* param: {string|Object} Raw query.
* return: {string|Object} Normalized query.
* @param {Function} [eventProcessor.filter] Event will be dispatched only
* if it returns `true`.
* param: {string} eventType
* param: {string|Object} query
* return: {boolean}
* @param {Function} [eventProcessor.afterTrigger] Called after all handlers called.
* param: {string} eventType
*/
var Eventful = function (eventProcessor) {
this._$handlers = {};
this._$eventProcessor = eventProcessor;
};
Eventful.prototype = {
constructor: Eventful,
/**
* The handler can only be triggered once, then removed.
*
* @param {string} event The event name.
* @param {string|Object} [query] Condition used on event filter.
* @param {Function} handler The event handler.
* @param {Object} context
*/
one: function (event, query, handler, context) {
return on(this, event, query, handler, context, true);
},
/**
* Bind a handler.
*
* @param {string} event The event name.
* @param {string|Object} [query] Condition used on event filter.
* @param {Function} handler The event handler.
* @param {Object} [context]
*/
on: function (event, query, handler, context) {
return on(this, event, query, handler, context, false);
},
/**
* Whether any handler has bound.
*
* @param {string} event
* @return {boolean}
*/
isSilent: function (event) {
var _h = this._$handlers;
return !_h[event] || !_h[event].length;
},
/**
* Unbind a event.
*
* @param {string} [event] The event name.
* If no `event` input, "off" all listeners.
* @param {Function} [handler] The event handler.
* If no `handler` input, "off" all listeners of the `event`.
*/
off: function (event, handler) {
var _h = this._$handlers;
if (!event) {
this._$handlers = {};
return this;
}
if (handler) {
if (_h[event]) {
var newList = [];
for (var i = 0, l = _h[event].length; i < l; i++) {
if (_h[event][i].h !== handler) {
newList.push(_h[event][i]);
}
}
_h[event] = newList;
}
if (_h[event] && _h[event].length === 0) {
delete _h[event];
}
} else {
delete _h[event];
}
return this;
},
/**
* Dispatch a event.
*
* @param {string} type The event name.
*/
trigger: function (type) {
var _h = this._$handlers[type];
var eventProcessor = this._$eventProcessor;
if (_h) {
var args = arguments;
var argLen = args.length;
if (argLen > 3) {
args = arrySlice.call(args, 1);
}
var len = _h.length;
for (var i = 0; i < len;) {
var hItem = _h[i];
if (eventProcessor && eventProcessor.filter && hItem.query != null && !eventProcessor.filter(type, hItem.query)) {
i++;
continue;
} // Optimize advise from backbone
switch (argLen) {
case 1:
hItem.h.call(hItem.ctx);
break;
case 2:
hItem.h.call(hItem.ctx, args[1]);
break;
case 3:
hItem.h.call(hItem.ctx, args[1], args[2]);
break;
default:
// have more than 2 given arguments
hItem.h.apply(hItem.ctx, args);
break;
}
if (hItem.one) {
_h.splice(i, 1);
len--;
} else {
i++;
}
}
}
eventProcessor && eventProcessor.afterTrigger && eventProcessor.afterTrigger(type);
return this;
},
/**
* Dispatch a event with context, which is specified at the last parameter.
*
* @param {string} type The event name.
*/
triggerWithContext: function (type) {
var _h = this._$handlers[type];
var eventProcessor = this._$eventProcessor;
if (_h) {
var args = arguments;
var argLen = args.length;
if (argLen > 4) {
args = arrySlice.call(args, 1, args.length - 1);
}
var ctx = args[args.length - 1];
var len = _h.length;
for (var i = 0; i < len;) {
var hItem = _h[i];
if (eventProcessor && eventProcessor.filter && hItem.query != null && !eventProcessor.filter(type, hItem.query)) {
i++;
continue;
} // Optimize advise from backbone
switch (argLen) {
case 1:
hItem.h.call(ctx);
break;
case 2:
hItem.h.call(ctx, args[1]);
break;
case 3:
hItem.h.call(ctx, args[1], args[2]);
break;
default:
// have more than 2 given arguments
hItem.h.apply(ctx, args);
break;
}
if (hItem.one) {
_h.splice(i, 1);
len--;
} else {
i++;
}
}
}
eventProcessor && eventProcessor.afterTrigger && eventProcessor.afterTrigger(type);
return this;
}
};
function normalizeQuery(host, query) {
var eventProcessor = host._$eventProcessor;
if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
query = eventProcessor.normalizeQuery(query);
}
return query;
}
function on(eventful, event, query, handler, context, isOnce) {
var _h = eventful._$handlers;
if (typeof query === 'function') {
context = handler;
handler = query;
query = null;
}
if (!handler || !event) {
return eventful;
}
query = normalizeQuery(eventful, query);
if (!_h[event]) {
_h[event] = [];
}
for (var i = 0; i < _h[event].length; i++) {
if (_h[event][i].h === handler) {
return eventful;
}
}
var wrap = {
h: handler,
one: isOnce,
query: query,
ctx: context || eventful,
// FIXME
// Do not publish this feature util it is proved that it makes sense.
callAtLast: handler.zrEventfulCallAtLast
};
var lastIndex = _h[event].length - 1;
var lastWrap = _h[event][lastIndex];
lastWrap && lastWrap.callAtLast ? _h[event].splice(lastIndex, 0, wrap) : _h[event].push(wrap);
return eventful;
} // ----------------------
// The events in zrender
// ----------------------
/**
* @event module:zrender/mixin/Eventful#onclick
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#onmouseover
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#onmouseout
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#onmousemove
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#onmousewheel
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#onmousedown
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#onmouseup
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#ondrag
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#ondragstart
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#ondragend
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#ondragenter
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#ondragleave
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#ondragover
* @type {Function}
* @default null
*/
/**
* @event module:zrender/mixin/Eventful#ondrop
* @type {Function}
* @default null
*/
var _default = Eventful;
module.exports = _default;

324
node_modules/zrender/lib/mixin/Transformable.js generated vendored Normal file
View File

@ -0,0 +1,324 @@
var matrix = require("../core/matrix");
var vector = require("../core/vector");
/**
* 提供变换扩展
* @module zrender/mixin/Transformable
* @author pissang (https://www.github.com/pissang)
*/
var mIdentity = matrix.identity;
var EPSILON = 5e-5;
function isNotAroundZero(val) {
return val > EPSILON || val < -EPSILON;
}
/**
* @alias module:zrender/mixin/Transformable
* @constructor
*/
var Transformable = function (opts) {
opts = opts || {}; // If there are no given position, rotation, scale
if (!opts.position) {
/**
* 平移
* @type {Array.<number>}
* @default [0, 0]
*/
this.position = [0, 0];
}
if (opts.rotation == null) {
/**
* 旋转
* @type {Array.<number>}
* @default 0
*/
this.rotation = 0;
}
if (!opts.scale) {
/**
* 缩放
* @type {Array.<number>}
* @default [1, 1]
*/
this.scale = [1, 1];
}
/**
* 旋转和缩放的原点
* @type {Array.<number>}
* @default null
*/
this.origin = this.origin || null;
};
var transformableProto = Transformable.prototype;
transformableProto.transform = null;
/**
* 判断是否需要有坐标变换
* 如果有坐标变换, 则从position, rotation, scale以及父节点的transform计算出自身的transform矩阵
*/
transformableProto.needLocalTransform = function () {
return isNotAroundZero(this.rotation) || isNotAroundZero(this.position[0]) || isNotAroundZero(this.position[1]) || isNotAroundZero(this.scale[0] - 1) || isNotAroundZero(this.scale[1] - 1);
};
var scaleTmp = [];
transformableProto.updateTransform = function () {
var parent = this.parent;
var parentHasTransform = parent && parent.transform;
var needLocalTransform = this.needLocalTransform();
var m = this.transform;
if (!(needLocalTransform || parentHasTransform)) {
m && mIdentity(m);
return;
}
m = m || matrix.create();
if (needLocalTransform) {
this.getLocalTransform(m);
} else {
mIdentity(m);
} // 应用父节点变换
if (parentHasTransform) {
if (needLocalTransform) {
matrix.mul(m, parent.transform, m);
} else {
matrix.copy(m, parent.transform);
}
} // 保存这个变换矩阵
this.transform = m;
var globalScaleRatio = this.globalScaleRatio;
if (globalScaleRatio != null && globalScaleRatio !== 1) {
this.getGlobalScale(scaleTmp);
var relX = scaleTmp[0] < 0 ? -1 : 1;
var relY = scaleTmp[1] < 0 ? -1 : 1;
var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0;
var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0;
m[0] *= sx;
m[1] *= sx;
m[2] *= sy;
m[3] *= sy;
}
this.invTransform = this.invTransform || matrix.create();
matrix.invert(this.invTransform, m);
};
transformableProto.getLocalTransform = function (m) {
return Transformable.getLocalTransform(this, m);
};
/**
* 将自己的transform应用到context上
* @param {CanvasRenderingContext2D} ctx
*/
transformableProto.setTransform = function (ctx) {
var m = this.transform;
var dpr = ctx.dpr || 1;
if (m) {
ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]);
} else {
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
};
transformableProto.restoreTransform = function (ctx) {
var dpr = ctx.dpr || 1;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
};
var tmpTransform = [];
var originTransform = matrix.create();
transformableProto.setLocalTransform = function (m) {
if (!m) {
// TODO return or set identity?
return;
}
var sx = m[0] * m[0] + m[1] * m[1];
var sy = m[2] * m[2] + m[3] * m[3];
var position = this.position;
var scale = this.scale;
if (isNotAroundZero(sx - 1)) {
sx = Math.sqrt(sx);
}
if (isNotAroundZero(sy - 1)) {
sy = Math.sqrt(sy);
}
if (m[0] < 0) {
sx = -sx;
}
if (m[3] < 0) {
sy = -sy;
}
position[0] = m[4];
position[1] = m[5];
scale[0] = sx;
scale[1] = sy;
this.rotation = Math.atan2(-m[1] / sy, m[0] / sx);
};
/**
* 分解`transform`矩阵到`position`, `rotation`, `scale`
*/
transformableProto.decomposeTransform = function () {
if (!this.transform) {
return;
}
var parent = this.parent;
var m = this.transform;
if (parent && parent.transform) {
// Get local transform and decompose them to position, scale, rotation
matrix.mul(tmpTransform, parent.invTransform, m);
m = tmpTransform;
}
var origin = this.origin;
if (origin && (origin[0] || origin[1])) {
originTransform[4] = origin[0];
originTransform[5] = origin[1];
matrix.mul(tmpTransform, m, originTransform);
tmpTransform[4] -= origin[0];
tmpTransform[5] -= origin[1];
m = tmpTransform;
}
this.setLocalTransform(m);
};
/**
* Get global scale
* @return {Array.<number>}
*/
transformableProto.getGlobalScale = function (out) {
var m = this.transform;
out = out || [];
if (!m) {
out[0] = 1;
out[1] = 1;
return out;
}
out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
if (m[0] < 0) {
out[0] = -out[0];
}
if (m[3] < 0) {
out[1] = -out[1];
}
return out;
};
/**
* 变换坐标位置到 shape 的局部坐标空间
* @method
* @param {number} x
* @param {number} y
* @return {Array.<number>}
*/
transformableProto.transformCoordToLocal = function (x, y) {
var v2 = [x, y];
var invTransform = this.invTransform;
if (invTransform) {
vector.applyTransform(v2, v2, invTransform);
}
return v2;
};
/**
* 变换局部坐标位置到全局坐标空间
* @method
* @param {number} x
* @param {number} y
* @return {Array.<number>}
*/
transformableProto.transformCoordToGlobal = function (x, y) {
var v2 = [x, y];
var transform = this.transform;
if (transform) {
vector.applyTransform(v2, v2, transform);
}
return v2;
};
/**
* @static
* @param {Object} target
* @param {Array.<number>} target.origin
* @param {number} target.rotation
* @param {Array.<number>} target.position
* @param {Array.<number>} [m]
*/
Transformable.getLocalTransform = function (target, m) {
m = m || [];
mIdentity(m);
var origin = target.origin;
var scale = target.scale || [1, 1];
var rotation = target.rotation || 0;
var position = target.position || [0, 0];
if (origin) {
// Translate to origin
m[4] -= origin[0];
m[5] -= origin[1];
}
matrix.scale(m, m, scale);
if (rotation) {
matrix.rotate(m, m, rotation);
}
if (origin) {
// Translate back from origin
m[4] += origin[0];
m[5] += origin[1];
}
m[4] += position[0];
m[5] += position[1];
return m;
};
var _default = Transformable;
module.exports = _default;