【问题标题】:Fabricjs trouble getting radio button to set fabric object changeFabricjs 无法获取单选按钮来设置织物对象更改
【发布时间】:2019-08-20 11:54:21
【问题描述】:

我无法让我的单选按钮更改单击时添加到织物画布的对象。每次更改单选按钮时,新的图标颜色都会保持为绿色,它应该已更改为所选颜色。

我正在寻找的行为是,当您选择绿色、黄色或红色单选按钮时,放置在画布上的下一个图标应变为所选颜色。

有什么想法吗?

function iconSet() {
  var canvas = new fabric.Canvas('c');
  if (document.getElementById("green").checked == true) {
    var iconGreen = new fabric.Triangle({
      width: 62.5,
      height: 50,
      originX: 'center',
      originY: 'center',
      fill: 'green'
    });

    canvas.add(iconGreen);

    canvas.on('mouse:move', function(obj) {
      iconGreen.top = obj.e.y - 30;
      iconGreen.left = obj.e.x - 10;
      canvas.renderAll()
    })
    canvas.on('mouse:out', function(obj) {
      iconGreen.top = -100;
      iconGreen.left = -100;
      canvas.renderAll()
    })
    canvas.on('mouse:up', function(obj) {
      canvas.add(iconGreen.clone());
      canvas.renderAll();
    })
  } else if (document.getElementById("yellow").checked == true) {
    var iconYellow = new fabric.Triangle({
      width: 62.5,
      height: 50,
      originX: 'center',
      originY: 'center',
      fill: 'yellow'
    });

    canvas.add(iconYellow);

    canvas.on('mouse:move', function(obj) {
      iconYellow.top = obj.e.y - 30;
      iconYellow.left = obj.e.x - 10;
      canvas.renderAll()
    })

    canvas.on('mouse:out', function(obj) {
      iconYellow.top = -100;
      iconYellow.left = -100;
      canvas.renderAll()
    })

    canvas.on('mouse:up', function(obj) {
      canvas.add(iconYellow.clone());
      canvas.renderAll();
    })
  } else if (document.getElementById("red").checked == true) {
    var iconRed = new fabric.Triangle({
      width: 62.5,
      height: 50,
      originX: 'center',
      originY: 'center',
      fill: 'red'
    });

    canvas.add(iconRed);

    canvas.on('mouse:move', function(obj) {
      iconRed.top = obj.e.y - 30;
      iconRed.left = obj.e.x - 10;
      canvas.renderAll()
    })

    canvas.on('mouse:out', function(obj) {
      iconRed.top = -100;
      iconRed.left = -100;
      canvas.renderAll()
    })

    canvas.on('mouse:up', function(obj) {
      canvas.add(iconRed.clone());
      canvas.renderAll();
    })
  }
}
canvas {
  border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>


Green<input name="iconType" type="radio" id="green" onclick="iconSet()" /> Yellow

<input name="iconType" type="radio" id="yellow" onclick="iconSet()" /> Red

<input name="iconType" type="radio" id="red" onclick="iconSet()" />

<canvas id="c" width="600" height="600"></canvas>

【问题讨论】:

    标签: javascript fabricjs


    【解决方案1】:

    当您每次创建 new fabric.Triangle 时,您可以创建一次,当单选按钮值更改时,将使用 fabricTriangle.setFill() 方法更新现有 fabricTriangle 的颜色。

    见下面代码sn-p

    document.getElementById('green').checked = true;
    
    var canvas = new fabric.Canvas('c'),
      fabricTriangle = getfabricTriangle('green');
    
    canvas.on('mouse:move', function(obj) {
      fabricTriangle.top = obj.e.y - 30;
      fabricTriangle.left = obj.e.x - 10;
      canvas.renderAll()
    });
    
    canvas.on('mouse:out', function(obj) {
      fabricTriangle.top = -100;
      fabricTriangle.left = -100;
      canvas.renderAll()
    });
    
    canvas.on('mouse:up', function(obj) {
      canvas.add(fabricTriangle.clone());
      canvas.renderAll();
    });
    
    canvas.add(fabricTriangle)
    
    function getfabricTriangle(color) {
      if (!fabricTriangle) {
      //If it is not created then first will create and return..
         return new fabric.Triangle({
          width: 62.5,
          height: 50,
          originX: 'center',
          originY: 'center',
          fill: color
        });
      } /*else {
      //just changing the color of exiting fabric.Triangle...
        fabricTriangle.setFill(color)
      }*/
    }
    
    function iconSet() {
      fabricTriangle.setFill(document.querySelector('input[type="radio"]:checked').value)
    }
    canvas {
      border: 1px solid #ccc;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
    
    
    Green
    <input name="iconType" type="radio" id="green" onclick="iconSet()" value="green" /> 
    
    Yellow
    <input name="iconType" type="radio" id="yellow" onclick="iconSet()" value="yellow" /> 
    
    Red
    <input name="iconType" type="radio" id="red" onclick="iconSet()" value="red" />
    
    <canvas id="c" width="600" height="600"></canvas>

    【讨论】:

      【解决方案2】:

      尝试全局声明画布和对象变量,并更改对象的填充属性和单选按钮更改时画布的触发方法

      icon.setFill("yellow");
      canvas.renderAll();  
      canvas.trigger('object:modified', {target: icon});
      

      示例

      var canvas = new fabric.Canvas('c');
      var iconTriangle = new fabric.Triangle({
          width: 62.5,
          height: 50,
          originX: 'center',
          originY: 'center',
          fill:"green"
      });
      canvas.add(iconTriangle);
      
      canvas.on('mouse:move', function(obj) {
          iconTriangle.top = obj.e.y - 30;
          iconTriangle.left = obj.e.x - 10;
          canvas.renderAll()
      });
      canvas.on('mouse:out', function(obj) {
          iconTriangle.top = -100;
          iconTriangle.left = -100;
          canvas.renderAll()
      });
      canvas.on('mouse:up', function(obj) {
          canvas.add(iconTriangle.clone());
          canvas.renderAll();
      });
      
      function iconSet() {
          if (document.getElementById("green").checked == true) {
              iconTriangle.setFill("green");
              canvas.renderAll();
          } 
          else if (document.getElementById("yellow").checked == true) {
              iconTriangle.setFill("yellow");
              canvas.renderAll();
         }
         else if (document.getElementById("red").checked == true) {
              iconTriangle.setFill("red");
              canvas.renderAll();
          }
      }
      canvas {
        border: 1px solid #ccc;
      }
      <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
      
      Green<input name="iconType" type="radio" id="green" onclick="iconSet()" /> Yellow
      <input name="iconType" type="radio" id="yellow" onclick="iconSet()" /> Red
      <input name="iconType" type="radio" id="red" onclick="iconSet()" />
      <canvas id="c" width="300" height="300"></canvas>

      【讨论】:

      • 这个答案对我来说是最好的解决方案。但是,即使在移动现有图标时,mouse:up 事件也会触发放置图标。我可以使用以下命令关闭mouse:up 事件,但无法重新打开事件侦听器。 canvas.on('mouse:over', function (obj) { canvas.off('mouse:up'); }); & canvas.on('mouse:out', function (obj) { canvas.on('mouse:up'); });
      • 在设置 fill 后,我对您的 sn-p 手动触发 object:modified 事件感到头疼。有什么意义?
      • 简而言之。通知 Canvas 对象中的某些内容被修改包含在画布中。它告诉画布发生了哪些变化。
      • 它并没有真正通知 Canvas 任何有意义的事情。它只是触发附加到object:modified 事件的事件侦听器。默认情况下,Fabric.js 在内部没有附加到此事件的侦听器。您可以致电console.log(canvas.__eventListeners['object:modified']) 进行检查。
      • 是的。你说的对。即使没有它。误会了。
      【解决方案3】:

      问题是您创建了canvas 和要在function 中添加的图标,然后您就忘记了它们。在函数内部定义一个变量是没有问题的,但是你需要保证以后能够引用它。 var 变量是function 范围的,这意味着您将无法从function 调用之外访问这些变量,即使您再次调用function。此外,您重新创建这些对象,但是,您需要确保能够跟踪您打算使用的变量并且不重新创建您的画布对象。这里有一个快速修复:

      var canvas = new fabric.Canvas('c');
      var icons = {
          green: null,
          yellow: null,
          red: null
      };
      function iconSet() {
        for (var ic in icons)
          if (icons[ic]) {
            canvas.remove(icons[ic]);
            icons[ic] = null;
          }
        if (document.getElementById("green").checked == true) {
          var iconGreen = new fabric.Triangle({
            width: 62.5,
            height: 50,
            originX: 'center',
            originY: 'center',
            fill: 'green'
          });
      
          canvas.add(icons.green = iconGreen);
      
          canvas.on('mouse:move', function(obj) {
            iconGreen.top = obj.e.y - 30;
            iconGreen.left = obj.e.x - 10;
            canvas.renderAll()
          })
          canvas.on('mouse:out', function(obj) {
            iconGreen.top = -100;
            iconGreen.left = -100;
            canvas.renderAll()
          })
          canvas.on('mouse:up', function(obj) {
            canvas.add(iconGreen.clone());
            canvas.renderAll();
          })
        } else if (document.getElementById("yellow").checked == true) {
          var iconYellow = new fabric.Triangle({
            width: 62.5,
            height: 50,
            originX: 'center',
            originY: 'center',
            fill: 'yellow'
          });
      
          canvas.add(icons.yellow = iconYellow);
      
          canvas.on('mouse:move', function(obj) {
            iconYellow.top = obj.e.y - 30;
            iconYellow.left = obj.e.x - 10;
            canvas.renderAll()
          })
      
          canvas.on('mouse:out', function(obj) {
            iconYellow.top = -100;
            iconYellow.left = -100;
            canvas.renderAll()
          })
      
          canvas.on('mouse:up', function(obj) {
            canvas.add(iconYellow.clone());
            canvas.renderAll();
          })
        } else if (document.getElementById("red").checked == true) {
          var iconRed = new fabric.Triangle({
            width: 62.5,
            height: 50,
            originX: 'center',
            originY: 'center',
            fill: 'red'
          });
      
          canvas.add(icons.red = iconRed);
      
          canvas.on('mouse:move', function(obj) {
            iconRed.top = obj.e.y - 30;
            iconRed.left = obj.e.x - 10;
            canvas.renderAll()
          })
      
          canvas.on('mouse:out', function(obj) {
            iconRed.top = -100;
            iconRed.left = -100;
            canvas.renderAll()
          })
      
          canvas.on('mouse:up', function(obj) {
            canvas.add(iconRed.clone());
            canvas.renderAll();
          })
        }
      }
      

      按照我解释的想法,请参阅Fiddle。您可能想进一步重构它,但这是一个好的开始。

      【讨论】:

        【解决方案4】:

        这可能是您需要的。我还清理了代码使其更短 JsFiddle:https://jsfiddle.net/96nceasu/3/

        var canvas = new fabric.Canvas('c');
        function iconSet(ele){
              var icon = new fabric.Triangle({
                  width: 62.5,
                  height: 50,
                  originX: 'center',
                  originY: 'center',
                  fill: ele.id
                });
                canvas.add(icon);
                canvas.on('mouse:move', function(obj) {
                  icon.fill = ele.id;
                  icon.top = obj.e.y - 30;
                  icon.left = obj.e.x - 10;
                  canvas.renderAll()
                })
                canvas.on('mouse:out', function(obj) {
                  icon.top = -100;
                  icon.left = -100;
                  canvas.renderAll()
                })
                canvas.on('mouse:up', function(obj) {
                  canvas.add(icon.clone());
                  canvas.renderAll();
                })
              
            }
        canvas{
              border: 1px solid #ccc;
            }
            <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
            Green<input name="iconType" type="radio" id="green" onclick="iconSet(this)" /> Yellow
            <input name="iconType" type="radio" id="yellow" onclick="iconSet(this)" /> Red
            <input name="iconType" type="radio" id="red" onclick="iconSet(this)" />
            <canvas id="c" width="600" height="600"></canvas>

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-07-02
          • 1970-01-01
          • 2019-10-05
          • 2013-06-14
          • 1970-01-01
          • 2020-07-14
          • 2022-01-14
          • 1970-01-01
          相关资源
          最近更新 更多