0

I'm trying to create a little jQueryUI plugin that allows the user to draw rectangles on a div#canvas. The plugin extends ui.mouse and takes care of appending a helper, to visualize the process of drawing the rectangle, but it doesn't actually render it.

Instead, it should return a boxProperties object, but I haven't been able to do that. I'm fairly new to IIFEs and haven't fully grasped closures but I suspect that the solution lies somewhere there. I've tried some stuff but in lack of proper knowledge couldn't achieve anything.

The catch is that div#canvas (where the rectangles are drawn), is actually a Marionette.CollectionView and the rectangles themselves are going to be Marionette.ItemView added dynamically to the collectionview, which will render them as soon as they're drawn.

What should I add to my code, so that as soon as a rectangle is drawn, a boxProperties object is returned so that I can pass it to the rectangle ItemView in order to get it rendered?

Here's my plugin code

(function($, undefined){
    $.widget('nc.boxMaker', $.ui.mouse, {
        version: '0.0.1',

        options: {
            distance: 60
        },

        _create: function() {
            el = this.element;
            screenOffset = el.offset();
            screenOffset.left = Math.round(screenOffset.left);
            screenOffset.top = Math.round(screenOffset.top);
            this._mouseInit();
        },

        _mouseStart: function(event) {
            this.coords = [event.pageX - screenOffset.left, event.pageY - screenOffset.top];
            this.boxHelper = $(document.createElement('div'));

            this.boxHelper.css({
                "border":'1px dotted black',
                "z-index": 100,
                "position": "absolute",
                "left": this.coords[0],
                "top": this.coords[1],
                "width": 10,
                "height": 10
            });
            el.append(this.boxHelper);
        },

        _mouseDrag: function(event) {
            var x1 = this.coords[0], y1 = this.coords[1], 
                x2 = event.pageX - screenOffset.left, y2 = event.pageY - screenOffset.top;
            if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
            if (y1 > y2) { var tmp1 = y2; y2 = y1; y1 = tmp1; }
            boxProperties = {left: x1, top: y1, width: x2-x1, height: y2-y1};
            this.boxHelper.css(boxProperties);
        },

        _mouseStop: function(event) {
            this.boxHelper.remove();
            return boxProperties;
        }

    });

})(jQuery);

1 Answer 1

0

In the end I used jQuery-UI _trigger method

    _mouseStop: function(event) {
        this.boxHelper.remove();
        console.log("about to trigger view event!")
        this._trigger("stoppedDrawing", event, boxProperties);
    }

So whenever the _mouseStop method is called, we're gonna remove the helper rectangle, and trigger an event of type "stoppedDrawing" and also pass the boxProperties. Note that the full event type will be "boxmakerstoppeddrawing" because I've named my jquery-ui plugin boxMaker.

Now back in my Marionette.CollectionView i initialize the view

  initialize: function() {
    this.$el.boxMaker(); 

  },

And then I add my events

  events: {
    'boxmakerstoppeddrawing' : 'drawingHandler'
  },

Since I'm calculating stuff I have a function on my itemViewOptions, that returns the boxProperties object

  itemViewOptions: function() {
    return boxProperties;
  }

Last but not least I have my drawingHandler, that takes care of creating an instance of the Rectangle model, with the boxProperties, and adding it to the collection (which takes care of appending it)

  drawingHandler: function() {
    var rectangle = new Rectangle();
    this.collection.add(rectangle);
  }
Sign up to request clarification or add additional context in comments.

1 Comment

did u release the plugin? i want to implement the same functionality eg. a user can create a rectangle on the canvas using mouse and then assign it the width and height through some variables. when the values of the variables are updated, the rectangle is redrawn.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.