Skip to content

Instantly share code, notes, and snippets.

Created December 18, 2015 22:25
Show Gist options
  • Save anonymous/fb5fbc580db4a35cfecb to your computer and use it in GitHub Desktop.
Save anonymous/fb5fbc580db4a35cfecb to your computer and use it in GitHub Desktop.
JS Bin [add your bin description] // source http://jsbin.com/zocuwed
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="[add your bin description]">
<meta charset="utf-8">
<title>JS Bin</title>
<style id="jsbin-css">
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;
}
</style>
</head>
<body>
<div>
<button
is="hitbox-button"
></button>
</div>
<div>
<button
is="hitbox-button"
padding="100"
></button>
</div>
<script id="jsbin-javascript">
;(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);
this.addEventListener('click', function(e) {
e.stopImmediatePropagation();
return false;
});
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);
</script>
<script id="jsbin-source-css" type="text/css">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;
}</script>
<script id="jsbin-source-javascript" type="text/javascript">;(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);
this.addEventListener('click', function(e) {
e.stopImmediatePropagation();
return false;
});
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);
</script></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);
this.addEventListener('click', function(e) {
e.stopImmediatePropagation();
return false;
});
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