【问题标题】:How do you make a loop for canvas function which has several arguments?如何为具有多个参数的画布函数创建循环?
【发布时间】:2021-12-17 05:59:35
【问题描述】:
<canvas id="chart" width="700" height="550"></canvas>

<script>
  const canvas = document.getElementById('chart');
  const context = canvas.getContext('2d');

  /* Draw a line from (fromX, fromY) to (toX, toY) */
  function drawLine(fromX, fromY, toX, toY) {
    context.beginPath();
    context.moveTo(toX, toY);
    context.lineTo(fromX, fromY);
    context.stroke();
  }

  /* Draw a text (string) on (x, y) */
  function drawText(text, x, y) {
    context.fillStyle = 'black';
    context.fillText(text, x, y);
  }

  /* Draw a text and with a line to its right */
  function drawLineWithText(text, fromX, fromY, toX, toY) {
    drawText(text, fromX - 50, fromY + 3);
    drawLine(fromX, fromY, toX, toY);
  }

  for (var fromY = 50; fromY < 500; fromY += 50, toY = 50 toY < 500; toY += 50, fromX = 70, toX =700) {
    drawLineWithText(text, fromX, fromY, toX, toY);
  }
</script>
**强文本** 我实际上不知道如何为此做一个 for 语句,我试图玩弄,但只有在我手动完成时才设法使它工作,编写自己的参数示例; drawLineWithText(1000, 20, 30, 100, 30)

【问题讨论】:

  • 你想做什么?如果我们确切地知道您想要什么,我们可以做出更好的回应。
  • 最终目标是制作条形图,现在我只想制作线条,每条线左侧有一个y值
  • 每一步应该怎么做?文字在哪里?

标签: javascript html loops for-loop canvas


【解决方案1】:

在这种情况下,我没有看到任何需要在 for 循环中使用多个变量的特殊情况...
如果我们分解循环中的内容,我们最终会得到:

/*
    fromY = 50; fromY < 500; fromY += 50, 
      toY = 50;   toY < 500;   toY += 50, 

    fromX = 70, 
      toX = 700
*/

fromYtoY 具有相同的模式,fromXtoX 只是硬编码值...

所以为了简化你的代码,我会这样做:

const canvas = document.getElementById('chart');
const context = canvas.getContext('2d');

function drawLine(fromX, fromY, toX, toY) {
  context.beginPath();
  context.moveTo(toX, toY);
  context.lineTo(fromX, fromY);
  context.stroke();
}

for (var i = 50; i < 500; i += 50) {
  drawLine(70, i, 700, i);
}
&lt;canvas id="chart" width="700" height="550"&gt;&lt;/canvas&gt;



您可以在一个循环中包含多个变量,这绝对是可能的,但您的示例并不是它的最佳用途,这里是多个变量的一个很好的示例。

const canvas = document.getElementById('chart');
const context = canvas.getContext('2d');

function drawLine(fromX, fromY, toX, toY) {
  context.beginPath();
  context.moveTo(toX, toY);
  context.lineTo(fromX, fromY);
  context.stroke();
}

var x, y
for (x=50, y=10;  x<200, y<100;  x*=1.3, y+=9) {
  drawLine(10, y/3, x, y);
}
&lt;canvas id="chart" width="500" height="100"&gt;&lt;/canvas&gt;

这里有一些关于 for 循环结构的好读物:
https://gomakethings.com/the-anatomy-of-a-for-loop-in-vanilla-js-and-when-you-would-want-to-use-it-instead-of-array.foreach/

...它分为三个部分,每个部分用分号 (;) 分隔:

  • 在第一个分号之前,您可以声明或分配变量。
  • 在第一个和第二个分号之间,您定义了一个在每个循环后检查的条件。只要此条件为真,循环就会继续运行。一旦条件为假,循环就会停止。
  • 在第二个分号之后,您可以指定在每个循环之后运行的语句。

【讨论】:

    【解决方案2】:

    尝试将您的自定义参数收集到一个可以首先迭代的数组中。可能是这样的:

    // establish your starts, ends, and steps
    const text = 'Some text';
    
    const fromXStart = 70;
    const fromXEnd = 700;
    const fromXStep = 50;
    
    const fromYStart = 50;
    const fromYEnd = 500;
    const fromYStep = 50;
    
    const toXStart = 700;
    const toXEnd = 1000;
    const toXStep = 50;
    
    const toYStart = 50;
    const toYEnd = 500;
    const toYStep = 50;
    
    // create an object to keep track of where we are at each iteration of the loop
    const currentArgs = {
      fromX: fromXStart,
      fromY: fromYStart,
      toX: toXStart,
      toY: toYStart
    }
    
    // create a single array of args to loop over with our intial values
    const args = [
      [text, currentArgs.fromX, currentArgs.fromY, currentArgs.toX, currentArgs.toY]
    ]
    
    // create a check function to see if we're done looping (if all ends have been met)
    const isDone = () => {
      const fromXIsDone = currentArgs.fromX >= fromXEnd;
      const fromYIsDone = currentArgs.fromY >= fromYEnd;
      const toXIsDone = currentArgs.toX >= toXEnd;
      const toYIsDone = currentArgs.toY >= toYEnd;
      return fromXIsDone && fromYIsDone && toXIsDone && toYIsDone;
    }
    
    // loop until done
    while (!isDone()) {
      // use Math.min to ensure we don't go past the max
      currentArgs.fromX = Math.min(fromXEnd, currentArgs.fromX + fromXStep);
      currentArgs.fromY = Math.min(fromYEnd, currentArgs.fromY + fromYStep);
      currentArgs.toX = Math.min(toXEnd, currentArgs.toX + toXStep);
      currentArgs.toY = Math.min(toYEnd, currentArgs.toY + toYStep);
      args.push([
        text, currentArgs.fromX, currentArgs.fromY, currentArgs.toX, currentArgs.toY
      ])
    }
    
    // now loop over our args array and use the spread syntax (...) to spread the args as args
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
    for (let i = 0; i < args.length; i++) {
      drawLineWithText(...args[i]);
    }

    【讨论】:

    • 该死的家伙,你是个天才,对我来说太复杂了:O
    猜你喜欢
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-06
    • 2021-01-10
    • 1970-01-01
    • 2021-12-25
    • 2013-02-09
    相关资源
    最近更新 更多