将折线变顺滑,其实一共就两步:获取点的集合-使用贝塞尔曲线将点连起来
-
获取点的集合
使折线变顺滑,首先要确定这条折线上的点,拿到这条线上点的集合,再把它们转化为可以用贝塞尔曲线来连接起来的点的集合,如下函数:
// 使曲线顺滑
makeSmoothCurveLine(points) {
const arr = [];
points.forEach((point, i) => {
if (i !== 0) {
const [A, B] = this.getCtrlPoint(i - 1, points);
arr.push([A.x, A.y, B.x, B.y, point.x, point.y]);
}
});
return arr;
}
/**
* 获取 模拟贝塞尔曲线关键控制点
*/
getCtrlPoint(i, points, a = 0.168, b = 0.168) {
let x0;
let y0;
let x1;
let y1;
if (points[i].x === points[i + 1].x || points[i].y === points[i + 1].y) {
a = 0;
b = 0;
}
if (i < 1) {
x0 = points[0].x + (points[1].x - points[0].x) * a;
y0 = points[0].y + (points[1].y - points[0].y) * a;
} else {
x0 = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
y0 = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
}
if (i > points.length - 3) {
const last = points.length - 1;
x1 = points[last].x - (points[last].x - points[last - 1].x) * b;
y1 = points[last].y - (points[last].y - points[last - 1].y) * b;
} else {
x1 = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
y1 = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
}
return [
{
x: x0,
y: y0
},
{
x: x1,
y: y1
}
];
}
-
在canvas中使用贝塞尔曲线函数将这些点连接起来
// 绘制线条
drawCurve() {
const canvas = document.querySelector('#creative-bar-chart-line');
if (!canvas) {
return;
}
canvas.width = this.boxWidth;
canvas.height = this.boxHeight;
this.ctx = canvas.getContext('2d');
this.ctx.beginPath();
this.ctx.moveTo(this.pointsAll[0].x, this.pointsAll[0].y);
this.pointsAll.forEach(item => {
this.ctx.bezierCurveTo(...item);
});
this.ctx.lineWidth = this.chartData.lineStyle.width;
this.ctx.strokeStyle = this.chartData.lineStyle.color;
this.ctx.stroke();
}
到此就完成啦,不清楚其中奥妙的同学可以去了解下贝塞尔曲线~