171 lines
6.4 KiB
JavaScript
171 lines
6.4 KiB
JavaScript
// button, button, who's got the button?
|
|
// by Case Duckworth <acdw@acdw.net>
|
|
// vim:fdm=marker
|
|
// from stackoverflow
|
|
const Color = (function () { // {{{
|
|
function toHex(num, padding) { return num.toString(16).padStart(padding || 2); }
|
|
function parsePart(value) {
|
|
var perc = value.lastIndexOf('%');
|
|
return perc < 0 ? value : value.substr(0, perc);
|
|
}
|
|
function Color(data) {
|
|
if (arguments.length > 1) {
|
|
this[0] = arguments[0];
|
|
this[1] = arguments[1];
|
|
this[2] = arguments[2];
|
|
if (arguments.length > 3) { this[3] = arguments[3]; }
|
|
} else if (data instanceof Color || Array.isArray(data)) {
|
|
this[0] = data[0];
|
|
this[1] = data[1];
|
|
this[2] = data[2];
|
|
this[3] = data[3];
|
|
} else if (typeof data === 'string') {
|
|
data = data.trim();
|
|
if (data[0] === "#") {
|
|
switch (data.length) {
|
|
case 4:
|
|
this[0] = parseInt(data[1], 16); this[0] = (this[0] << 4) | this[0];
|
|
this[1] = parseInt(data[2], 16); this[1] = (this[1] << 4) | this[1];
|
|
this[2] = parseInt(data[3], 16); this[2] = (this[2] << 4) | this[2];
|
|
break;
|
|
case 9:
|
|
this[3] = parseInt(data.substr(7, 2), 16);
|
|
//Fall Through
|
|
case 7:
|
|
this[0] = parseInt(data.substr(1, 2), 16);
|
|
this[1] = parseInt(data.substr(3, 2), 16);
|
|
this[2] = parseInt(data.substr(5, 2), 16);
|
|
break;
|
|
}
|
|
} else if (data.startsWith("rgb")) {
|
|
var parts = data.substr(data[3] === "a" ? 5 : 4, data.length - (data[3] === "a" ? 6 : 5)).split(',');
|
|
this.r = parsePart(parts[0]);
|
|
this.g = parsePart(parts[1]);
|
|
this.b = parsePart(parts[2]);
|
|
if (parts.length > 3) { this.a = parsePart(parts[3]); }
|
|
}
|
|
}
|
|
}
|
|
Color.prototype = {
|
|
constructor: Color,
|
|
0: 255,
|
|
1: 255,
|
|
2: 255,
|
|
3: 255,
|
|
get r() { return this[0]; },
|
|
set r(value) { this[0] = value == null ? 0 : Math.max(Math.min(parseInt(value), 255), 0); },
|
|
get g() { return this[1]; },
|
|
set g(value) { this[1] = value == null ? 0 : Math.max(Math.min(parseInt(value), 255), 0); },
|
|
get b() { return this[2]; },
|
|
set b(value) { this[2] = value == null ? 0 : Math.max(Math.min(parseInt(value), 255), 0); },
|
|
get a() { return this[3] / 255; },
|
|
set a(value) { this[3] = value == null ? 255 : Math.max(Math.min(value > 1 ? value : parseFloat(value) * 255, 255), 0); },
|
|
get luma() { return .299 * this.r + .587 * this.g + .114 * this.b; },
|
|
get inverted() { return new Color(255 - this[0], 255 - this[1], 255 - this[2], this[3]); },
|
|
toString: function (option) {
|
|
if (option === 16) {
|
|
return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b) + (this[3] === 255 ? '' : toHex(this[3]));
|
|
} else if (option === '%') {
|
|
if (this.a !== 1) {
|
|
return `rgba(${this.r / 255 * 100}%, ${this.g / 255 * 100}%, ${this.b / 255 * 100}%, ${this.a / 255})`;
|
|
} else {
|
|
return `rgb(${this.r / 255 * 100}%, ${this.g / 255 * 100}%, ${this.b / 255 * 100})%`;
|
|
}
|
|
} else {
|
|
if (this.a !== 1) {
|
|
return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`;
|
|
} else {
|
|
return `rgb(${this.r}, ${this.g}, ${this.b})`;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
return Color;
|
|
}()); // }}}
|
|
|
|
const btn = document.getElementById("button");
|
|
const text = document.getElementById("text");
|
|
const counter = document.getElementById("counter");
|
|
var clicks = 0;
|
|
var moused;
|
|
|
|
function random(n) {
|
|
return Math.floor(Math.random() * (n+1));
|
|
}
|
|
function randomColor() {
|
|
// lifted straight from MDN, #noshame
|
|
return 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
|
|
}
|
|
function randomGradient() {
|
|
return 'linear-gradient('+random(360)+'deg, '+randomColor()+', '+randomColor()+')';
|
|
}
|
|
|
|
function adjustColor(el) {
|
|
var style = window.getComputedStyle(el);
|
|
var background = new Color(style['background-color']);
|
|
var text = new Color(style['color']);
|
|
if (Math.abs(background.luma - text.luma) < 100) {
|
|
el.style.color = text.inverted.toString();
|
|
}
|
|
}
|
|
|
|
function adjustShadow(el, clr) {
|
|
var size = Math.floor(Math.max(el.offsetHeight,el.offsetWidth)/10);
|
|
if (clr === undefined) {
|
|
var style = window.getComputedStyle(el);
|
|
var bg = new Color(style['background-color']);
|
|
var clr = new Color(bg.r - 50, bg.g - 50, bg.b - 50, (255*0.6));
|
|
}
|
|
var xsign = Math.random() > 0.5 ? '' : '-';
|
|
var ysign = Math.random() > 0.5 ? '' : '-';
|
|
el.style.boxShadow = xsign + size + "px " + ysign + size + "px " + clr;
|
|
}
|
|
|
|
function adjustBorder(el) {
|
|
var style = window.getComputedStyle(el);
|
|
var background = new Color(style['background-color']);
|
|
var border = new Color(background.r + 40, background.g + 40, background.b + 40);
|
|
el.style.borderColor = border.toString();
|
|
}
|
|
|
|
function reposition(el, center) {
|
|
let winH = window.innerHeight;
|
|
let winW = window.innerWidth;
|
|
let elH = el.offsetHeight;
|
|
let elW = el.offsetWidth;
|
|
if (center) {
|
|
el.style.top = ((winH / 2) - (elH / 2)) + "px";
|
|
el.style.left = ((winW / 2) - (elW / 2)) + "px";
|
|
} else {
|
|
el.style.top = random(winH - elH) + "px";
|
|
el.style.left = random(winW - elW) + "px";
|
|
}
|
|
}
|
|
|
|
btn.addEventListener('mouseenter', ev => {
|
|
moused = window.setTimeout(reposition, random(9000), btn, false);
|
|
});
|
|
btn.addEventListener('click', ev => {
|
|
moused = window.setTimeout(reposition, random(1000), btn, false);
|
|
});
|
|
|
|
btn.addEventListener("click", ev => {
|
|
clicks++;
|
|
counter.innerHTML = clicks;
|
|
reposition(text);
|
|
});
|
|
|
|
btn.addEventListener('click', ev => {
|
|
document.body.style.backgroundImage = randomGradient();
|
|
btnColor = randomColor();
|
|
btn.style.backgroundColor = btnColor;
|
|
adjustColor(btn);
|
|
adjustBorder(btn);
|
|
btn.style.borderRadius = '2%';
|
|
btn.style.padding = random(Math.min(window.innerHeight,window.innerWidth)/5)+"px";
|
|
adjustShadow(btn);
|
|
});
|
|
|
|
window.onload = function() {reposition(btn, true);};
|