Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
META-INF.assets.rjzjh.zrender.graphic.States.js Maven / Gradle / Ivy
/**
* States machine for managing graphic states
*/
define(function (require) {
/**
* @typedef {Object} IGraphicState
* @property {number} [zlevel]
* @property {number} [z]
* @property {Array.} {position}
* @property {Array.|number} {rotation}
* @property {Array.} {scale}
* @property {Object} style
*
* @property {Function} onenter
* @property {Function} onleave
* @property {Function} ontransition
* @property {Array.} transition
* Transition object or a string descriptor like '* 30 0 Linear'
*/
var zrUtil = require('../core/util');
var Style = require('./Style');
var vec2Copy = require('../core/vector').copy;
var transitionProperties = ['position', 'rotation', 'scale', 'style', 'shape'];
/**
* @module zrender/graphic/States~TransitionObject
*/
var TransitionObject = function (opts) {
if (typeof opts == 'string') {
this._fromStr(opts);
}
else if (opts) {
opts.property && (this.property = opts.property);
opts.duration != null && (this.duration = opts.duration);
opts.easing && (this.easing = opts.easing);
opts.delay && (this.delay = opts.delay);
}
if (this.property !== '*') {
this.property = this.property.split(',');
}
else {
this.property = transitionProperties;
}
};
TransitionObject.prototype = {
constructor: TransitionObject,
/**
* List of all transition properties. Splitted by comma. Must not have spaces in the string.
* e.g. 'position,style.color'. '*' will match all the valid properties.
* @type {string}
* @default *
*/
property: '*',
/**
* @type {string}
* @default 'Linear'
*/
easing: 'Linear',
/**
* @type {number}
* @default 'number'
*/
duration: 500,
/**
* @type {number}
*/
delay: 0,
_fromStr: function (str) {
var arr = str.split(/\s+/g);
this.property = arr[0];
this.duration = +arr[1];
this.delay = +arr[2];
this.easing = arr[3];
}
};
/**
* @alias module:zrender/graphic/States
*/
var GraphicStates = function (opts) {
opts = opts || {};
this._states = {};
/**
* Target element
* @type {zrender/graphic/Displayable|zrender/container/Group}
*/
this._el = opts.el;
this._subStates = [];
this._transitionAnimators = [];
if (opts.initialState) {
this._initialState = opts.initialState;
}
var optsStates = opts.states;
if (optsStates) {
for (var name in optsStates) {
var state = optsStates[name];
this._addState(name, state);
}
}
this.setState(this._initialState);
};
GraphicStates.prototype = {
constructor: GraphicStates,
/**
* All other state will be extended from initial state
* @type {string}
* @private
*/
_initialState: 'normal',
/**
* Current state
* @type {string}
* @private
*/
_currentState: '',
el: function () {
return this._el;
},
_addState: function (name, state) {
this._states[name] = state;
if (state.transition) {
state.transition = new TransitionObject(state.transition);
}
// Extend from initial state
if (name !== this._initialState) {
this._extendFromInitial(state);
}
else {
var el = this._el;
// setState 的时候自带的 style 和 shape 都会被直接覆盖
// 所以这边先把自带的 style 和 shape 扩展到初始状态中
zrUtil.merge(state.style, el.style, false, false);
if (state.shape) {
zrUtil.merge(state.shape, el.shape, false, true);
}
else {
state.shape = zrUtil.clone(el.shape, true);
}
for (var name in this._states) {
this._extendFromInitial(this._states[name]);
}
}
},
_extendFromInitial: function (state) {
var initialState = this._states[this._initialState];
if (initialState && state !== initialState) {
zrUtil.merge(state, initialState, false, true);
}
},
setState: function (name, silent) {
if (name === this._currentState
&& ! this.transiting()
) {
return;
}
var state = this._states[name];
if (state) {
this._stopTransition();
if (! silent) {
var prevState = this._states[this._currentState];
if (prevState) {
prevState.onleave && prevState.onleave.call(this);
}
state.onenter && state.onenter.call(this);
}
this._currentState = name;
if (this._el) {
var el = this._el;
// Setting attributes
if (state.zlevel != null) {
el.zlevel = state.zlevel;
}
if (state.z != null) {
el.z = state.z;
}
// SRT
state.position && vec2Copy(el.position, state.position);
state.scale && vec2Copy(el.scale, state.scale);
if (state.rotation != null) {
el.rotation = state.rotation;
}
// Style
if (state.style) {
var initialState = this._states[this._initialState];
el.style = new Style();
if (initialState) {
el.style.extendFrom(initialState.style);
}
if (
// Not initial state
name != this._initialState
// Not copied from initial state in _extendFromInitial method
&& initialState.style !== state.style
) {
el.style.extendFrom(state.style, true);
}
}
if (state.shape) {
el.shape = zrUtil.clone(state.shape, true);
}
el.dirty();
}
}
for (var i = 0; i < this._subStates.length; i++) {
this._subStates.setState(name);
}
},
getState: function () {
return this._currentState;
},
transitionState: function (target, done) {
if (
target === this._currentState
&& ! this.transiting()
) {
return;
}
var state = this._states[target];
var styleShapeReg = /$[style|shape]\./;
var self = this;
// Animation 去重
var propPathMap = {};
if (state) {
self._stopTransition();
var el = self._el;
if (state.transition && el && el.__zr) {// El can be animated
var transitionCfg = state.transition;
var property = transitionCfg.property;
var animatingCount = 0;
var animationDone = function () {
animatingCount--;
if (animatingCount === 0) {
self.setState(target);
done && done();
}
};
for (var i = 0; i < property.length; i++) {
var propName = property[i];
// Animating all the properties in style or shape
if (propName === 'style' || propName === 'shape') {
if (state[propName]) {
for (var key in state[propName]) {
var path = propName + '.' + key;
if (propPathMap[path]) {
continue;
}
propPathMap[path] = 1;
animatingCount += self._animProp(
state, propName, key, transitionCfg, animationDone
);
}
}
}
else {
if (propPathMap[propName]) {
continue;
}
propPathMap[propName] = 1;
// Animating particular property in style or style
if (propName.match(styleShapeReg)) {
// remove 'style.', 'shape.' prefix
var subProp = propName.slice(0, 5);
propName = propName.slice(6);
animatingCount += self._animProp(
state, subProp, propName, transitionCfg, animationDone
);
}
else {
animatingCount += self._animProp(
state, '', propName, transitionCfg, animationDone
);
}
}
}
// No transition properties
if (animatingCount === 0) {
self.setState(target);
done && done();
}
}
else {
self.setState(target);
done && done();
}
}
var subStates = self._subStates;
for (var i = 0; i < subStates.length; i++) {
subStates.transitionState(target);
}
},
/**
* Do transition animation of particular property
* @param {Object} state
* @param {string} subPropKey
* @param {string} key
* @param {string} transitionCfg
* @param {Function} done
* @private
*/
_animProp: function (state, subPropKey, key, transitionCfg, done) {
var el = this._el;
var stateObj = subPropKey ? state[subPropKey] : state;
var elObj = subPropKey ? el[subPropKey] : el;
var availableProp = stateObj && (key in stateObj)
&& elObj && (key in elObj);
var transitionAnimators = this._transitionAnimators;
if (availableProp) {
var obj = {};
if (stateObj[key] === elObj[key]) {
return 0;
}
obj[key] = stateObj[key];
var animator = el.animate(subPropKey)
.when(transitionCfg.duration, obj)
.delay(transitionCfg.dealy)
.done(function () {
var idx = zrUtil.indexOf(transitionAnimators, 1);
if (idx > 0) {
transitionAnimators.splice(idx, 1);
}
done();
})
.start(transitionCfg.easing);
transitionAnimators.push(animator);
return 1;
}
return 0;
},
_stopTransition: function () {
var transitionAnimators = this._transitionAnimators;
for (var i = 0; i < transitionAnimators.length; i++) {
transitionAnimators[i].stop();
}
transitionAnimators.length = 0;
},
transiting: function () {
return this._transitionAnimators.length > 0;
},
addSubStates: function (states) {
this._subStates.push(states);
},
removeSubStates: function (states) {
var idx = zrUtil.indexOf(this._subStates, states);
if (idx >= 0) {
this._subStates.splice(states, 1);
}
}
};
return GraphicStates;
});