Backbonejs - Add Shape Can Drag

Learn Backbonejs

by erick

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.2.1/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js"></script>
<div id="page" style="width:2000px;height:2000px;">
    <button id="new-shape">New Shape</button>
</div>

CSS

.shape{
    height: 100%;
    width: 100%;
}
.hide {
    display: none;
}
.control {
    width: 16px;
    height: 16px;
    position: absolute;
    bottom: 2px;
    cursor: pointer;
}
.resize {
    background: top left no-repeat url(http://cdn1.iconfinder.com/data/icons/fugue/icon/arrow-resize-135.png);
    right: 5px;
    cursor: nw-resize;
}
.delete {
    background: top left no-repeat url(http://cdn3.iconfinder.com/data/icons/uidesignicons/delete.png);
    right: 26px;
}

.change-color {
    background: top left no-repeat url(http://cdn1.iconfinder.com/data/icons/silk2/color_wheel.png);
    right: 47px;
}

JavaScript

var Shape = Backbone.Model.extend({
    defaults: { x:50, y:50, width:150, height:150, color:'black' },
    setTopLeft: function(x,y) { this.set({ x:x, y:y }); },
    setDim: function(w,h) { this.set({ width:w, height:h }); },
});

var ShapeView = Backbone.View.extend({ 
    initialize: function() {
        $('#page').mousemove(this, this.mousemove).mouseup(this, this.mouseup);
        this.model.bind('change', this.updateView, this);
    },
    render: function() {
        $('#page').append(this.el);
        $(this.el).html('<div class="shape"/>'
                  + '<div class="control delete hide"/>'
                  + '<div class="control change-color hide"/>'
                  + '<div class="control resize hide"/>')
            .css({ position: 'absolute', padding: '10px' });
        this.updateView();
        return this;
    },
    updateView: function() {
        $(this.el).css({
            left:       this.model.get('x'),
            top:        this.model.get('y'),
            width:      this.model.get('width') - 10,
            height:     this.model.get('height') - 10 });
        this.$('.shape').css({ background: this.model.get('color') });
    },
    events: {
        'mouseenter .shape': 'hoveringStart',
        'mouseleave': 'hoveringEnd',
        'mousedown .shape': 'draggingStart',
        'mousedown .resize': 'resizingStart',
        'mousedown .change-color': 'changeColor',
        'mousedown .delete': 'deleting',
    },
    hoveringStart: function () {
        this.$('.control').removeClass('hide');
    },
    hoveringEnd: function () {
        this.$('.control').addClass('hide');
    },
    draggingStart: function (e) {
        this.dragging = true;
        this.initialX = e.pageX - this.model.get('x');
        this.initialY = e.pageY - this.model.get('y');
        return false; // prevents text selection
    },
    resizingStart: function() {
        this.resizing = true;
        return false;
    },
    changeColor: function() {
       ...