canvas 支持二次贝塞尔曲线和三次贝塞尔曲线

48 阅读1分钟

tutieshi_640x516_8s.gif

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <style type="text/css">
      #canvas {
        margin: 0 auto;
        border: 1px solid black;
      }
    </style>
  </head>

  <body>
    <canvas id="canvas" width="1000" height="500"></canvas>
  </body>
  <script type="text/javascript">
    var oCanvas = document.getElementById("canvas");
    var width = oCanvas.width;
    var height = oCanvas.height;
    var context = oCanvas.getContext("2d");
    var state = null;
    var points = [];
    var arr = [];
    var cancel = 0;
    var x = 0;
    var y = 0;
    var w = 0;
    var h = 0;
    context.strokeStyle = "black";
    context.fillStyle = "black";
    context.lineWidth = 10;
    document
      .getElementById("canvas")
      .addEventListener("mousedown", function (e) {
        state = "down";
        x = e.offsetX;
        y = e.offsetY;
        if (points.length < 4) {
          points.push({ x: x, y: y });
        } else {
          points = [];
          cancel = 0;
        }
      });
    document
      .getElementById("canvas")
      .addEventListener("mousemove", function (e) {
        w = e.offsetX;
        h = e.offsetY;
        context.clearRect(0, 0, width, height);
        if (arr.length != 0) {
          context.putImageData(arr[arr.length - 1], 0, 0, 0, 0, width, height);
        }
        if (state == "down") {
          if (points.length < 1) {
            return;
          }
          if (points.length == 1) {
            points.push({ x: w, y: h });
          } else if (points.length >= 2) {
            points[points.length - 1].x = w;
            points[points.length - 1].y = h;
          }
          if (points.length == 3) {
            if (cancel == 0) {
              cancel = 1;
              arr.pop();
            }
          }
          if (points.length == 4) {
            if (cancel == 1) {
              cancel = 2;
              arr.pop();
            }
          }
          context.beginPath();
          context.moveTo(points[0].x, points[0].y);
          if (points.length === 4) {
            context.bezierCurveTo(
              points[2].x,
              points[2].y,
              points[3].x,
              points[3].y,
              points[1].x,
              points[1].y
            );
          } else if (points.length === 3) {
            context.quadraticCurveTo(
              points[2].x,
              points[2].y,
              points[1].x,
              points[1].y
            );
          } else {
            context.lineTo(points[1].x, points[1].y);
          }
          context.lineCap = "round";
          context.stroke();
          context.lineCap = "butt";
        }
      });
    document.getElementById("canvas").addEventListener("mouseup", function (e) {
      state = null;
      if (points.length == 4) {
        points = [];
        cancel = 0;
      }
      arr.push(context.getImageData(0, 0, width, height));
    });
  </script>
</html>