Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save aresnick/f08279e380a06020c9b3 to your computer and use it in GitHub Desktop.
Save aresnick/f08279e380a06020c9b3 to your computer and use it in GitHub Desktop.
Some simple examples of re-ordering interactions with HTML, CSS, and JS
<html>
<head>
<style>
.container {
/* Style the containers */
width: 250px;
height: 250px;
border-radius: calc(250px/2);
position: absolute;
top: 50%;
}
/* Position and color our individual containers */
#one {
left: calc(0*(100% - 250px)/2);
background-color: lightblue;
}
#two {
left: calc(1*(100% - 250px)/2);
background-color: lightgreen;
}
#three {
left: calc(2*(100% - 250px)/2);
background-color: orange;
}
.bubble {
/* Style the bubble we can drag around */
position: absolute;
width: 50px;
height: 50px;
border-radius: calc(50px/2);
background-color: lightgrey;
left: calc(50% - 50px/2);
top: calc(25% - 50px/2);
}
p {
position: fixed;
bottom: 0;
}
</style>
</head>
<body>
<p>
Drag the small bubble into one of the big bubbles (or try dragging it elsewhere and compare).
</p>
<div class='container' id='one'></div>
<div class='container' id='two'></div>
<div class='container' id='three'></div>
<script>
// Grab all the container divs
var divs = Array.prototype.slice.call(document.querySelectorAll('.container'));
divs.forEach(function(div) { // for each one
// Prevent the default behavior when you start dragging
var blockDragenter = function(event) {
event.stopPropagation();
event.preventDefault();
};
// Prevent the default behavior when you are dragging over
var blockDragover = function(event) {
event.stopPropagation();
event.preventDefault();
};
// But if someone drops something on me
var receiveDrop = function(event) {
// Grab the ID from the dataTransfer
var draggedId = event.dataTransfer.getData("text/plain");
div.appendChild(document.querySelector('#' + draggedId));
// And put it inside me
event.preventDefault(); // but still prevent the default behavior
};
// Actually attach our event listeners
div.addEventListener('dragenter', blockDragenter, false);
div.addEventListener('dragover', blockDragover, false);
div.addEventListener('drop', receiveDrop, false);
});
var Bubble = function() {
var bubble = this;
// Synthesize our HTML
this.html = document.createElement('div');
this.html.classList.add('bubble');
// Set a random background color to distinguish Blocks
var randomRGBA = [0, 0, 0].map(function(n) {
return Math.floor(Math.random() * 255);
}).concat([1]);
this.html.style.backgroundColor = 'rgba(' + randomRGBA.join(',') + ')';
// We want to create a unique ID for each bubble, to do this, we'll grab the current time in milliseconds and convert that to a string of letters
// Get the time, in milliseconds, as an array of numbers
var now = Array.prototype.slice.call(String(Date.now()));
now = now.map(function(n) {
// Replace that array with an array of letters using ASCII codes, see http://www.ascii-code.com/ for more
return String.fromCharCode(parseInt(n) + 65);
});
this.html.id = now.join(''); // set my id
this.html.setAttribute('draggable', 'true'); // tell the browser we're draggable
this.html.addEventListener('dragstart', function(event) {
// and when you start dragging me, set the dataTransfer for the dragEvent to my ID
event.dataTransfer.setData('text/plain', bubble.html.id);
});
// Add me to the DOM
document.body.appendChild(this.html);
};
var b = new Bubble(); // Make a new bubble
</script>
</body>
</html>
<html>
<head>
<style>
body {
/* Reset the body's default margin */
margin: 0;
}
.bubble {
/* Style our bubbles */
width: 200px;
height: 200px;
border-radius: calc(200px/2);
position: absolute;
}
p {
position: fixed;
bottom: 0;
}
</style>
</head>
<body>
<p>
Drag the bubbles and re-order them.
</p>
<script>
var bubbles = []; // A global array for easy access to our bubbles
var Bubble = function() { // Define a bubble class
var bubble = this;
// Synthesize our HTML
this.html = document.createElement('div');
this.html.classList.add('bubble');
// Give it a random background color
var randomRGBA = [0, 0, 0].map(function(n) {
return Math.floor(Math.random() * 255);
}).concat([1]);
this.html.style.backgroundColor = 'rgba(' + randomRGBA.join(',') + ')';
// Put it in our bubbles array
bubbles.push(this);
// Add it to the DOM
document.body.appendChild(this.html);
// And position it appropriately
this.reorient();
};
Object.defineProperty(Bubble.prototype, 'number', {
// A custom getter to get where in the bubbles array it is
get: function() {
return bubbles.indexOf(this);
}
});
Bubble.prototype.reorient = function() {
// Restyle where we are depending on where we are in the bubbles array
this.html.style.top = 0;
this.html.style.left = this.number * parseInt(this.html.offsetWidth) + 'px';
};
window.addEventListener('load', function(event) {
for (var i = 0; i < 5; i++) {
new Bubble();
} // Make 10 bubbles
var mouse = { // Initialize a dictionary to store mouse info
x: null,
y: null,
down: false,
move: false,
draggedElement: null
};
document.addEventListener('mousemove', function(event) {
// Update our mouse position whenever the mouse moves
mouse.x = event.pageX;
mouse.y = event.pageY;
});
document.addEventListener('mousedown', function(event) {
// When we press down, register this in our mouse info dictionary
mouse.down = true;
mouse.draggedElement = event.toElement; // grab the clicked element
mouse.draggedElement.style.zIndex = bubbles.length + 1; // and move it to the top
});
document.addEventListener('mouseup', function(event) {
// When we let go of the click
mouse.up = true; // register this
bubbles.sort(function(b1, b2) {
return b1.html.offsetLeft - b2.html.offsetLeft;
}); // sort our bubbles array by whose left edge comes first
bubbles.forEach(function(bubble) {
bubble.reorient(); // and redisplay the DOM to mirror our bubbles array's sorting
});
mouse.draggedElement.style.zIndex = 0; // put the dragged element back on the bottom
mouse.draggedElement = null; // and then clear the dragged element placeholder
});
document.addEventListener('mousemove', function(event) {
// When the mouse moves
if (mouse.draggedElement) { // Check if we're dragging something
var width = mouse.draggedElement.offsetWidth; // grab its width
var height = mouse.draggedElement.offsetHeight; // and height
// and put the dragged element's center where our mouse is
mouse.draggedElement.style.left = mouse.x - width / 2;
mouse.draggedElement.style.top = mouse.y - height / 2;
}
});
});
</script>
</body>
</html>
<html>
<head>
<style>
.container {
/* Style and position our container */
width: 250px;
height: 250px;
border-radius: calc(250px/2);
background-color: orange;
position: absolute;
top: 50%;
}
.bubble {
/* Style and position our bubbles */
position: absolute;
width: 50px;
height: 50px;
border-radius: calc(50px/2);
background-color: lightgrey;
left: calc(50% - 50px/2);
top: calc(25% - 50px/2);
}
p {
position: fixed;
bottom: 0;
}
</style>
</head>
<body>
<p>
Click the small bubble put it back in the big one.
</p>
<div class='container'></div>
<script>
var Bubble = function() {
var bubble = this;
// Synthesize our HTML
this.html = document.createElement('div');
this.html.addEventListener('click', function(event) {
// When we're clicked
// grab the .container and add my HTML to it
document.querySelector('.container').appendChild(bubble.html);
});
this.html.classList.add('bubble');
// Set a random background color
var randomRGBA = [0, 0, 0].map(function(n) {
return Math.floor(Math.random() * 255);
}).concat([1]);
this.html.style.backgroundColor = 'rgba(' + randomRGBA.join(',') + ')';
document.body.appendChild(this.html); // add me to the DOM
};
var b = new Bubble(); // Make a Bubble
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment