Skip to content

Custom Objects

Christopher Venczel edited this page Dec 23, 2021 · 6 revisions

Introduction

The app features two main types of objects: Konva objects and Custom objects. Konva objects are objects rendered directly onto an HTML canvas by using the Konva.js 2d canvas library and they include: rectangles, ellipses, stars, triangles, lines, texts, images, videos, and drawings. The second major type of object is the "custom" object which renders in it's own HTML div element and includes objects such as polls, timers, iFrames, inputs, games and other interactive objects. The custom objects are designed in such a way that you can create any type of React component and have them behave like a Konva object (they can be dragged/transformed, right clicked, cut/copy/pasted/deleted, edited, same render system etc). The goal with custom objects was to have a system where the programmer could just put their React components into a CustomWrapper.jsx component and have it work automatically like any other Konva object.

Custom Object

There are 3 main parts to how a custom object work: KonvaHtml and the CustomWrapper, the customRect object, and the getKonvaObj function.

KonvaHtml and CustomWrapper

KonvaHtml.jsx and CustomWrapper.jsx are two files that work together to create the Custom Object system. The CustomWrapper is essentially just the shell or container around any HTML that you want in your custom object. It contains a KonvaHtml object which creates a Konva Group object with the transform properties of the custom object as well as renders the HTML for the custom object with those transform properties. Essentially KonvaHtml tries to take Konva object properties such as x, y, scale, rotation, opacity etc. and tries to convert them to CSS transform properties and apply them to the HTML inside the CustomWrapper. Every time the properties of the corresponding Konva Group changes (the custom object is being dragged/transformed), the new transformation is converted to CSS and applied to the custom HTML. This allows the user to transform the HTML as they would any other object by using the Konva Group as a proxy to apply transforms to which are then translated to the HTML object via KonvaHtml.

The customRect

Since Konva Groups don't have the ability to be transformed directly, we change the groups size by changing a Konva Rectangle in the group. The group properties automatically update when it's contents have been transformed. For example if the customRect in the group is dragged, this will also change the x, y of the entire group. Same with scaling, rotating etc. since the group acts as a container for it's objects. So by applying transforms to the customRect we can update the group properties which will trigger KonvaHtml to update the CSS transform on the HTML inside the CustomWrapper. The workflow of a custom object transform is essentially: User transforms customRect contained in Group -> Group properties update -> KonvaHtml is triggered to re-render HTML in CustomWrapper with new CSS transform properties -> Custom object is now transformed.

There were some bugs related to the customRect losing it's parent when switching pages which led to custom object transforms breaking. To fix this the edit page renders a customRect canvas which the customRect is added to before any canvas changes (e.g: page change, overlay open/close, personal area open/close) are made to ensure that the customRect always has a parent and to avoid this bug. Since this canvas is rendered separate from the rest of the render system it is always available as a ref under this.refs.customRectCanvas. It is useful to use the following line of code whenever running into similar issues: this.refs.customRectCanvas.add(this.refs.customRect);

The getKonvaObj function

The getKonvaObj simply takes in an object id and returns the corresponding Konva object. For normal Konva objects (rectangles, stars, ellipses etc.) this just returns the object whereas for custom objects it returns the corresponding Konva Group. This is mainly used to handle object selection.

Clone this wiki locally