JSFiddle - React, Tailwind, and code Playground
by secretgspot
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>
Copyright (c) <a href="http://www.javageneration.com/">Chaker Nakhli</a> - Source code licensed under the terms of the Apache License, Version 2.
<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() {
...