EffectLine.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. var graphic = require("../../util/graphic");
  2. var Line = require("./Line");
  3. var zrUtil = require("zrender/lib/core/util");
  4. var _symbol = require("../../util/symbol");
  5. var createSymbol = _symbol.createSymbol;
  6. var vec2 = require("zrender/lib/core/vector");
  7. var curveUtil = require("zrender/lib/core/curve");
  8. /**
  9. * Provide effect for line
  10. * @module echarts/chart/helper/EffectLine
  11. */
  12. /**
  13. * @constructor
  14. * @extends {module:zrender/graphic/Group}
  15. * @alias {module:echarts/chart/helper/Line}
  16. */
  17. function EffectLine(lineData, idx, seriesScope) {
  18. graphic.Group.call(this);
  19. this.add(this.createLine(lineData, idx, seriesScope));
  20. this._updateEffectSymbol(lineData, idx);
  21. }
  22. var effectLineProto = EffectLine.prototype;
  23. effectLineProto.createLine = function (lineData, idx, seriesScope) {
  24. return new Line(lineData, idx, seriesScope);
  25. };
  26. effectLineProto._updateEffectSymbol = function (lineData, idx) {
  27. var itemModel = lineData.getItemModel(idx);
  28. var effectModel = itemModel.getModel('effect');
  29. var size = effectModel.get('symbolSize');
  30. var symbolType = effectModel.get('symbol');
  31. if (!zrUtil.isArray(size)) {
  32. size = [size, size];
  33. }
  34. var color = effectModel.get('color') || lineData.getItemVisual(idx, 'color');
  35. var symbol = this.childAt(1);
  36. if (this._symbolType !== symbolType) {
  37. // Remove previous
  38. this.remove(symbol);
  39. symbol = createSymbol(symbolType, -0.5, -0.5, 1, 1, color);
  40. symbol.z2 = 100;
  41. symbol.culling = true;
  42. this.add(symbol);
  43. } // Symbol may be removed if loop is false
  44. if (!symbol) {
  45. return;
  46. } // Shadow color is same with color in default
  47. symbol.setStyle('shadowColor', color);
  48. symbol.setStyle(effectModel.getItemStyle(['color']));
  49. symbol.attr('scale', size);
  50. symbol.setColor(color);
  51. symbol.attr('scale', size);
  52. this._symbolType = symbolType;
  53. this._updateEffectAnimation(lineData, effectModel, idx);
  54. };
  55. effectLineProto._updateEffectAnimation = function (lineData, effectModel, idx) {
  56. var symbol = this.childAt(1);
  57. if (!symbol) {
  58. return;
  59. }
  60. var self = this;
  61. var points = lineData.getItemLayout(idx);
  62. var period = effectModel.get('period') * 1000;
  63. var loop = effectModel.get('loop');
  64. var constantSpeed = effectModel.get('constantSpeed');
  65. var delayExpr = zrUtil.retrieve(effectModel.get('delay'), function (idx) {
  66. return idx / lineData.count() * period / 3;
  67. });
  68. var isDelayFunc = typeof delayExpr === 'function'; // Ignore when updating
  69. symbol.ignore = true;
  70. this.updateAnimationPoints(symbol, points);
  71. if (constantSpeed > 0) {
  72. period = this.getLineLength(symbol) / constantSpeed * 1000;
  73. }
  74. if (period !== this._period || loop !== this._loop) {
  75. symbol.stopAnimation();
  76. var delay = delayExpr;
  77. if (isDelayFunc) {
  78. delay = delayExpr(idx);
  79. }
  80. if (symbol.__t > 0) {
  81. delay = -period * symbol.__t;
  82. }
  83. symbol.__t = 0;
  84. var animator = symbol.animate('', loop).when(period, {
  85. __t: 1
  86. }).delay(delay).during(function () {
  87. self.updateSymbolPosition(symbol);
  88. });
  89. if (!loop) {
  90. animator.done(function () {
  91. self.remove(symbol);
  92. });
  93. }
  94. animator.start();
  95. }
  96. this._period = period;
  97. this._loop = loop;
  98. };
  99. effectLineProto.getLineLength = function (symbol) {
  100. // Not so accurate
  101. return vec2.dist(symbol.__p1, symbol.__cp1) + vec2.dist(symbol.__cp1, symbol.__p2);
  102. };
  103. effectLineProto.updateAnimationPoints = function (symbol, points) {
  104. symbol.__p1 = points[0];
  105. symbol.__p2 = points[1];
  106. symbol.__cp1 = points[2] || [(points[0][0] + points[1][0]) / 2, (points[0][1] + points[1][1]) / 2];
  107. };
  108. effectLineProto.updateData = function (lineData, idx, seriesScope) {
  109. this.childAt(0).updateData(lineData, idx, seriesScope);
  110. this._updateEffectSymbol(lineData, idx);
  111. };
  112. effectLineProto.updateSymbolPosition = function (symbol) {
  113. var p1 = symbol.__p1;
  114. var p2 = symbol.__p2;
  115. var cp1 = symbol.__cp1;
  116. var t = symbol.__t;
  117. var pos = symbol.position;
  118. var quadraticAt = curveUtil.quadraticAt;
  119. var quadraticDerivativeAt = curveUtil.quadraticDerivativeAt;
  120. pos[0] = quadraticAt(p1[0], cp1[0], p2[0], t);
  121. pos[1] = quadraticAt(p1[1], cp1[1], p2[1], t); // Tangent
  122. var tx = quadraticDerivativeAt(p1[0], cp1[0], p2[0], t);
  123. var ty = quadraticDerivativeAt(p1[1], cp1[1], p2[1], t);
  124. symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2;
  125. symbol.ignore = false;
  126. };
  127. effectLineProto.updateLayout = function (lineData, idx) {
  128. this.childAt(0).updateLayout(lineData, idx);
  129. var effectModel = lineData.getItemModel(idx).getModel('effect');
  130. this._updateEffectAnimation(lineData, effectModel, idx);
  131. };
  132. zrUtil.inherits(EffectLine, graphic.Group);
  133. var _default = EffectLine;
  134. module.exports = _default;