monicao
6/6/2012 - 7:18 PM

## Zach's super awesome rectangle drawing algo

Zach's super awesome rectangle drawing algo

``````\$(document).ready(function(){
window.drawing = false;
\$("#wrapper").mousedown(function(e){
x = e.pageX; // not supported in IE7, IE8  (clientX, clientY)
y = e.pageY;
window.originalX = x;
window.originalY = y;
window.drawing = true;
window.active_rect = \$("<div class='rect'></div>");
window.active_rect.css({
position: "absolute",
left: x,
top: y,
border: "1px solid red",
width: 1,
height: 1
});
\$("#wrapper").append(window.active_rect);
return false; // prevent drag
});

\$("#wrapper").mousemove(function(e){
if(window.drawing && typeof(window.active_rect) != "undefined" && window.active_rect) {
var css = window.rectangleCSS({x: window.originalX, y: window.originalY}, {x: e.pageX, y: e.pageY});
window.active_rect.css(css);
}
});

\$("#wrapper").mouseup(function(e){
window.drawing = false;
delete window.active_rect;
});

// K   L
// M   N
// point A and point B are two opposing points (Ax != Bx and Ay != By)
// Returns: the css coordinates for an absolutely positioned div representing
//          the rectangle described by pointA and pointB
window.rectangleCSS = function(pointA, pointB) {
//console.log("rectangleCSS " + pointA.x + ", " + pointA.y + " " + pointB.x + ", " + pointB.y);
var K, L, M, N;
// Figure out if we're dealing with a K, N pair or a L, M pair
if(pointA.x > pointB.x) {  // A is either L or N
if(pointA.y > pointB.y) {
//console.log("NK");
N = pointA; K = pointB;
} else {
//console.log("LM");
L = pointA; M = pointB;
}
} else { // A is either K or M
if(pointA.y > pointB.y) {
//console.log("ML");
M = pointA; L = pointB;
} else {
//console.log("KN");
K = pointA, N = pointB;
}
}

// Calculate the rectangle CSS values
if(K && N) {
console.log("KN");
return {left: K.x, top: K.y, width: (N.x - K.x), height: (N.y - K.y)};
} else { // we know L, M
console.log("LM");
return {left: M.x, top: L.y, width: (L.x - M.x), height: (M.y - L.y)};
}

}

// TESTS

window.runTests = function() {
console.log("Starting tests.");
var result;

console.log("Testing {x: 1, y: 1}, {x: 20, y: 20}");
result = window.rectangleCSS({x: 1, y: 1}, {x: 20, y: 20});
equals(result.x,      1);
equals(result.y,      1);
equals(result.width,  19);
equals(result.height, 19);

console.log("Testing {x: 20, y: 20}, {x: 1, y: 1}");
result = window.rectangleCSS({x: 20, y: 20}, {x: 1, y: 1});
equals(result.x,      1);
equals(result.y,      1);
equals(result.width,  19);
equals(result.height, 19);

console.log("Testing {x: 1, y: 20}, {x: 20, y: 1}");
result = window.rectangleCSS({x: 1, y: 20}, {x: 20, y: 1});
equals(result.x,      1);
equals(result.y,      1);
equals(result.width,  19);
equals(result.height, 19);

console.log("Testing {x: 20, y: 1}, {x: 1, y: 20}");
result = window.rectangleCSS({x: 20, y: 1}, {x: 1, y: 20});
equals(result.x,      1);
equals(result.y,      1);
equals(result.width,  19);
equals(result.height, 19);

}

window.equals = function(a, b) {
if(a === b) {
console.log("Passed");
} else {
console.log("Failed. Expected a: " + a + " to be equal to b: " + b);
}
}
});

``````
``````<html>
<title>Drawing</title>
<script type="text/javascript" src="drawing.js"></script>

<style type="text/css">
#wrapper {
width: 100%;
height: 100%;
border: 1px solid black;
}
</style>