Bézier Curves
- TSX
- TS
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
view.add(
<CubicBezier
ref={bezier}
lineWidth={6}
stroke={'lightseagreen'}
p0={[-200, -70]}
p1={[120, -120]}
p2={[-120, 120]}
p3={[200, 70]}
end={0}
/>,
);
yield* bezier().end(1, 1);
yield* bezier().start(1, 1).to(0, 1);
});
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
const cubicBezierElement = new CubicBezier({
lineWidth: 6,
stroke: 'lightseagreen',
p0: [-200, -70],
p1: [120, -120],
p2: [-120, 120],
p3: [200, 70],
end: 0,
});
bezier(cubicBezierElement);
view.add(cubicBezierElement);
yield* bezier.end(1, 1);
yield* bezier.start(1, 1).to(0, 1);
});
Bézier curves are ubiquitous in computer graphics. Canvas Commons comes with components to draw both quadratic and cubic Bézier curves.
If you're trying to draw more complicated shapes than single Bézier curves allow
for, check out the Spline component, instead.
Using the components
Each example below applies to both the QuadBezier and
CubicBezier nodes. You can switch between the two types of
curves using the dropdown on the right side of the animation player.
Defining control points
Bézier curves are defined by a start and end point, as well as several control points. The exact number of control points is different for different kinds of Bézier curves. A quadratic Bézier curve has only a single control point whereas a cubic Bézier curve has two.
- TSX
- TS
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
view.add(
<CubicBezier
ref={bezier}
lineWidth={6}
stroke={'lightseagreen'}
p0={[-200, -70]}
p1={[120, -120]}
p2={[-120, 120]}
p3={[200, 70]}
/>,
);
yield* waitFor(1);
});
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
const cubicBezierElement = new CubicBezier({
lineWidth: 6,
stroke: 'lightseagreen',
p0: [-200, -70],
p1: [120, -120],
p2: [-120, 120],
p3: [200, 70],
});
bezier(cubicBezierElement);
view.add(cubicBezierElement);
yield* waitFor(1);
});
All points of a Bézier curve are compound signals. This means that it's possible
to animate their x and y components separately.
- TSX
- TS
view.add(
<CubicBezier
ref={bezier}
lineWidth={6}
stroke={'lightseagreen'}
p0={[-200, -70]}
p1={[120, -120]}
p2={[-120, 120]}
p3={[200, 70]}
/>,
);
yield * bezier().p0.x(200, 1);
const cubicBezierElement = new CubicBezier({
lineWidth: 6,
stroke: 'lightseagreen',
p0: [-200, -70],
p1: [120, -120],
p2: [-120, 120],
p3: [200, 70],
});
bezier(cubicBezierElement);
view.add(cubicBezierElement);
yield * bezier.p0.x(200, 1);
Drawing arrows
Similar to the Line and Spline components, we can also add
arrowheads to a Bézier curve. To do so, we can use the
startArrow and endArrow properties. We can
control the size of the arrowheads with the arrowSize signal.
- TSX
- TS
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
view.add(
<CubicBezier
ref={bezier}
lineWidth={6}
stroke={'lightseagreen'}
p0={[-200, -70]}
p1={[120, -120]}
p2={[-120, 120]}
p3={[200, 70]}
arrowSize={16}
startArrow
endArrow
/>,
);
yield* bezier().arrowSize(20, 1).to(10, 1).to(16, 1);
});
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
const cubicBezierElement = new CubicBezier({
lineWidth: 6,
stroke: 'lightseagreen',
p0: [-200, -70],
p1: [120, -120],
p2: [-120, 120],
p3: [200, 70],
arrowSize: 16,
startArrow: true,
endArrow: true,
});
bezier(cubicBezierElement);
view.add(cubicBezierElement);
yield* bezier.arrowSize(20, 1).to(10, 1).to(16, 1);
});
Since startArrow and endArrow are booleans, they don't lend themselves well
to being animated. To animate adding arrows to a Bézier curve, we should animate
arrowSize, instead.
- TSX
- TS
view.add(
<QuadBezier
ref={bezier}
p0={[-150, 50]}
p1={[0, -120]}
p2={[150, 50]}
arrowSize={0}
startArrow
endArrow
/>,
);
yield * bezier().arrowSize(16, 1);
const quadBezierElement = new QuadBezier({
p0: [-150, 50],
p1: [0, -120],
p2: [150, 50],
arrowSize: 0,
startArrow: true,
endArrow: true,
});
bezier(quadBezierElement);
view.add(quadBezierElement);
yield * bezier.arrowSize(16, 1);
Examples
The following section shows examples of common animations for Bézier curves.
- TSX
- TS
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
view.add(
<CubicBezier
ref={bezier}
lineWidth={6}
stroke={'lightseagreen'}
p0={[-200, -70]}
p1={[120, -120]}
p2={[-120, 120]}
p3={[200, 70]}
end={0}
/>,
);
yield* bezier().end(1, 2).to(0, 2);
});
import ...
export default makeScene2D(function* (view) {
const bezier = createRef<CubicBezier>();
const cubicBezierElement = new CubicBezier({
lineWidth: 6,
stroke: 'lightseagreen',
p0: [-200, -70],
p1: [120, -120],
p2: [-120, 120],
p3: [200, 70],
end: 0,
});
bezier(cubicBezierElement);
view.add(cubicBezierElement);
yield* bezier.end(1, 2).to(0, 2);
});