Skip to content

Instantly share code, notes, and snippets.

@spalladino
Created April 1, 2016 17:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spalladino/c0c52c5783d4173f24a21e69a1de8c1b to your computer and use it in GitHub Desktop.
Save spalladino/c0c52c5783d4173f24a21e69a1de8c1b to your computer and use it in GitHub Desktop.
Random placement of rectangles in a canvas based on minmax distance
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);
<!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