Search code examples
javascriptpaperjs

Adding custom object to Group in paperJS


In PaperJS, only regular types seem to be able to be added to a Group. Whenever I try to append the group with a custom object I get the error item._remove is not a function

Whenever I create my own object, for instance:

function textBox(point, width) {
    this.box = new Path.Rectangle({
        point: point,
        size: new Size(width,40),
        strokeColor: new Color(0,0,0,0.1),
        fillColor: 'white',
        strokeWidth: 1
    });

    this.box.onMouseUp = function(event) {
        cursor = this.point + new Point(5,2);
    }

}

and try to append this to a group:

var testGroup = new Group();
testGroup.appendTop(new textBox(new Point(0,0), 400));

The error shows up. My question is thus: how do I add custom objects to a group? Surely I can't be expected to either manually create each individual object or otherwise manipulate them all on an individual level without using Group dynamics. It seems I have to, just like every other type in PaperJS, make my object extend Item, but I so far have failed to get it to accept my constructor for it. I'm wondering what is required for it to be accepted.


Solution

  • Indeed, there currently is no built-in mechanism to extend Paper.js classes apart from compiling them along with the library.
    So for simple cases like the one that you seem to encounter, I would use a factory function that instantiates my custom object and then interact with it as with any other Paper.js object.
    For example, if your custom object is a box with a text in it, you can instantiate a group with a rectangle and a text in it and then just interact with this group.

    Here is a sketch demonstrating the solution.

    function createMyTextBox(point, content) {
        // Create a text item
        var text = new PointText({
            point: point,
            content: content,
            fontSize: 36,
            fillColor: 'red',
            justification: 'center'
        });
    
        // Create a rectangle around the text
        var rectangle = new Path.Rectangle({
            rectangle: text.bounds.scale(1.2),
            strokeColor: 'black'
        });
    
        // Create a Group that will wrap our items.
        var group = new Group([text, rectangle]);
    
        // Return the group
        return group;
    }
    
    // Create 2 text boxes
    var textBox1 = createMyTextBox(view.center, 'text 1');
    var textBox2 = createMyTextBox(view.center + [0, 100], 'text 2');
    
    // You can use text boxes like regular items.
    textBox2.translate(100, 0);
    textBox2.scale(0.8);