113 lines
2.7 KiB
JavaScript
113 lines
2.7 KiB
JavaScript
var Path = require("../Path");
|
|
|
|
var vec2 = require("../../core/vector");
|
|
|
|
var _curve = require("../../core/curve");
|
|
|
|
var quadraticSubdivide = _curve.quadraticSubdivide;
|
|
var cubicSubdivide = _curve.cubicSubdivide;
|
|
var quadraticAt = _curve.quadraticAt;
|
|
var cubicAt = _curve.cubicAt;
|
|
var quadraticDerivativeAt = _curve.quadraticDerivativeAt;
|
|
var cubicDerivativeAt = _curve.cubicDerivativeAt;
|
|
|
|
/**
|
|
* 贝塞尔曲线
|
|
* @module zrender/shape/BezierCurve
|
|
*/
|
|
var out = [];
|
|
|
|
function someVectorAt(shape, t, isTangent) {
|
|
var cpx2 = shape.cpx2;
|
|
var cpy2 = shape.cpy2;
|
|
|
|
if (cpx2 === null || cpy2 === null) {
|
|
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)];
|
|
} else {
|
|
return [(isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t), (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t)];
|
|
}
|
|
}
|
|
|
|
var _default = Path.extend({
|
|
type: 'bezier-curve',
|
|
shape: {
|
|
x1: 0,
|
|
y1: 0,
|
|
x2: 0,
|
|
y2: 0,
|
|
cpx1: 0,
|
|
cpy1: 0,
|
|
// cpx2: 0,
|
|
// cpy2: 0
|
|
// Curve show percent, for animating
|
|
percent: 1
|
|
},
|
|
style: {
|
|
stroke: '#000',
|
|
fill: null
|
|
},
|
|
buildPath: function (ctx, shape) {
|
|
var x1 = shape.x1;
|
|
var y1 = shape.y1;
|
|
var x2 = shape.x2;
|
|
var y2 = shape.y2;
|
|
var cpx1 = shape.cpx1;
|
|
var cpy1 = shape.cpy1;
|
|
var cpx2 = shape.cpx2;
|
|
var cpy2 = shape.cpy2;
|
|
var percent = shape.percent;
|
|
|
|
if (percent === 0) {
|
|
return;
|
|
}
|
|
|
|
ctx.moveTo(x1, y1);
|
|
|
|
if (cpx2 == null || cpy2 == null) {
|
|
if (percent < 1) {
|
|
quadraticSubdivide(x1, cpx1, x2, percent, out);
|
|
cpx1 = out[1];
|
|
x2 = out[2];
|
|
quadraticSubdivide(y1, cpy1, y2, percent, out);
|
|
cpy1 = out[1];
|
|
y2 = out[2];
|
|
}
|
|
|
|
ctx.quadraticCurveTo(cpx1, cpy1, x2, y2);
|
|
} else {
|
|
if (percent < 1) {
|
|
cubicSubdivide(x1, cpx1, cpx2, x2, percent, out);
|
|
cpx1 = out[1];
|
|
cpx2 = out[2];
|
|
x2 = out[3];
|
|
cubicSubdivide(y1, cpy1, cpy2, y2, percent, out);
|
|
cpy1 = out[1];
|
|
cpy2 = out[2];
|
|
y2 = out[3];
|
|
}
|
|
|
|
ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get point at percent
|
|
* @param {number} t
|
|
* @return {Array.<number>}
|
|
*/
|
|
pointAt: function (t) {
|
|
return someVectorAt(this.shape, t, false);
|
|
},
|
|
|
|
/**
|
|
* Get tangent at percent
|
|
* @param {number} t
|
|
* @return {Array.<number>}
|
|
*/
|
|
tangentAt: function (t) {
|
|
var p = someVectorAt(this.shape, t, true);
|
|
return vec2.normalize(p, p);
|
|
}
|
|
});
|
|
|
|
module.exports = _default; |