Skip to content

Instantly share code, notes, and snippets.

@findzen
Forked from anonymous/index.html
Last active December 20, 2015 00:31
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 findzen/dbe189d571e212a6598b to your computer and use it in GitHub Desktop.
Save findzen/dbe189d571e212a6598b to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div>
<button
is="hitbox-button"
></button>
</div>
<div>
<button
is="hitbox-button"
padding="100"
></button>
</div>
</body>
</html>
body {
padding: 50px;
}
button {
border: 0;
background: red;
height: 100px;
width: 100px;
}
div {
border: 2px dotted blue;
display: inline-block;
margin: 50px;
padding: 50px;
}
div:nth-child(2) {
padding: 100px;
}
.in-bounds {
background: green;
}
;(function(window, document, undefined) {
'use strict';
var HIT_CLASS = 'in-bounds';
var PADDING = 50;
var btns = document.getElementsByTagName('button');
addSpecialClick(btns[0], function() {
console.log('button 1 clicked');
});
addSpecialClick(btns[1], function() {
console.log('button 2 clicked');
});
var proto = Object.create(HTMLButtonElement.prototype);
proto.createdCallback = function() {
var self = this;
var rect = this.getBoundingClientRect();
var padding =
this.attributes.padding &&
this.attributes.padding.value ?
Number(this.attributes.padding.value) :
PADDING;
var bounds = {
left: rect.left - padding,
right: rect.right + padding,
top: rect.top - padding,
bottom: rect.bottom + padding
};
this.addEventListener('mousedown', onMouseDown);
function checkBounds(x, y) {
if (
isInBounds(bounds, x, y)
) {
self.classList.add(HIT_CLASS);
return;
}
self.classList.remove(HIT_CLASS);
}
//
// Event handlers
//
function onMouseDown(e) {
checkBounds(e.clientX, e.clientY);
document.body.addEventListener('mouseup', onMouseUp);
document.body.addEventListener('mousemove', onMouseMove);
}
function onMouseMove(e) {
checkBounds(e.clientX, e.clientY);
}
function onMouseUp(e) {
document.body.removeEventListener('mouseup', onMouseUp);
document.body.removeEventListener('mousemove', onMouseMove);
self.classList.remove(HIT_CLASS);
// Don't dispatch event if out of bounds
if (!isInBounds(bounds, e.clientX, e.clientY)) {
return;
}
self.dispatchEvent(new Event('hitbox-click', {
view: window,
bubbles: true,
cancelable: true,
clientX: e.clientX,
clientY: e.clientY
}));
}
};
// Register element extending button
document.registerElement('hitbox-button', {
prototype: proto,
extends: 'button'
});
function addSpecialClick(el, callback) {
el.addEventListener('hitbox-click', callback);
}
// Returns true if x and y are within bounds
function isInBounds(bounds, x, y) {
return x >= bounds.left &&
x <= bounds.right &&
y >= bounds.top &&
y <= bounds.bottom;
}
})(window, document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment