【问题标题】:How to check if an object with specific id exists on a canvas with fabricjs如何使用fabricjs检查画布上是否存在具有特定ID的对象
【发布时间】:2021-05-19 11:08:00
【问题描述】:

我有一个功能,可以在单击画布内的圆圈时在鼠标按下时添加图像。现在每次我单击圆圈时都会添加一个新图像,这不是我想要的。我想要某种切换功能,以便在第二次单击时删除图像并在第三次添加新图像,依此类推。

我现在的功能是这样的:

cirkel1.on('mousedown', ()=>{
  var imgURL = 'https://i1.wp.com/nypost.com/wp-content/uploads/sites/2/2020/04/pugs-coronavirus.jpg';
  var pugImg = new Image();
  pugImg.onload = function (img) {
    var pug = new fabric.Image(pugImg, {
    width: 350,
    height: 100,
    left: 250,
    top: 70,
    scaleX: .25,
    scaleY: .25
    id: 'testimg'
    });
    canvas.add(pug);
  };
  pugImg.src = imgURL;
});

我想如果我检查画布上是否存在 pug 对象,我可以将其删除,并且仅在不存在 pug 对象时添加一个新对象。

所以我尝试了这个:

cirkel1.on('mousedown', ()=>{
  var imgURL = 'https://printzelf.nl/new/assets/images/logo_gewoon.png';
  var pugImg = new Image();
  pugImg.onload = function (img) {
    var pug = new fabric.Image(pugImg, {
    width: 350,
    height: 100,
    left: 250,
    top: 70,
    scaleX: .25,
    scaleY: .25
    id: 'testimg'
    });
    canvas.add(pug);
    if(pug > 0){
      console.log('pug exists');
    }else{
      console.log('pug doesnt exist');
    }
  };
  pugImg.src = imgURL;

});

但这总是转到这部分console.log('pug doesnt exist');,即使画布上有多个哈巴狗。

那么检查这个的正确方法是什么?

完整代码:

https://codepen.io/twan2020/pen/MWbmgqE

【问题讨论】:

    标签: javascript canvas html5-canvas fabricjs


    【解决方案1】:

    如果您想切换图像可见性,那么您只需要更改其visible 属性的布尔值。

    我们不会对每个热点圈进行硬编码,而是使用一个可以扩展的容器,以便将来添加更多。

    const hotspots = [
      {
        top: 140,
        left: 230,
        radius: 10,
        fill: '#009fe3',
        id: 'cirkel1',
        hoverCursor: 'pointer',
        selectable: false,
        imgUrl: 'https://i1.wp.com/nypost.com/wp-content/uploads/sites/2/2020/04/pugs-coronavirus.jpg' 
      }
    ];
    

    当点击热点时加载图像,我们需要跟踪已激活的热点。

    const loadedImages = [];
    

    现在我们准备好填充画布了。

    for (let [idx, props] of hotspots.entries()) {
      let c = new fabric.Circle(props);
      c.class = 'hotspot';
      c.name = 'hotspot-' + idx;
      canvas.add(c);
    }
    

    这段代码没有什么神奇之处,我们只是在热点圈中添加了两个属性classname,然后再将其添加到画布中。 class 属性将允许我们过滤画布上的对象,以便我们只将 mousedown 处理程序添加到热点圈。完成此操作后,我们现在可以添加处理程序了。

    for (const ho of canvas.getObjects()) {
      // check for 'hotspot' class
      if (ho.class && ho.class === 'hotspot') {
        ho.on('mousedown', () => {
          // check if image was previously loaded
          if (loadedImages.indexOf(ho.name) < 0) {
            // image is not in the array
            // so it needs to be loaded
            // prepare the image properties
            let imgProps = {
              width: 850,
              height: 800,
              left: (ho.left + 30),
              top: (ho.top - 30),
              scaleX: .25,
              scaleY: .25,
              id: 'img-' + ho.name
            };
            var pugImg = new Image();
            pugImg.onload = function (img) {
              var pug = new fabric.Image(pugImg, imgProps);
              canvas.add(pug);
            };
            pugImg.src = ho.imgUrl;
            // update the `loadedImages` array
            loadedImages.push(ho.name);
          } else {
            // image was previously loaded
            for (const o of canvas.getObjects()) {
              // find the correct image on the canvas
              if (o.id && o.id === 'img-' + ho.name) {
                // toggle the visible property
                o.visible = !o.visible;
                break;
              }
            }
          }
        });
      }
    }
    

    mousedown 处理程序有两个可能的执行路径。如果之前没有点击过热点,那么图像将不会被加载。我们通过在loadedImages 数组中搜索热点的name 属性的值来确定这一点。如果找不到名称,则加载图像并将名称添加到数组中。热点name用于设置图片在添加到画布之前的id。如果热点存在于数组中,则我们找到带有图像id 的画布对象并切换visible 属性。

    Codepen:https://codepen.io/danag/pen/MWbvWbo

    【讨论】:

    • 感谢您的解释!我使用了您的代码,但由于某种原因,当我单击圆圈时,我不断收到新的哈巴狗图像,它不会删除任何旧图像。你能看看是怎么回事吗?这就是我添加它的方式:codepen.io/twan2020/pen/GRNvKmX
    • 我得到的错误是:obj is not defined for:loadedImages.push(obj.name);。我不确定 obj 名称应该是什么。如果我使用loadedImages.push(pugImg.name);,则错误消失了,但在反复单击圆圈后仍然不断添加新的哈巴狗图像。而不是 add-remove-add-remove 等。
    • obj.name 更改为ho.name,代码将起作用。我已经修改了答案,我不确定当我输入 obj 而不是 ho 时我在想什么。
    • 传奇!谢谢完全符合我的需要。
    • 不同的热点有不同的图片容易吗?
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多