Commit 1110551c authored by David DeSandro's avatar David DeSandro
Browse files

🔧 refactor Packer.mergeRects

use while loops to check rect and compareRect
should be less iterations

add merge-rects demo
parent df33a5b5
Showing with 101 additions and 22 deletions
+101 -22
......@@ -128,30 +128,32 @@ Packer.prototype.addSpace = function( rect ) {
* @returns {Array} rects: an array of Rects
**/
Packer.mergeRects = function( rects ) {
for ( var i=0, len = rects.length; i < len; i++ ) {
var rect = rects[i];
// skip over this rect if it was already removed
if ( !rect ) {
continue;
}
// clone rects we're testing, remove this rect
var compareRects = rects.slice(0);
// do not compare with self
compareRects.splice( i, 1 );
// compare this rect with others
var removedCount = 0;
for ( var j=0, jLen = compareRects.length; j < jLen; j++ ) {
var compareRect = compareRects[j];
// if this rect contains another,
// remove that rect from test collection
var indexAdjust = i > j ? 0 : 1;
if ( rect.contains( compareRect ) ) {
// console.log( 'current test rects:' + testRects.length, testRects );
// console.log( i, j, indexAdjust, rect, compareRect );
rects.splice( j + indexAdjust - removedCount, 1 );
removedCount++;
var i = 0;
var rect = rects[i];
rectLoop:
while ( rect ) {
var j = 0;
var compareRect = rects[ i + j ];
while ( compareRect ) {
if ( compareRect == rect ) {
j++; // next
} else if ( compareRect.contains( rect ) ) {
// remove rect
rects.splice( i, 1 );
rect = rects[i]; // set next rect
continue rectLoop; // bail on compareLoop
} else if ( rect.contains( compareRect ) ) {
// remove compareRect
rects.splice( i + j, 1 );
} else {
j++;
}
compareRect = rects[ i + j ]; // set next compareRect
}
i++;
rect = rects[i];
}
return rects;
......
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>merge rects</title>
</head>
<body>
<h1>merge rects</h1>
<p>
<button class="make-rects-button" onclick="makeRects();">make rects</button>
<button class="merge-rects-button" onclick="mergeRects();">merge rects</button>
</p>
<canvas width="400" height="400"></canvas>
<script src="../js/rect.js"></script>
<script src="../js/packer.js"></script>
<script>
function makeRect() {
var size = Math.floor( Math.random() * 12 ) + 1;
// var height = Math.floor( Math.random() * 9 ) + 1;
var x = Math.floor( Math.random() * ( 20 - size ) );
var y = Math.floor( Math.random() * ( 20 - size ) );
return new Packery.Rect({
x: x * 20,
y: y * 20,
width: size * 20,
height: size * 20,
hue: Math.floor( Math.random() * 6 ) * 360 / 6
});
}
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var rects;
function makeRects() {
rects = [];
for ( var i=0; i < 10; i++ ) {
rects.push( makeRect() );
}
render();
}
function renderRect( rect) {
var x = rect.x + 0.5;
var y = rect.y + 0.5;
ctx.lineWidth = 3;
ctx.strokeStyle = 'hsla(' + rect.hue + ', 100%, 40%, 0.8)';
ctx.strokeRect( x, y, rect.width, rect.height );
ctx.fillStyle = 'hsla(' + rect.hue + ', 100%, 50%, 0.2)';
ctx.fillRect( x, y, rect.width, rect.height );
}
function render() {
ctx.clearRect( 0, 0, 400, 400 );
rects.forEach( renderRect );
}
makeRects();
function mergeRects() {
rects = Packery.Packer.mergeRects( rects );
render();
}
</script>
</body>
</html>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment