BezierCurve.js
3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* 贝塞尔曲线
* @module zrender/shape/BezierCurve
*/
import Path from '../Path';
import * as vec2 from '../../core/vector';
import {
quadraticSubdivide,
cubicSubdivide,
quadraticAt,
cubicAt,
quadraticDerivativeAt,
cubicDerivativeAt
} from '../../core/curve';
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)
];
}
}
export 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);
}
});