BezierCurve.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. var Path = require("../Path");
  2. var vec2 = require("../../core/vector");
  3. var _curve = require("../../core/curve");
  4. var quadraticSubdivide = _curve.quadraticSubdivide;
  5. var cubicSubdivide = _curve.cubicSubdivide;
  6. var quadraticAt = _curve.quadraticAt;
  7. var cubicAt = _curve.cubicAt;
  8. var quadraticDerivativeAt = _curve.quadraticDerivativeAt;
  9. var cubicDerivativeAt = _curve.cubicDerivativeAt;
  10. /**
  11. * 贝塞尔曲线
  12. * @module zrender/shape/BezierCurve
  13. */
  14. var out = [];
  15. function someVectorAt(shape, t, isTangent) {
  16. var cpx2 = shape.cpx2;
  17. var cpy2 = shape.cpy2;
  18. if (cpx2 === null || cpy2 === null) {
  19. return [(isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t), (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t)];
  20. } else {
  21. return [(isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t), (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t)];
  22. }
  23. }
  24. var _default = Path.extend({
  25. type: 'bezier-curve',
  26. shape: {
  27. x1: 0,
  28. y1: 0,
  29. x2: 0,
  30. y2: 0,
  31. cpx1: 0,
  32. cpy1: 0,
  33. // cpx2: 0,
  34. // cpy2: 0
  35. // Curve show percent, for animating
  36. percent: 1
  37. },
  38. style: {
  39. stroke: '#000',
  40. fill: null
  41. },
  42. buildPath: function (ctx, shape) {
  43. var x1 = shape.x1;
  44. var y1 = shape.y1;
  45. var x2 = shape.x2;
  46. var y2 = shape.y2;
  47. var cpx1 = shape.cpx1;
  48. var cpy1 = shape.cpy1;
  49. var cpx2 = shape.cpx2;
  50. var cpy2 = shape.cpy2;
  51. var percent = shape.percent;
  52. if (percent === 0) {
  53. return;
  54. }
  55. ctx.moveTo(x1, y1);
  56. if (cpx2 == null || cpy2 == null) {
  57. if (percent < 1) {
  58. quadraticSubdivide(x1, cpx1, x2, percent, out);
  59. cpx1 = out[1];
  60. x2 = out[2];
  61. quadraticSubdivide(y1, cpy1, y2, percent, out);
  62. cpy1 = out[1];
  63. y2 = out[2];
  64. }
  65. ctx.quadraticCurveTo(cpx1, cpy1, x2, y2);
  66. } else {
  67. if (percent < 1) {
  68. cubicSubdivide(x1, cpx1, cpx2, x2, percent, out);
  69. cpx1 = out[1];
  70. cpx2 = out[2];
  71. x2 = out[3];
  72. cubicSubdivide(y1, cpy1, cpy2, y2, percent, out);
  73. cpy1 = out[1];
  74. cpy2 = out[2];
  75. y2 = out[3];
  76. }
  77. ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2);
  78. }
  79. },
  80. /**
  81. * Get point at percent
  82. * @param {number} t
  83. * @return {Array.<number>}
  84. */
  85. pointAt: function (t) {
  86. return someVectorAt(this.shape, t, false);
  87. },
  88. /**
  89. * Get tangent at percent
  90. * @param {number} t
  91. * @return {Array.<number>}
  92. */
  93. tangentAt: function (t) {
  94. var p = someVectorAt(this.shape, t, true);
  95. return vec2.normalize(p, p);
  96. }
  97. });
  98. module.exports = _default;