JavaScript 如何通过多个点绘制平滑曲线

JavaScript 如何通过多个点绘制平滑曲线

在本文中,我们将学习如何使用JavaScript和canvas浏览器API以及HTML元素绘制平滑曲线通过多个点。

在网页上可视化数据或创建交互式图形时,通过多个点绘制平滑曲线可以极大地提高信息的美观性和可读性。让我们通过一些示例来了解如何实现。

示例1

在这个示例中,我们将利用巴赛尔曲线的概念,通过一组控制点来绘制平滑曲线。我们会预定义一些点,通过canvas HTML元素和其上下文API来绘制平滑曲线。

文件名:index.html

<html lang="en">
   <head>
      <title>
         How to Draw Smooth Curve Through Multiple Points using JavaScript?
      </title>

      <style>
         canvas {
         border: 1px solid #000;
         }
      </style>
   </head>
   <body>
      <canvas id="myCanvas" width="500" height="300"></canvas>

      <script>
         const canvas = document.getElementById("myCanvas");
         const context = canvas.getContext("2d");

         const points = [
            { x: 50, y: 100 },
            { x: 150, y: 200 },
            { x: 250, y: 50 },
            { x: 350, y: 150 },
            { x: 450, y: 100 },
         ];

         function drawSmoothCurve(points) {
            context.beginPath();
            context.moveTo(points[0].x, points[0].y);

            for (let i = 1; i < points.length - 1; i++) {
               const xc = (points[i].x + points[i + 1].x) / 2;
               const yc = (points[i].y + points[i + 1].y) / 2;
               context.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
            }

            // Connect the last two points with a straight line
            context.lineTo(points[points.length - 1].x, points[points.length - 1].y);
            context.stroke();
         }
         drawSmoothCurve(points);
      </script>
   </body>
</html>

示例2

在这个示例中,我们将按照上述代码结构,并使用贝塞尔曲线和Catmull-Rom样条方法通过多个点画出平滑曲线。

文件名:index.html

<html lang="en">
<head>
   <title>How to Draw Smooth Curve Through Multiple Points using JavaScript?</title>

   <style>
      canvas {
         border: 1px solid #000;
      }
   </style>
</head>
<body>
   <canvas id="myCanvas" width="500" height="300"></canvas>
   <script>
      const canvas = document.getElementById("myCanvas");
      const context = canvas.getContext("2d");

      const points = [
         { x: 50, y: 100 },
         { x: 150, y: 200 },
         { x: 250, y: 50 },
         { x: 350, y: 150 },
         { x: 450, y: 100 },
      ];
      function drawSmoothCurve(points) {
         context.beginPath();
         context.moveTo(points[0].x, points[0].y);

         // Example 1: Bézier Curves
         // context.quadraticCurveTo(cp1x, cp1y, x, y);
         // context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);

         for (let i = 1; i < points.length - 1; i++) {
            const xc = (points[i].x + points[i + 1].x) / 2;
            const yc = (points[i].y + points[i + 1].y) / 2;
            context.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
         }

         // Connect the last two points with a straight line
         context.lineTo(points[points.length - 1].x, points[points.length - 1].y);
         context.stroke();
      }

      drawSmoothCurve(points);

      // Example 2: Catmull-Rom Splines
      function catmullRomSpline(points, context) {
         context.beginPath();
         context.moveTo(points[0].x, points[0].y);

         for (let i = 1; i < points.length - 2; i++) {
            const p0 = points[i - 1];
            const p1 = points[i];
            const p2 = points[i + 1];
            const p3 = points[i + 2];
            const t = 0.5;
            const x1 = (-t * p0.x + (2 - t) * p1.x + (t - 2) * p2.x + t * p3.x) / 2;
            const y1 = (-t * p0.y + (2 - t) * p1.y + (t - 2) * p2.y + t * p3.y) / 2;
            const x2 = ((2 * t - 3) * p0.x + (3 - 4 * t) * p1.x + (1 + 2 * t) * p2.x + (-t) * p3.x) / 2;
            const y2 = ((2 * t - 3) * p0.y + (3 - 4 * t) * p1.y + (1 + 2 * t) * p2.y + (-t) * p3.y) / 2;
            const x3 = (t * p1.x + (2 - t) * p2.x) / 2;
            const y3 = (t * p1.y + (2 - t) * p2.y) / 2;
            context.bezierCurveTo(x1, y1, x2, y2,  x3, y3);
         }

         context.lineTo(points[points.length - 2].x, points[points.length - 2].y);
         context.lineTo(points[points.length - 1].x, points[points.length - 1].y);
         context.stroke();
      }
      catmullRomSpline(points, context);
   </script>
</body>
</html>

结论

总结而言,使用JavaScript通过多个点绘制平滑曲线可以极大地增强基于Web的图形和数据可视化的视觉美感和可读性。通过利用贝塞尔曲线和Catmull-Rom样条曲线的优势,我们学会了如何利用canvas HTML元素和其上下文API在JavaScript中绘制平滑曲线通过多个点。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程