为 Fabric.js 个对象制作 "control panel"

Making a "control panel" for Fabric.js objects

这可能比 fabric.js 问题更笼统 javascript。

我正在查看 Fabric.jskitchensink”演示。如果单击 "Object" 选项卡,然后单击 select 左侧绘图区域中的项目,控制面板将填充 selected 对象的属性,并且有(或看起来是) ) 单向绑定:控制面板中的更改反映在 selected 对象中。

我需要实现这种控制面板,但不确定从哪里开始。我一直在查看该演示的页面源代码,但它非常密集。

有人可以在正确的方向上轻推我如何开始吗?是否涉及库或框架?我是不是想多了?我来自 Flex/Actionscript 背景,在那里做这类事情非常容易,但我仍然对 Javascript|HTML|CSS 组合的密度感到困惑.

我们在可定制的产品页面中使用了类似的功能。它与 Kitchensink 示例有点不同。在我们的系统中,您需要先向 canvas 添加一个文本对象。

主要工作流程是这样的:

  • 给每个新对象一个id给canvas:

     addText() {
        const textSample = new fabric.IText('Örnek yazı', {
            left: canvas.width * fabric.util.getRandomInt(20, 30) / 100,
            top: canvas.width * fabric.util.getRandomInt(20, 30) / 100,
            fontFamily: 'Georgia, Times, "Times New Roman", serif',
            fontSize: 30,
            id: myId //This is my id
        });
        window.canvas.add(textSample);
    }
    
  • 当在 canvas 上选择项目时,获取其 ID 并激活右栏的文本区域。

     let activeTextObjectId
     window.canvas.on({
      'object:selected': () => {  
         if (window.canvas.getActiveObject().type === 'i-text') {  
           activeTextObjectId = getIdOfSelectedObject()
           activateTextaArea() // I think you can handle this
         }
       }
     })
    
    getIdOfSelectedObject() {
        return window.canvas.getActiveObject().id
    }
    
  • 所以你有 canvas 对象的 ID。现在您可以 运行 一个函数来在 textarea keyup 事件触发时更新文本对象 (updateTextObjectInCanvas)

    document.getElementById('myTextarea').onkeyup = function () {
      updateCanvasTextObject(this.value)
    } 
    
  • 您需要一个函数,该函数通过其 ID (getObjectFromCanvasById) 从 canvas 获取对象,并更新其文本 (updateCanvasTextObject)。

    updateCanvasTextObject(value) {
      const canvasTextObject = this.getObjectFromCanvasById(activeTextObjectId)
      canvasTextObject.text = value
      window.canvas.renderAll()
    }
    
    //Instead of getting object from canvas, you can directly edit using getActiveObject() method of fabric.js
    getObjectFromCanvasById(id) {
        const canvasObject = window.canvas.getObjects().filter((item) => {
            return item.id === parseInt(id)
        })
        return canvasObject[0]
    }
    

抱歉,代码很乱,可以优化,但我认为它提供了有关工作流程的想法。 当然,您将需要在真实世界的示例中进行许多控制和验证。此外,使用 JS 库和状态管理系统(例如 Vue.js 和 Vuex)构建此应用程序会容易得多。 希望对您有所帮助。

这是我的代码real world working example