7807b4fdde2fe31869c55117540fd46c17b05e18.svn-base 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. /**
  2. * echarts图表动画基类
  3. *
  4. * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
  5. * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
  6. *
  7. */
  8. define(function (require) {
  9. var zrUtil = require('zrender/tool/util');
  10. var curveTool = require('zrender/tool/curve');
  11. /**
  12. * 折线型动画
  13. *
  14. * @param {ZRender} zr
  15. * @param {shape} oldShape
  16. * @param {shape} newShape
  17. * @param {number} duration
  18. * @param {tring} easing
  19. */
  20. function pointList(zr, oldShape, newShape, duration, easing) {
  21. var newPointList = newShape.style.pointList;
  22. var newPointListLen = newPointList.length;
  23. var oldPointList;
  24. if (!oldShape) { // add
  25. oldPointList = [];
  26. if (newShape._orient != 'vertical') {
  27. var y = newPointList[0][1];
  28. for (var i = 0; i < newPointListLen; i++) {
  29. oldPointList[i] = [newPointList[i][0], y];
  30. }
  31. }
  32. else {
  33. var x = newPointList[0][0];
  34. for (var i = 0; i < newPointListLen; i++) {
  35. oldPointList[i] = [x, newPointList[i][1]];
  36. }
  37. }
  38. if (newShape.type == 'half-smooth-polygon') {
  39. oldPointList[newPointListLen - 1] = zrUtil.clone(newPointList[newPointListLen - 1]);
  40. oldPointList[newPointListLen - 2] = zrUtil.clone(newPointList[newPointListLen - 2]);
  41. }
  42. oldShape = {style : {pointList : oldPointList}};
  43. }
  44. oldPointList = oldShape.style.pointList;
  45. var oldPointListLen = oldPointList.length;
  46. if (oldPointListLen == newPointListLen) {
  47. newShape.style.pointList = oldPointList;
  48. }
  49. else if (oldPointListLen < newPointListLen) {
  50. // 原来短,新的长,补全
  51. newShape.style.pointList = oldPointList.concat(newPointList.slice(oldPointListLen));
  52. }
  53. else {
  54. // 原来长,新的短,截断
  55. newShape.style.pointList = oldPointList.slice(0, newPointListLen);
  56. }
  57. zr.addShape(newShape);
  58. newShape.__animating = true;
  59. zr.animate(newShape.id, 'style')
  60. .when(
  61. duration,
  62. { pointList: newPointList }
  63. )
  64. .during(function () {
  65. // Updating bezier points
  66. if (newShape.updateControlPoints) {
  67. newShape.updateControlPoints(newShape.style);
  68. }
  69. })
  70. .done(function() {
  71. newShape.__animating = false;
  72. })
  73. .start(easing);
  74. }
  75. /**
  76. * 复制样式
  77. *
  78. * @inner
  79. * @param {Object} target 目标对象
  80. * @param {Object} source 源对象
  81. * @param {...string} props 复制的属性列表
  82. */
  83. function cloneStyle(target, source) {
  84. var len = arguments.length;
  85. for (var i = 2; i < len; i++) {
  86. var prop = arguments[i];
  87. target.style[prop] = source.style[prop];
  88. }
  89. }
  90. /**
  91. * 方型动画
  92. *
  93. * @param {ZRender} zr
  94. * @param {shape} oldShape
  95. * @param {shape} newShape
  96. * @param {number} duration
  97. * @param {tring} easing
  98. */
  99. function rectangle(zr, oldShape, newShape, duration, easing) {
  100. var newShapeStyle = newShape.style;
  101. if (!oldShape) { // add
  102. oldShape = {
  103. position : newShape.position,
  104. style : {
  105. x : newShapeStyle.x,
  106. y : newShape._orient == 'vertical'
  107. ? newShapeStyle.y + newShapeStyle.height
  108. : newShapeStyle.y,
  109. width: newShape._orient == 'vertical'
  110. ? newShapeStyle.width : 0,
  111. height: newShape._orient != 'vertical'
  112. ? newShapeStyle.height : 0
  113. }
  114. };
  115. }
  116. var newX = newShapeStyle.x;
  117. var newY = newShapeStyle.y;
  118. var newWidth = newShapeStyle.width;
  119. var newHeight = newShapeStyle.height;
  120. var newPosition = [newShape.position[0], newShape.position[1]];
  121. cloneStyle(
  122. newShape, oldShape,
  123. 'x', 'y', 'width', 'height'
  124. );
  125. newShape.position = oldShape.position;
  126. zr.addShape(newShape);
  127. if (newPosition[0] != oldShape.position[0] || newPosition[1] != oldShape.position[1]) {
  128. zr.animate(newShape.id, '')
  129. .when(
  130. duration,
  131. {
  132. position: newPosition
  133. }
  134. )
  135. .start(easing);
  136. }
  137. newShape.__animating = true;
  138. zr.animate(newShape.id, 'style')
  139. .when(
  140. duration,
  141. {
  142. x: newX,
  143. y: newY,
  144. width: newWidth,
  145. height: newHeight
  146. }
  147. )
  148. .done(function() {
  149. newShape.__animating = false;
  150. })
  151. .start(easing);
  152. }
  153. /**
  154. * 蜡烛动画
  155. *
  156. * @param {ZRender} zr
  157. * @param {shape} oldShape
  158. * @param {shape} newShape
  159. * @param {number} duration
  160. * @param {tring} easing
  161. */
  162. function candle(zr, oldShape, newShape, duration, easing) {
  163. if (!oldShape) { // add
  164. var y = newShape.style.y;
  165. oldShape = {style : {y : [y[0], y[0], y[0], y[0]]}};
  166. }
  167. var newY = newShape.style.y;
  168. newShape.style.y = oldShape.style.y;
  169. zr.addShape(newShape);
  170. newShape.__animating = true;
  171. zr.animate(newShape.id, 'style')
  172. .when(
  173. duration,
  174. { y: newY }
  175. )
  176. .done(function() {
  177. newShape.__animating = false;
  178. })
  179. .start(easing);
  180. }
  181. /**
  182. * 环型动画
  183. *
  184. * @param {ZRender} zr
  185. * @param {shape} oldShape
  186. * @param {shape} newShape
  187. * @param {number} duration
  188. * @param {tring} easing
  189. */
  190. function ring(zr, oldShape, newShape, duration, easing) {
  191. var x = newShape.style.x;
  192. var y = newShape.style.y;
  193. var r0 = newShape.style.r0;
  194. var r = newShape.style.r;
  195. newShape.__animating = true;
  196. if (newShape._animationAdd != 'r') {
  197. newShape.style.r0 = 0;
  198. newShape.style.r = 0;
  199. newShape.rotation = [Math.PI*2, x, y];
  200. zr.addShape(newShape);
  201. zr.animate(newShape.id, 'style')
  202. .when(
  203. duration,
  204. {
  205. r0 : r0,
  206. r : r
  207. }
  208. )
  209. .done(function() {
  210. newShape.__animating = false;
  211. })
  212. .start(easing);
  213. zr.animate(newShape.id, '')
  214. .when(
  215. duration,
  216. { rotation : [0, x, y] }
  217. )
  218. .start(easing);
  219. }
  220. else {
  221. newShape.style.r0 = newShape.style.r;
  222. zr.addShape(newShape);
  223. zr.animate(newShape.id, 'style')
  224. .when(
  225. duration,
  226. {
  227. r0 : r0
  228. }
  229. )
  230. .done(function() {
  231. newShape.__animating = false;
  232. })
  233. .start(easing);
  234. }
  235. }
  236. /**
  237. * 扇形动画
  238. *
  239. * @param {ZRender} zr
  240. * @param {shape} oldShape
  241. * @param {shape} newShape
  242. * @param {number} duration
  243. * @param {tring} easing
  244. */
  245. function sector(zr, oldShape, newShape, duration, easing) {
  246. if (!oldShape) { // add
  247. if (newShape._animationAdd != 'r') {
  248. oldShape = {
  249. style : {
  250. startAngle : newShape.style.startAngle,
  251. endAngle : newShape.style.startAngle
  252. }
  253. };
  254. }
  255. else {
  256. oldShape = {style : {r0 : newShape.style.r}};
  257. }
  258. }
  259. var startAngle = newShape.style.startAngle;
  260. var endAngle = newShape.style.endAngle;
  261. cloneStyle(
  262. newShape, oldShape,
  263. 'startAngle', 'endAngle'
  264. );
  265. zr.addShape(newShape);
  266. newShape.__animating = true;
  267. zr.animate(newShape.id, 'style')
  268. .when(
  269. duration,
  270. {
  271. startAngle : startAngle,
  272. endAngle : endAngle
  273. }
  274. )
  275. .done(function() {
  276. newShape.__animating = false;
  277. })
  278. .start(easing);
  279. }
  280. /**
  281. * 文本动画
  282. *
  283. * @param {ZRender} zr
  284. * @param {shape} oldShape
  285. * @param {shape} newShape
  286. * @param {number} duration
  287. * @param {tring} easing
  288. */
  289. function text(zr, oldShape, newShape, duration, easing) {
  290. if (!oldShape) { // add
  291. oldShape = {
  292. style : {
  293. x : newShape.style.textAlign == 'left'
  294. ? newShape.style.x + 100
  295. : newShape.style.x - 100,
  296. y : newShape.style.y
  297. }
  298. };
  299. }
  300. var x = newShape.style.x;
  301. var y = newShape.style.y;
  302. cloneStyle(
  303. newShape, oldShape,
  304. 'x', 'y'
  305. );
  306. zr.addShape(newShape);
  307. newShape.__animating = true;
  308. zr.animate(newShape.id, 'style')
  309. .when(
  310. duration,
  311. {
  312. x : x,
  313. y : y
  314. }
  315. )
  316. .done(function() {
  317. newShape.__animating = false;
  318. })
  319. .start(easing);
  320. }
  321. /**
  322. * 多边形动画
  323. *
  324. * @param {ZRender} zr
  325. * @param {shape} oldShape
  326. * @param {shape} newShape
  327. * @param {number} duration
  328. * @param {tring} easing
  329. */
  330. function polygon(zr, oldShape, newShape, duration, easing) {
  331. var rect = require('zrender/shape/Polygon').prototype.getRect(newShape.style);
  332. var x = rect.x + rect.width / 2;
  333. var y = rect.y + rect.height / 2;
  334. newShape.scale = [0.1, 0.1, x, y];
  335. zr.addShape(newShape);
  336. newShape.__animating = true;
  337. zr.animate(newShape.id, '')
  338. .when(
  339. duration,
  340. {
  341. scale : [1, 1, x, y]
  342. }
  343. )
  344. .done(function() {
  345. newShape.__animating = false;
  346. })
  347. .start(easing);
  348. }
  349. /**
  350. * 和弦动画
  351. *
  352. * @param {ZRender} zr
  353. * @param {shape} oldShape
  354. * @param {shape} newShape
  355. * @param {number} duration
  356. * @param {tring} easing
  357. */
  358. function ribbon(zr, oldShape, newShape, duration, easing) {
  359. if (!oldShape) { // add
  360. oldShape = {
  361. style : {
  362. source0 : 0,
  363. source1 : newShape.style.source1 > 0 ? 360 : -360,
  364. target0 : 0,
  365. target1 : newShape.style.target1 > 0 ? 360 : -360
  366. }
  367. };
  368. }
  369. var source0 = newShape.style.source0;
  370. var source1 = newShape.style.source1;
  371. var target0 = newShape.style.target0;
  372. var target1 = newShape.style.target1;
  373. if (oldShape.style) {
  374. cloneStyle(
  375. newShape, oldShape,
  376. 'source0', 'source1', 'target0', 'target1'
  377. );
  378. }
  379. zr.addShape(newShape);
  380. newShape.__animating = true;
  381. zr.animate(newShape.id, 'style')
  382. .when(
  383. duration,
  384. {
  385. source0 : source0,
  386. source1 : source1,
  387. target0 : target0,
  388. target1 : target1
  389. }
  390. )
  391. .done(function() {
  392. newShape.__animating = false;
  393. })
  394. .start(easing);
  395. }
  396. /**
  397. * gaugePointer动画
  398. *
  399. * @param {ZRender} zr
  400. * @param {shape} oldShape
  401. * @param {shape} newShape
  402. * @param {number} duration
  403. * @param {tring} easing
  404. */
  405. function gaugePointer(zr, oldShape, newShape, duration, easing) {
  406. if (!oldShape) { // add
  407. oldShape = {
  408. style : {
  409. angle : newShape.style.startAngle
  410. }
  411. };
  412. }
  413. var angle = newShape.style.angle;
  414. newShape.style.angle = oldShape.style.angle;
  415. zr.addShape(newShape);
  416. newShape.__animating = true;
  417. zr.animate(newShape.id, 'style')
  418. .when(
  419. duration,
  420. {
  421. angle : angle
  422. }
  423. )
  424. .done(function() {
  425. newShape.__animating = false;
  426. })
  427. .start(easing);
  428. }
  429. /**
  430. * icon动画
  431. *
  432. * @param {ZRender} zr
  433. * @param {shape} oldShape
  434. * @param {shape} newShape
  435. * @param {number} duration
  436. * @param {tring} easing
  437. */
  438. function icon(zr, oldShape, newShape, duration, easing, delay) {
  439. // 避免markPoint特效取值在动画帧上
  440. newShape.style._x = newShape.style.x;
  441. newShape.style._y = newShape.style.y;
  442. newShape.style._width = newShape.style.width;
  443. newShape.style._height = newShape.style.height;
  444. if (!oldShape) { // add
  445. var x = newShape._x || 0;
  446. var y = newShape._y || 0;
  447. newShape.scale = [0.01, 0.01, x, y];
  448. zr.addShape(newShape);
  449. newShape.__animating = true;
  450. zr.animate(newShape.id, '')
  451. .delay(delay)
  452. .when(
  453. duration,
  454. {scale : [1, 1, x, y]}
  455. )
  456. .done(function() {
  457. newShape.__animating = false;
  458. })
  459. .start(easing || 'QuinticOut');
  460. }
  461. else { // mod
  462. rectangle(zr, oldShape, newShape, duration, easing);
  463. }
  464. }
  465. /**
  466. * line动画
  467. *
  468. * @param {ZRender} zr
  469. * @param {shape} oldShape
  470. * @param {shape} newShape
  471. * @param {number} duration
  472. * @param {tring} easing
  473. */
  474. function line(zr, oldShape, newShape, duration, easing) {
  475. if (!oldShape) {
  476. oldShape = {
  477. style : {
  478. xStart : newShape.style.xStart,
  479. yStart : newShape.style.yStart,
  480. xEnd : newShape.style.xStart,
  481. yEnd : newShape.style.yStart
  482. }
  483. };
  484. }
  485. var xStart = newShape.style.xStart;
  486. var xEnd = newShape.style.xEnd;
  487. var yStart = newShape.style.yStart;
  488. var yEnd = newShape.style.yEnd;
  489. cloneStyle(
  490. newShape, oldShape,
  491. 'xStart', 'xEnd', 'yStart', 'yEnd'
  492. );
  493. zr.addShape(newShape);
  494. newShape.__animating = true;
  495. zr.animate(newShape.id, 'style')
  496. .when(
  497. duration,
  498. {
  499. xStart: xStart,
  500. xEnd: xEnd,
  501. yStart: yStart,
  502. yEnd: yEnd
  503. }
  504. )
  505. .done(function() {
  506. newShape.__animating = false;
  507. })
  508. .start(easing);
  509. }
  510. /**
  511. * markline动画
  512. *
  513. * @param {ZRender} zr
  514. * @param {shape} oldShape
  515. * @param {shape} newShape
  516. * @param {number} duration
  517. * @param {tring} easing
  518. */
  519. function markline(zr, oldShape, newShape, duration, easing) {
  520. easing = easing || 'QuinticOut';
  521. newShape.__animating = true;
  522. zr.addShape(newShape);
  523. var newShapeStyle = newShape.style;
  524. var animationDone = function () {
  525. newShape.__animating = false;
  526. };
  527. var x0 = newShapeStyle.xStart;
  528. var y0 = newShapeStyle.yStart;
  529. var x2 = newShapeStyle.xEnd;
  530. var y2 = newShapeStyle.yEnd;
  531. if (newShapeStyle.curveness > 0) {
  532. newShape.updatePoints(newShapeStyle);
  533. var obj = { p: 0 };
  534. var x1 = newShapeStyle.cpX1;
  535. var y1 = newShapeStyle.cpY1;
  536. var newXArr = [];
  537. var newYArr = [];
  538. var subdivide = curveTool.quadraticSubdivide;
  539. zr.animation.animate(obj)
  540. .when(duration, { p: 1 })
  541. .during(function () {
  542. // Calculate subdivided curve
  543. subdivide(x0, x1, x2, obj.p, newXArr);
  544. subdivide(y0, y1, y2, obj.p, newYArr);
  545. newShapeStyle.cpX1 = newXArr[1];
  546. newShapeStyle.cpY1 = newYArr[1];
  547. newShapeStyle.xEnd = newXArr[2];
  548. newShapeStyle.yEnd = newYArr[2];
  549. zr.modShape(newShape);
  550. })
  551. .done(animationDone)
  552. .start(easing);
  553. }
  554. else {
  555. zr.animate(newShape.id, 'style')
  556. .when(0, {
  557. xEnd: x0,
  558. yEnd: y0
  559. })
  560. .when(duration, {
  561. xEnd: x2,
  562. yEnd: y2
  563. })
  564. .done(animationDone)
  565. .start(easing);
  566. }
  567. }
  568. return {
  569. pointList : pointList,
  570. rectangle : rectangle,
  571. candle : candle,
  572. ring : ring,
  573. sector : sector,
  574. text : text,
  575. polygon : polygon,
  576. ribbon : ribbon,
  577. gaugePointer : gaugePointer,
  578. icon : icon,
  579. line : line,
  580. markline : markline
  581. };
  582. });