Created
April 1, 2016 17:49
-
-
Save spalladino/c0c52c5783d4173f24a21e69a1de8c1b to your computer and use it in GitHub Desktop.
Random placement of rectangles in a canvas based on minmax distance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
HEIGHT = 800; | |
WIDTH = 1200; | |
CANDIDATES = 5; | |
INTERVAL = 1000; | |
var logos = []; | |
var tryPositionLogo = function(width, height) { | |
var candidate = null; | |
var candidateValue = null; | |
for (var i = 0; i < CANDIDATES; i++) { | |
var x = Math.random() * WIDTH; | |
var y = Math.random() * HEIGHT; | |
var maxMinDistance = null; | |
var validPositioning = true; | |
// Calculate max min distance | |
for (var j = 0; j < logos.length; j++) { | |
var logo = logos[j]; | |
var distX = (x >= logo.x) ? (x - (logo.x + logo.width)) : (logo.x - (x + width)); | |
var distY = (y >= logo.y) ? (y - (logo.y + logo.height)) : (logo.y - (y + height)); | |
// If both distances are negative, there was an overlap | |
if (distX < 0 && distY < 0) { | |
validPositioning = false; | |
break; | |
} | |
// Estimate distance | |
var dist = Math.sqrt((distX < 0 ? 0 : distX * distX) + (distY < 0 ? 0 : distY * distY)); | |
// Update max-min value | |
maxMinDistance = (maxMinDistance == null) ? dist : Math.min(dist, maxMinDistance); | |
} | |
// Update candidate if we found a better one | |
if (validPositioning && (maxMinDistance == null || maxMinDistance >= candidateValue)) { | |
candidate = {x: x, y: y}; | |
candidateValue = maxMinDistance; | |
} | |
} | |
// We found a candidate, place it | |
if (candidate) { | |
var newLogo = {x: candidate.x, y: candidate.y, height: height, width: width}; | |
newLogo.node = buildLogo(newLogo); | |
newLogo.node.appendTo('#canvas'); | |
newLogo.node.fadeIn(); | |
logos.push(newLogo); | |
return true; | |
} | |
return false; | |
}; | |
// Build the HTML node for the logo given its x, y, witdth y height | |
var buildLogo = function(spec) { | |
var logo = $('<div class="logo"></div>'); | |
logo.css('height', spec.height); | |
logo.css('width', spec.width); | |
logo.css('top', spec.y); | |
logo.css('left', spec.x); | |
return logo; | |
}; | |
// Main | |
window.setInterval(function() { | |
// Replace with actual coordinates for logo | |
var width = Math.random() * 100 + 50; | |
var height = Math.random() * 100 + 50; | |
// Try 100 times to place it | |
var attempts = 100; | |
while (--attempts > 0 && !tryPositionLogo(width, height)); | |
if (logos.length > 4) { | |
$(logos[0].node).fadeOut(400, function() { $(this).remove(); }); | |
logos.splice(0, 1); | |
} | |
}, INTERVAL); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<script src="app.js"></script> | |
<script src="https://code.jquery.com/jquery-2.2.2.min.js" integrity="sha256-36cp2Co+/62rEAAYHLmRCPIych47CvdM+uTBJwSzWjI=" crossorigin="anonymous"></script> | |
<style> | |
#canvas { | |
height: 800px; | |
width: 1200px; | |
margin: 40px; | |
border: 1px black solid; | |
position: relative; | |
} | |
.logo { | |
border: 1px gray solid; | |
background-color: #222222; | |
position: absolute; | |
opacity: 1; | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="canvas"></div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment