创建画布对象数组

时间:2018-04-11 20:09:08

标签: javascript arrays canvas

我已经读过你可以创建一个任何东西的数组。在我努力学习javaScript / canvas的过程中,我开始创建一个形状数组。这个想法是有一个三个圆圈的阵列。 Math.floor将用于抓取一个元素/圆并在画布上显示它。我把代码放在一起,对我来说很有意义......我已经创建了一个数组,我已经填充了数组,我从数组中抓取了一个随机元素......我还没有达到必须在画布上显示它,因为无论我的方法如何,所有三个圆圈总是在画布上。掌握这个概念会很酷。你能告诉我为什么这段代码不起作用吗?先感谢您。

 <script>
        var canvas = document.getElementById("canvas");
        var c = canvas.getContext("2d");

        var objects = [];
        objects[0] = 
            [c.beginPath(),
            c.lineWidth = 5,
            c.strokeStyle = 'red',
            c.arc(200, 200, 50, 0, Math.PI * 2, false),
            c.stroke()];

        objects[1] = 
            [c.beginPath(),
            c.lineWidth = 5,
            c.strokeStyle = 'dimgray',
            c.arc(600, 200, 50, 0, Math.PI * 2, false),
            c.stroke()];

        objects[2] = 
            [c.beginPath(),
            c.lineWidth = 5,
            c.strokeStyle = 'purple',
            c.arc(1000, 200, 50, 0, Math.PI * 2, false),
            c.stroke()];

        for (var i = 0; i < objects.length; i++) {
            objects[i] = Math.floor(Math.random() * 3);}    

</script>

2 个答案:

答案 0 :(得分:2)

你应该创建一个以drawCirclecanvas为参数的函数color

const drawCircle = (canvas, color = "red") =>
{
  canvas.beginPath ()
  canvas.lineWidth = 5
  canvas.strokeStyle = color
  canvas.arc (95, 50, 40, 0, 2 * Math.PI)
  canvas.stroke ()
}

const getCanvas = (id) =>
  document.getElementById(id).getContext("2d")

drawCircle (getCanvas('canvas-1')) // default "red"
drawCircle (getCanvas('canvas-2'), 'dimgray')
drawCircle (getCanvas('canvas-3'), 'purple')
<canvas id="canvas-1"></canvas>
<canvas id="canvas-2"></canvas>
<canvas id="canvas-3"></canvas>

我们可以为位置半径线宽添加其他参数,但是我们如何知道将它们传递到哪个顺序?更好的选择是传递具有默认值的描述符对象。

const drawCircle = (canvas, descriptor = {}) =>
{
  const { x = 95
        , y = 50
        , radius = 40
        , lineWidth = 5
        , color = "red"
        } = descriptor

  canvas.beginPath ()
  canvas.lineWidth = lineWidth
  canvas.strokeStyle = color
  canvas.arc (x, y, radius, 0, 2 * Math.PI)
  canvas.stroke ()
}

const getCanvas = (id) =>
  document.getElementById(id).getContext("2d")

drawCircle (getCanvas('canvas-1')) // default styles
drawCircle (getCanvas('canvas-2'), { color: 'dimgray' })
drawCircle (getCanvas('canvas-3'), { color: 'purple', radius: 10 })
<canvas id="canvas-1"></canvas>
<canvas id="canvas-2"></canvas>
<canvas id="canvas-3"></canvas>

上面,我们使用命名参数descriptor,但我们也可以内联它。因为描述符包含很多属性,所以可读性会受到一些影响,并使我们函数的先前版本更好一些。

const drawCircle = (canvas, { x=95, y=50, radius=40, lineWidth=5, color="red" } = {}) => {
  canvas.beginPath ()
  canvas.lineWidth = lineWidth
  canvas.strokeStyle = color
  canvas.arc (x, y, radius, 0, 2 * Math.PI)
  canvas.stroke ()
}

现在,使用drawCircle您可以创建预设,例如

const FatPurpleCircle = canvas =>
  drawCircle (canvas, { color: "purple", lineWidth: 10 })

const SmallBlueCircle = canvas =>
  drawCircle (canvas, { color: "blue", radius: 5 })

你可以拥有一组名为circles的预设。给定一个返回数组随机元素的函数sample,我们可以选择一个随机圆函数,并用它在提供的画布上绘制其内容

const circles =
  [ FatPurpleCircle, SmallBlueCircle, ... ]

const sample = (arr = []) => {
  const size = arr.length
  const rand = Math.floor (Math.random () * size)
  return arr[rand]
}

const drawRandomCircle =
  sample (circles)

drawRandomCircle (getCanvas('canvas-1'))

答案 1 :(得分:0)

你有一个选择是存储每个&#34;画布&#34;在函数中,然后全部存储在数组中。这将最终接近您之前使用的相同格式,但通过不同的方法。 @Patrick Roberts在评论中提到了类似的方法。

help?> Dict
# ...
  Given a single iterable argument, constructs a Dict whose key-value pairs
  are taken from 2-tuples (key,value) generated by the argument.

Here是Codepen演示此实现。

至于为什么它不起作用,@Xofox在他的评论中解释得非常好:

  

[...]您无法在数组中存储代码行。 c.arc(600,200,50,0,Math.PI * 2,false)将执行该方法,然后返回undefined。该数组存储结果未定义。