Reputation: 8425
http://codepen.io/mikethedj4/pen/gCsih
http://jsfiddle.net/ba5Ld/3/
I'm working on a basic experimental html designer (all you do is draw divs/rectangles and resize them nothing to fancy)
I'm using ThreeDubMedia's drag plugin to accomplish the the drag and resize events.
I know using global variables is bad practice, but I couldn't figureout how to accomplish this type of effect without them.
Anyway I ran into two problems: first is divs are still draggable when select tool is inactive (which moveable is set to false in which I assume it shouldn't be dragging), two when I pick the edit tool when the mouse is down on a div it sets the contenteditable property to true, however it's not working. When I took a look in the google developer tools it shows that the property is added and active but it's not working.
Any help is greatly appreciated.
$('.start').click(function() {
moveable = 1;
drawable = false;
editable = false;
removeable = false;
$('.draw, .nodraw').removeClass('d-active e-active noselect active inactive r-active');
$(this).addClass('active noselect s-active');
if ($('.s-active').is(':visible')) {
if(moveable) {
$('#drawingArea *').addClass('moveable');
$('.moveable').drag("start",function( ev, dd ){
dd.attr = $( ev.target ).prop("className");
dd.width = $( this ).width();
dd.height = $( this ).height();
})
.drag(function( ev, dd ){
var props = {};
if ( dd.attr.indexOf("E") > -1 ){
props.width = Math.max( 32, dd.width + dd.deltaX );
}
if ( dd.attr.indexOf("S") > -1 ){
props.height = Math.max( 32, dd.height + dd.deltaY );
}
if ( dd.attr.indexOf("W") > -1 ){
props.width = Math.max( 32, dd.width - dd.deltaX );
props.left = dd.originalX + dd.width - props.width;
}
if ( dd.attr.indexOf("N") > -1 ){
props.height = Math.max( 32, dd.height - dd.deltaY );
props.top = dd.originalY + dd.height - props.height;
}
if ( dd.attr.indexOf("editable") > -1 ){
props.top = dd.offsetY;
props.left = dd.offsetX;
}
$( this ).css( props );
}, {relative:true});
$('#drawingArea *').on('mousedown touchstart', function() {
if(moveable) {
$('#drawingArea *').removeClass('editable');
$('.handle, .NN, .NE, .EE, .SE, .SS, .SW, .WW, .NW').remove();
$(this).addClass('editable').append('<div class="handle NE"></div> <div class="handle NN"></div> <div class="handle NW"></div> <div class="handle WW"></div> <div class="handle EE"></div> <div class="handle SW"></div> <div class="handle SS"></div> <div class="handle SE"></div>');
$('#drawingArea').on('mousemove touchmove', function(e) {
e.preventDefault();
});
}
});
}
} else {
moveable = false;
$('.handle, .NN, .NE, .EE, .SE, .SS, .SW, .WW, .NW').remove();
return false;
}
});
Upvotes: 0
Views: 339
Reputation: 6883
Closures are created to do this for you:
var a = 1;
(function(){ // Function call creates new scope every time.
var a = 2;
// JS look up current scope, then parent to search correct `a` variable
a = a + 1;
console.log(a) // -> 3.
})();
console.log(a) //-> 1, use local scope
One more example
var b = 1;
(function(){ // Function call nests new scope
console.log(b) // -> 1. Use 'b' from parent scope
b++; // -> 2. Increase `b` from parent scope
var b = 1; // -> 1. Define b in local scope
console.log(b) // -> 1. This `b` from local scope
})();
console.log(b) // -> 2. Search in local scope only
Each function searching for local scope then parent and so on. Now you can wrap all of your HTMLNodes
into closures. Example:
$('.start') // -> two or more nodes
.each(function(i, node){
// Bind variables in function scope
var moveable, drawable, editable, removable;
$(node).click(function(){
// If you click twice you will get 'undefined' and 1 respectively.
console.log(moveable);
moveable = 1;
// Do all other useful stuff
});
It is the only answer to your question. But it is not the best or event approperiate solution (you can use jQuery's data
method to save state of each node). Let me explain. String
and Array
are globals, so global variables aren't bad. It's bad practice to use them to save the states.
Upvotes: 1