T
T
thehighhomie2018-11-13 17:41:53
redux
thehighhomie, 2018-11-13 17:41:53

Vuex/Redux: Proper storage of objects from a 3rd party library?

Hello! I ask you to read the question to the end, it is not short, but this is because I tried to describe the problem as clearly as possible.
I am writing a complex application on Vue.js + Vuex: working with text, images and other graphic objects on canvas, for this I also use the fabric.js library.
Since the fabric.js library is not related to Vue.js, there is no reactivity in it, and I use watch to update the elements.
Now, the issue is that I've run into a problem with managing fabric.js objects in components other than where fabric.js is initialized. My question is related to the storage, it doesn’t matter Vuex or Redux, although I almost didn’t really work with Redux, but I think I’ll understand the principle.
In my case, I use the fabric.js library, but it doesn’t matter, since there are a lot of libraries for working with elements, but I will try to convey the essence clearly by touching on fabric.js.
Briefly about my implementation of rendering objects:
In the TheCanvas component, in the mounted hook, the canvas object (new fabric.Canvas) is initialized and the render method is called, where it cycles through the objects from the storage. The example is simplified, I'm not writing code that is not relevant to the question and I don't want to make a sheet 3k pixels high)

mounted () {
  this.canvas = new fabric.Canvas(this.$el, {
    selectionColor: 'rgba(0, 112, 224, 0.02)',
    selectionBorderColor: 'rgba(0, 112, 224, 0.3)'
  })

  this.render(this.elems)
},

methods: {
  render (elems) {
      elems.forEach(elem => {
        if (elem.type === 'image') {
          fabric.Image.fromURL(elem.url, imgObj => {
            imgObj.set(elem.attrs)
            this.canvas.add(imgObj)
          })
        } else if (elem.type === 'text') {
          const textObj = new fabric.Textbox(elem.content, elem.attrs)
          this.canvas.add(textObj)
        }
      })
    }
}

I add new objects to the storage manually, otherwise there is no way to add them, since any information about the fabric object can only be obtained after creating the object through new fabric
// вызов мутации добавления нового элемента
this.addElem({
  type: 'image',
  url: urls.regular,
  attrs: {
    top,
    left
  }
})

// а вот сама мутация, очень простая
addElem (state, payload) {
  state.elems.push(payload)
}

And I get the following structure of objects:
// пример с 2 типами элементов, очень просто.
store: {
  elems: [
    {
      type: 'image',
      url: 'someUrl',
      attrs: {
        top,
        left
      }
    },
    {
      type: 'text',
      content: 'Текст',
      attrs: {
        top: this.canvasSize.height / 2 - 14,
        left: this.canvasSize.width / 2 - 40,
        padding: 4,
        width: 80,
        fontFamily: 'Arial',
        fontSize: 24,
        textAlign: 'center'
      }
    }
  ]
}

So, this way of storing objects in storage does not work at all, because in other components I cannot get data about the object, such as the selected text and the style of each character, since this data can only be obtained by the method of the fabric object, which is created by example as in render (render code above):
const textObj = new fabric.Textbox(elem.content, elem.attrs)
  this.canvas.add(textObj)

  // и уже у объекта texObj я могу вызвать метод и получить нужные стили:
  textObj.getSelectionStyles()

  // или же установить новые стили для выделенных символов текста
  textObt.setSelectionStyles({ color: 'red' })

To summarize:
The way I add objects is not working, although it is suitable for most cases.
The object created by calling new fabric has a toJson method that returns the json of the object.
I thought about adding the fabric object to the json storage (the object itself cannot be transferred, otherwise it gives a maximum call stack error ...), but I don’t see the point of json, because in other components where you need to get information about a specific object (for example, like me wrote above with styles: textObj.getSelectionStyles()) I won't be able to access this method, because when the toJson method is called on the factory object, the json simply gets properties.
Let me clarify the question again:
The question is rather difficult, so I ask professionals who already have experience in developing complex applications to share how best to implement storing objects in storage and working with them.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question