【问题标题】:HTML5 Canvas - Changing a square into a circleHTML5 Canvas - 将正方形变为圆形
【发布时间】:2015-01-29 02:04:27
【问题描述】:

在 HTML5 画布上,我找不到制作彩色圆圈的方法。我一直在咨询this 作为参考。

这是我目前的尝试

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillRect(20, 20, 100, 100);
ctx.lineJoin = "round";
ctx.lineWidth = "cornerRadius";
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">

(同样在 jsFiddle 上:http://jsfiddle.net/kvnm21r1/1/

我尝试过使用画布arc 方法,它会创建一个圆圈,但不会给它上色。

我不能使用border-radius 属性,因为ctx 不是元素。

有什么办法可以把正方形变成圆形吗?

提前致谢。

【问题讨论】:

  • 所以你想让你的正方形在一段时间后变成一个圆形?还是你只想要一个圆圈?
  • 我想要一个圆圈。这就是我一直在努力创造的

标签: javascript css html canvas


【解决方案1】:

您可以使用二次曲线将正方形的直线“四舍五入”,直到它们形成一个圆。

// change sideCount to the # of poly sides desired
//
var sideCount = 4;


var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 2;
ctx.fillStyle = randomColor();

var PI2 = Math.PI * 2;
var cx = 150;
var cy = 150;
var radius = 100;

var xx = function (a) {
  return (cx + radius * Math.cos(a));
}
var yy = function (a) {
  return (cy + radius * Math.sin(a));
}
var lerp = function (a, b, x) {
  return (a + x * (b - a));
}

var sides = [];
for (var i = 0; i < sideCount; i++) {
  sides.push(makeSide(i, sideCount));
}

var percent = 0;
var percentDirection = 0.50;

$("#toShape").click(function () {
  percentDirection = -0.50;
})

$("#toCircle").click(function () {
  percentDirection = 0.50;
})

animate();

// functions

function animate() {
  requestAnimationFrame(animate);
  drawSides(percent);
  percent += percentDirection;
  if (percent > 100) {
    percent = 100;
  }
  if (percent < 0) {
    percent = 0;
  }
}

function drawSides(pct, color) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  if (pct == 100) {
    ctx.beginPath();
    ctx.arc(cx, cy, radius, 0, PI2);
    ctx.closePath();
    ctx.fill();
  } else {
    ctx.beginPath();
    ctx.moveTo(sides[0].x0, sides[0].y0);
    for (var i = 0; i < sideCount; i++) {
      var side = sides[i];
      var cpx = lerp(side.midX, side.cpX, pct / 100);
      var cpy = lerp(side.midY, side.cpY, pct / 100);
      ctx.quadraticCurveTo(cpx, cpy, side.x2, side.y2);
    }
    ctx.fill();
  }
}

function makeSide(n, sideCount) {
  var sweep = PI2 / sideCount;
  var sAngle = sweep * (n - 1);
  var eAngle = sweep * n;

  var x0 = xx(sAngle);
  var y0 = yy(sAngle);
  var x1 = xx((eAngle + sAngle) / 2);
  var y1 = yy((eAngle + sAngle) / 2);
  var x2 = xx(eAngle);
  var y2 = yy(eAngle);

  var dx = x2 - x1;
  var dy = y2 - y1;
  var a = Math.atan2(dy, dx);
  var midX = lerp(x0, x2, 0.50);
  var midY = lerp(y0, y2, 0.50);
  var cpX = 2 * x1 - x0 / 2 - x2 / 2;
  var cpY = 2 * y1 - y0 / 2 - y2 / 2;

  return ({
    x0: x0,
    y0: y0,
    x2: x2,
    y2: y2,
    midX: midX,
    midY: midY,
    cpX: cpX,
    cpY: cpY,
    color: randomColor()
  });
}

function randomColor() {
  return ('#' + Math.floor(Math.random() * 16777215).toString(16));
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="toShape">Animate to Shape</button>
<button id="toCircle">Animate to Circle</button><br>
<canvas id="canvas" width=300 height=300></canvas>

【讨论】:

  • 哇,太棒了。回答字面问题的第一个答案:“有什么办法,我可以将我的正方形变成圆圈吗?”虽然我觉得 OP 只是想弄清楚画一个圆圈。跨度>
  • 我怀疑同样的事情...不过我只需要制作动画 ;-) 请注意,动画的最后一点确实使用了 arc 命令(因为 qCurves 无法创建完美的圆)。所以这两个请求在技术上都得到了满足:-)
【解决方案2】:

JSfiddle with a circle

要画一个圆,您需要画一个圆弧,并有一个起始角度和一个结束角度。所以你必须使用 Pi 并定义一个半径。

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;

context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();

【讨论】:

  • 重要的一点,在调用fill() 之前设置context.fillStyle 的颜色。
【解决方案3】:

尽可能避免使用 w3schools.com。请参阅 MDN 等网站。

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
ctx.beginPath();
var radius = 50; // Arc radius
var startAngle = 0; // Starting point on circle
var endAngle = Math.PI*2; // End point on circle
ctx.arc(150, 75, radius, startAngle, endAngle, true);
ctx.fill();
&lt;canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"&gt;

【讨论】:

  • “我尝试过使用画布圆弧方法,它会创建一个圆,但不会给它上色。”。 - 你应该提到如何给圆圈上色。这不会添加任何 OP 没有做的事情。
  • @SpencerWieczorek - ctx.fill(); 填满了圆圈(从代码中可以看出这一点)。
  • 再次阅读我的评论,我根本没有看到你提到如何着色一个圆圈。为此,您需要将fillStyle 设置为某种颜色。默认为黑色。
  • @SpencerWieczorek - 那么黑色有什么问题? OP的问题是无法首先创建一个圆圈,抚摸或填充。选择颜色是次要问题。另外,我提供的 MDN 链接更详细。
  • OP问了两次如何创建彩色圆圈,并提到他们可以创建一个圆圈,但它不是彩色的。他们显然需要调用fill()(或stoke())才能在屏幕上绘制圆圈。有可能 OP 已经可以做到这一点。
猜你喜欢
  • 2011-05-22
  • 1970-01-01
  • 2014-03-13
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
相关资源
最近更新 更多