184 lines
5.5 KiB
Plaintext
184 lines
5.5 KiB
Plaintext
/**
|
|
* Symbol with ripple effect
|
|
* @module echarts/chart/helper/EffectSymbol
|
|
*/
|
|
define(function (require) {
|
|
|
|
var zrUtil = require('zrender/core/util');
|
|
var symbolUtil = require('../../util/symbol');
|
|
var graphic = require('../../util/graphic');
|
|
var numberUtil = require('../../util/number');
|
|
var Symbol = require('./Symbol');
|
|
var Group = graphic.Group;
|
|
|
|
var EFFECT_RIPPLE_NUMBER = 3;
|
|
|
|
function normalizeSymbolSize(symbolSize) {
|
|
if (!zrUtil.isArray(symbolSize)) {
|
|
symbolSize = [+symbolSize, +symbolSize];
|
|
}
|
|
return symbolSize;
|
|
}
|
|
/**
|
|
* @constructor
|
|
* @param {module:echarts/data/List} data
|
|
* @param {number} idx
|
|
* @extends {module:zrender/graphic/Group}
|
|
*/
|
|
function EffectSymbol(data, idx) {
|
|
Group.call(this);
|
|
|
|
var symbol = new Symbol(data, idx);
|
|
var rippleGroup = new Group();
|
|
this.add(symbol);
|
|
this.add(rippleGroup);
|
|
|
|
rippleGroup.beforeUpdate = function () {
|
|
this.attr(symbol.getScale());
|
|
};
|
|
this.updateData(data, idx);
|
|
}
|
|
|
|
var effectSymbolProto = EffectSymbol.prototype;
|
|
|
|
effectSymbolProto.stopEffectAnimation = function () {
|
|
this.childAt(1).removeAll();
|
|
};
|
|
|
|
effectSymbolProto.startEffectAnimation = function (
|
|
period, brushType, rippleScale, effectOffset, z, zlevel
|
|
) {
|
|
var symbolType = this._symbolType;
|
|
var color = this._color;
|
|
|
|
var rippleGroup = this.childAt(1);
|
|
|
|
for (var i = 0; i < EFFECT_RIPPLE_NUMBER; i++) {
|
|
var ripplePath = symbolUtil.createSymbol(
|
|
symbolType, -0.5, -0.5, 1, 1, color
|
|
);
|
|
ripplePath.attr({
|
|
style: {
|
|
stroke: brushType === 'stroke' ? color : null,
|
|
fill: brushType === 'fill' ? color : null,
|
|
strokeNoScale: true
|
|
},
|
|
z2: 99,
|
|
silent: true,
|
|
scale: [1, 1],
|
|
z: z,
|
|
zlevel: zlevel
|
|
});
|
|
|
|
var delay = -i / EFFECT_RIPPLE_NUMBER * period + effectOffset;
|
|
// TODO Configurable period
|
|
ripplePath.animate('', true)
|
|
.when(period, {
|
|
scale: [rippleScale, rippleScale]
|
|
})
|
|
.delay(delay)
|
|
.start();
|
|
ripplePath.animateStyle(true)
|
|
.when(period, {
|
|
opacity: 0
|
|
})
|
|
.delay(delay)
|
|
.start();
|
|
|
|
rippleGroup.add(ripplePath);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Highlight symbol
|
|
*/
|
|
effectSymbolProto.highlight = function () {
|
|
this.trigger('emphasis');
|
|
};
|
|
|
|
/**
|
|
* Downplay symbol
|
|
*/
|
|
effectSymbolProto.downplay = function () {
|
|
this.trigger('normal');
|
|
};
|
|
|
|
/**
|
|
* Update symbol properties
|
|
* @param {module:echarts/data/List} data
|
|
* @param {number} idx
|
|
*/
|
|
effectSymbolProto.updateData = function (data, idx) {
|
|
var seriesModel = data.hostModel;
|
|
|
|
this.childAt(0).updateData(data, idx);
|
|
|
|
var rippleGroup = this.childAt(1);
|
|
var itemModel = data.getItemModel(idx);
|
|
var symbolType = data.getItemVisual(idx, 'symbol');
|
|
var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
|
|
var color = data.getItemVisual(idx, 'color');
|
|
|
|
rippleGroup.attr('scale', symbolSize);
|
|
|
|
rippleGroup.traverse(function (ripplePath) {
|
|
ripplePath.attr({
|
|
fill: color
|
|
});
|
|
});
|
|
|
|
var symbolOffset = itemModel.getShallow('symbolOffset');
|
|
if (symbolOffset) {
|
|
var pos = rippleGroup.position;
|
|
pos[0] = numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);
|
|
pos[1] = numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);
|
|
}
|
|
rippleGroup.rotation = (itemModel.getShallow('symbolRotate') || 0) * Math.PI / 180 || 0;
|
|
|
|
this._symbolType = symbolType;
|
|
this._color = color;
|
|
|
|
var showEffectOn = seriesModel.get('showEffectOn');
|
|
var rippleScale = itemModel.get('rippleEffect.scale');
|
|
var brushType = itemModel.get('rippleEffect.brushType');
|
|
var effectPeriod = itemModel.get('rippleEffect.period') * 1000;
|
|
var effectOffset = idx / data.count();
|
|
var z = itemModel.getShallow('z') || 0;
|
|
var zlevel = itemModel.getShallow('zlevel') || 0;
|
|
|
|
this.stopEffectAnimation();
|
|
if (showEffectOn === 'render') {
|
|
this.startEffectAnimation(
|
|
effectPeriod, brushType, rippleScale, effectOffset, z, zlevel
|
|
);
|
|
}
|
|
var symbol = this.childAt(0);
|
|
function onEmphasis() {
|
|
symbol.trigger('emphasis');
|
|
if (showEffectOn !== 'render') {
|
|
this.startEffectAnimation(
|
|
effectPeriod, brushType, rippleScale, effectOffset, z, zlevel
|
|
);
|
|
}
|
|
}
|
|
function onNormal() {
|
|
symbol.trigger('normal');
|
|
if (showEffectOn !== 'render') {
|
|
this.stopEffectAnimation();
|
|
}
|
|
}
|
|
this.on('mouseover', onEmphasis, this)
|
|
.on('mouseout', onNormal, this)
|
|
.on('emphasis', onEmphasis, this)
|
|
.on('normal', onNormal, this);
|
|
};
|
|
|
|
effectSymbolProto.fadeOut = function (cb) {
|
|
this.off('mouseover').off('mouseout').off('emphasis').off('normal');
|
|
cb && cb();
|
|
};
|
|
|
|
zrUtil.inherits(EffectSymbol, Group);
|
|
|
|
return EffectSymbol;
|
|
}); |