Search code examples
javascriptcanvaspaperjs

In PaperJS allow the user to edit a TextItem like regular text input field?


I am using PaperJS to make a canvas app that generates balloons with text inside each balloon. However I would like to allow the user to edit the text inside each balloon to whatever they want it to say.

Is it possible to allow a user to edit a PaperJS TextItem just like a HTML text input field?


Solution

  • The short answer is no, unless you implement parallel functionality from scratch. The solution I have used is to let the user draw a rectangle then overlay the rectangle on the canvas with a textbox or textarea at the same location using absolute positioning. It requires an additional level of abstraction but can work quite well.

    It's non-trivial, but here's a basic framework that shows a bit about how it works. I may get around to making it available online at some point but it will take a bit so I'm not sure when. I'm also extracting this on-the-fly from a larger system so if you spot any errors let me know.

    var rect;
    var tool = new paper.Tool();
    
    // create a paper rectangle. it's just a visual indicator of where the
    // text will go.
    tool.onMouseDown = function(e) {
        rect = new paper.Path.Rectangle(
                   from: e.downPoint,
                   to: e.downPoint,
                   strokeColor: 'red',
                   );
    }
    
    tool.onMouseDrag = function(3) {
        if (rect) {
            rect.remove();
        }
        rect = new paper.path.Rectangle({
                from: e.downPoint,
                to: e.point,
                strokeColor: 'red'
                });
    }
    
    tool.onMouseUp = function(e) {
        var bounds = rect.bounds;
        var textarea = $("<textarea class='dynamic-textarea' " + 
                       "style='position:absolute; left:" + bounds.x +
                       "px; top:" + bounds.y + "px; width: " + bounds.width +
                       "px; height: " + bounds.height +
                       "px; resize;' placeholder='Enter text'></textarea>");
        // make the paper rectangle invisible for now. may want to show on
        // mouseover or when selected.
        rect.visible = false;
    
        // add the text area to the DOM then remember it in the path
        $("#parent-div").append(textarea);
        rect.data.textarea = textarea;
    
        // you may want to give the textarea focus, assign tab indexes, etc.
    };