奥运会在HTML5画布上使用JavaScript响起

exe*_*ook 5 javascript html5 canvas

<center><canvas id=c1 width=400 height=400></canvas>
<script>
    ctx = c1.getContext('2d')
    ctx.fillStyle = '#7ef' // draw blue background with the darker frame
    ctx.fillRect(0, 0, 400, 400)
    ctx.fillStyle = '#9ff'
    ctx.fillRect(10, 10, 400-20, 400-20)

    var X = 75, W = 50, G = 20
    ctx.lineWidth = 10
    var colors = ['blue', 'black', 'red', 'yellow', 'green']
    var args = [
        [X,X,W],
        [X+W+W+G,X,W],
        [X+W+W+G+W+W+G,X,W],
        [X+W+G/2,X+W,W],
        [X+W+G/2+W+W+G,X+W,W]]

    while (colors.length > 0) {
        ctx.strokeStyle = colors.shift()
        ctx.beginPath()
        ctx.arc.apply(ctx, args.shift().concat([0,Math.PI*2,true]))
        ctx.stroke()
    }
</script>
Run Code Online (Sandbox Code Playgroud)

以上是我此时的代码.我的目标是娱乐孩子,有12岁男孩,但我的代码不够惊人,是否可以通过删除所有手工编码的坐标来减少烦恼?使戒指"互联"也很酷,但如何实现呢?

这是我当前代码的输出:

在此输入图像描述

这就是奥运会应该是这样的:

在此输入图像描述

Tib*_*bos 5

对于12岁的孩子!

我为你写了一些代码,这些代码不一定无聊或有趣,简单或困难,但它完成了工作:

var canvas = document.getElementById('c1').getContext('2d');
var radius = 50;

var circles = [
  {
    color:'blue',
    x : 2*radius - radius/2,
    y : 2*radius,
    isTop: true
  } , {
    color:'black',
    x : 4*radius,
    y : 2*radius,
    isTop: true
  } , {
    color:'red',
    x : 6*radius + radius/2,
    y : 2*radius,
    isTop: true
  } , {
    color:'yellow',
    x : 3*radius - radius/4,
    y : 3*radius,
    isTop: false
  } , {
    color:'green',
    x : 5*radius + radius/4,
    y : 3*radius,
    isTop: false
  }
];

function drawArc(canvas, color, x, y, start, end) {
  if (color !== 'white') drawArc(canvas, 'white', x, y, start, end);

  canvas.lineWidth = color === 'white' ? 16 : 10;
  canvas.strokeStyle = color;

  canvas.beginPath();
  canvas.arc(x, y, radius, start - Math.PI/2, end - Math.PI/2, true);
  canvas.stroke();
}

circles.forEach(function(circle){
  drawArc(canvas, circle.color, circle.x, circle.y, 0, Math.PI*2);
});

circles.forEach(function(circle){
  if (circle.isTop) {
     drawArc(canvas, circle.color, circle.x, circle.y, Math.PI, Math.PI*2/3);
     drawArc(canvas, circle.color, circle.x, circle.y, Math.PI*5/3, Math.PI*4/3);
  } else {
     drawArc(canvas, circle.color, circle.x, circle.y, 0, Math.PI/3);
     drawArc(canvas, circle.color, circle.x, circle.y, Math.PI*2/3, Math.PI/3);
  }
});
Run Code Online (Sandbox Code Playgroud)

http://jsbin.com/IrOJOhIg/1/edit

如果我要解释代码,我将从circle变量开始,这是一个数组,它表示每个圆圈的颜色,中心以及它是否在顶行.我会注释掉+= radius/2radius/4零部件,并为它们运行代码,显示出圈太紧在一起,并取消他们去证实更改x坐标分开移动它们.

然后我将解释drawArc绘制圆的一部分的函数,首先是白色,然后是实际颜色,以不同的线宽.这几乎是整个脚本中最困难的部分.

最后,我将再次运行脚本,并将最终的forEach注释掉,以显示最后绘制的戒指完全覆盖了之前的戒指并向12岁的孩子寻求解决方案.你应该瞄准的解决方案是绘制部分圆圈.

我从顶部开始将圆圈分成6个部分,如果你仔细看一眼它们,你会发现如果圆圈位于顶行,则可以覆盖相同的部分或在顶部.每个人的最终重绘每个圆圈的两个部分必须在交叉点的顶部.

最后,12岁的人在我的代码中注意到交叉点实际上是逆转的奖励积分,以及提出解决方案的人的更多奖励积分.(显然,最简单的解决方案是摆弄最后的forEach).编辑:实际上只是把条件!circle.isTop变得更简单.

PS:有一些舍入误差会导致弧线相交的细白线.他们可以修复,但我没有打扰他们.