Javascript 如何使用HTML5画布将圆弧转换为直线?

Javascript 如何使用HTML5画布将圆弧转换为直线?,javascript,html5-canvas,Javascript,Html5 Canvas,我想将一个圆动画化为一条半径等于宽度的线,我想知道如何使用圆弧来实现这一点?或者也许有更好的方法 从 到 这是我的弧: function drawStar(x,y,size,scale,opacity,ctx){ ctx.save(); ctx.beginPath(); ctx.arc(x,y,size+scale,0,size+scale * Math.PI,false); ctx.globalAlpha = opacity ctx.closePath(); setF

我想将一个圆动画化为一条半径等于宽度的线,我想知道如何使用圆弧来实现这一点?或者也许有更好的方法

这是我的弧:

function drawStar(x,y,size,scale,opacity,ctx){
  ctx.save();
  ctx.beginPath();
  ctx.arc(x,y,size+scale,0,size+scale * Math.PI,false);
  ctx.globalAlpha = opacity
  ctx.closePath();
  setFillStyle('rgb(255,237,219)',ctx);
  ctx.fill()
  ctx.restore();
}

我尝试使用ctx.scale(n,1),但是它没有保持相同的半径(宽度),它将圆弧集合作为一个整体进行缩放(放大效果)。

您可以使用
圆弧绘制圆的左右半部分,然后在两者之间执行
fillRect

编辑:要详细说明我之前说过的话:

function init() {
  let canvas = document.getElementById('myCanvas');

  canvas.width = 400;
  canvas.height = 400;
  canvas.style.width = "400px";
  canvas.style.height = "400px";

  let ctx = canvas.getContext("2d");

  function fillArc(ctx, cx, cy, r, startDeg, endDeg) {
    ctx.beginPath();
    ctx.arc(cx, cy, r, startDeg * Math.PI / 180, endDeg * Math.PI / 180);
    ctx.fill();
  }

  function fillOval(ctx, cx, cy, r, sideLength, skipFirstArc) {
    if (!skipFirstArc) {
      fillArc(ctx, cx, cy, r, 90, 270);
    }

    ctx.fillRect(cx, cy - r, sideLength, r * 2);
    fillArc(ctx, cx + sideLength, cy, r, 270, 90);
  }

  let sideLength = 0;
  ctx.fillStyle = 'red';

  function animateOval() {
    if (sideLength === 100) {
      ctx.clearRect(0, 0, 400, 400);
    }
    else {
      fillOval(ctx, 30, 30, 25, sideLength, sideLength > 0);
    }

    ++sideLength;

    if (sideLength > 100) {
      sideLength = 0;
    }
  }

  setInterval(animateOval, 16);
}

下面是一个运行上述代码的Plunker:

您可以使用
绘制一个圆的左右两半,然后在其间执行
fillRect
来连接它们

编辑:要详细说明我之前说过的话:

function init() {
  let canvas = document.getElementById('myCanvas');

  canvas.width = 400;
  canvas.height = 400;
  canvas.style.width = "400px";
  canvas.style.height = "400px";

  let ctx = canvas.getContext("2d");

  function fillArc(ctx, cx, cy, r, startDeg, endDeg) {
    ctx.beginPath();
    ctx.arc(cx, cy, r, startDeg * Math.PI / 180, endDeg * Math.PI / 180);
    ctx.fill();
  }

  function fillOval(ctx, cx, cy, r, sideLength, skipFirstArc) {
    if (!skipFirstArc) {
      fillArc(ctx, cx, cy, r, 90, 270);
    }

    ctx.fillRect(cx, cy - r, sideLength, r * 2);
    fillArc(ctx, cx + sideLength, cy, r, 270, 90);
  }

  let sideLength = 0;
  ctx.fillStyle = 'red';

  function animateOval() {
    if (sideLength === 100) {
      ctx.clearRect(0, 0, 400, 400);
    }
    else {
      fillOval(ctx, 30, 30, 25, sideLength, sideLength > 0);
    }

    ++sideLength;

    if (sideLength > 100) {
      sideLength = 0;
    }
  }

  setInterval(animateOval, 16);
}
下面是一个运行上述代码的Plunker:

您可以使用它来“变换”弧

在计算拉伸圆的完美端点时有一些技巧,但我猜测并调整了我的数字

var c=document.getElementById(“myCanvas”);
var ctx=c.getContext(“2d”);
ctx.beginPath();
ctx.moveTo(40,20);
ctx.lineTo(100,20);
ctx.bezierCurveTo(130,20,130,60,100,60);
ctx.lineTo(40,60);
ctx.bezierCurveTo(10,60,10,20,40,20);
ctx.stroke();
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(40,80);
ctx.bezierCurveTo(68,80,68,120,40,120);
ctx.bezierCurveTo(12,120,12,80,40,80);
ctx.fill();
ctx.stroke()
您可以使用“变换”圆弧

在计算拉伸圆的完美端点时有一些技巧,但我猜测并调整了我的数字

var c=document.getElementById(“myCanvas”);
var ctx=c.getContext(“2d”);
ctx.beginPath();
ctx.moveTo(40,20);
ctx.lineTo(100,20);
ctx.bezierCurveTo(130,20,130,60,100,60);
ctx.lineTo(40,60);
ctx.bezierCurveTo(10,60,10,20,40,20);
ctx.stroke();
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(40,80);
ctx.bezierCurveTo(68,80,68,120,40,120);
ctx.bezierCurveTo(12,120,12,80,40,80);
ctx.fill();
ctx.stroke()

改用宽线宽值加上“round”
lineCap
stroke()

var ctx=c.getContext(“2d”);
ctx.lineWidth=50;
ctx.lineCap=“圆形”;
ctx.moveTo(45,25);
ctx.lineTo(45.5,25);//在IE11中,这必须稍微偏移
ctx.moveTo(45100);
ctx.lineTo(150100);
ctx.stroke()

改用宽线宽值加上“round”
lineCap
stroke()

var ctx=c.getContext(“2d”);
ctx.lineWidth=50;
ctx.lineCap=“圆形”;
ctx.moveTo(45,25);
ctx.lineTo(45.5,25);//在IE11中,这必须稍微偏移
ctx.moveTo(45100);
ctx.lineTo(150100);
ctx.stroke()