首页 > 解决方案 > fabricjs中的循环元素

问题描述

我尝试从画布上的数组中绘制各种产品。现在我在一定程度上成功了。但是如果我想输出变量“articleNumber”,产品图像“oImg”会发生变化,而不是文本。该文本可能会被每个新图形覆盖,最后所有文本都与数组中的最后一个文本相同。它可能与“var text”有关。你们中的任何人都可以帮助我轻松解决这个问题吗?我对这个主题相对不熟悉,因此真的不知道要寻找什么。

for (var i = 0; i < allproducts.length; i++) {
  // Product image
  var articleNumber = allproducts[i];

  fabric.Image.fromURL('img/products/' + articleNumber + '.png', function(oImg) {
      oImg.scaleToHeight(fullHeight/10)
          .set('originX', 'center')
          .set('left', Math.floor(Math.random() * fullWidth))
          .set('top', Math.floor(Math.random() * (fullHeight - 200)))

    // Article Number
    var text = new fabric.Text('  '+ allproducts[i] + '  ', {
        left: oImg.left,
        top: oImg.top + fullHeight/10 + 2,
        originX: 'center', 
        fontSize: 9,
        fontFamily: 'Helvetica',
        textAlign: 'center',
        backgroundColor: 'white'
    });

    // Grouped Article number and Product Image
    var product = new fabric.Group([oImg, text], {
        hasControls: false,
    });

    // Add Product to Canvas
    canvas.add(product);
});
}

问候,雷登 G。

标签: javascriptcanvasfabricjs

解决方案


您的问题有一个非常简单的解决方法,可以使用let而不是在您的语句中var声明。ifor

for (let i = 0; i < allproducts.length; i++) {  
  // ...
}

问题在于,在您对 的所有回调中fromURL, 的值i停留在 for 循环完成时的最后一个值。这是因为当你用 声明i变量时var,它的作用域不仅在 for 循环内,而且在整个包含函数中。因此,只有一个i变量由所有回调共享,并且由于它们都在循环完成后运行,它们得到最后一个值i。如果你在你的回调中放置一个 console.log,你会发现确实如此。

let另一方面,当您使用时,i会为 for 循环的每次迭代创建一个新变量。这是因为let块作用域并且 for 循环是一个块。因此,每个回调都有自己唯一且正确的i.

let讨论了和之间差异var

这是您的代码的工作版本:

const allproducts = [1, 2, 3, 4];

var canvas = new fabric.Canvas('foo');

for (let i = 0; i < allproducts.length; i++) {
  // Product image
  var articleNumber = allproducts[i];

  const fullHeight = 1000;
  const fullWidth = 500;

  const imageUrl = 'https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcRlkStdmho9qfM4ofmV4lSVRV_MPmrxPu1f1Q&usqp=CAU';

  fabric.Image.fromURL(imageUrl, function(oImg) {

    oImg.scaleToHeight(fullHeight / 10)
      .set('originX', 'center')
      .set('left', Math.floor(Math.random() * fullWidth))
      .set('top', Math.floor(Math.random() * (fullHeight - 200)))

    // Article Number
    var text = new fabric.Text('  ' + allproducts[i] + '  ', {
      left: oImg.left,
      top: oImg.top + fullHeight / 10 + 2,
      originX: 'center',
      fontSize: 9,
      fontFamily: 'Helvetica',
      textAlign: 'center',
      backgroundColor: 'white'
    });

    // Grouped Article number and Product Image
    var product = new fabric.Group([oImg, text], {
      hasControls: false,
    });

    // Add Product to Canvas
    canvas.add(product);
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.1.0/fabric.min.js"></script>
<canvas id="foo" width="1200" height="1200"></canvas>


推荐阅读