Skip to content

Instantly share code, notes, and snippets.

@JLChnToZ
Last active February 23, 2017 07:48
Show Gist options
  • Select an option

  • Save JLChnToZ/758c8dc7f66beec32a6cefb2ec52be95 to your computer and use it in GitHub Desktop.

Select an option

Save JLChnToZ/758c8dc7f66beec32a6cefb2ec52be95 to your computer and use it in GitHub Desktop.
Click anywhere on the webpage to gacha :)
// Click-to-Gacha easter egg module for web pages
// (C) Jeremy Lam 2017.
// Require RandomJs and FingerPrintJs2 module in order to work
// You can change the behaviour in 'setTitle' and 'notify' function.
(function (root, factory) {
if(typeof define === 'function' && define.amd)
define(['random', 'fingerprintjs2'], factory);
else if(typeof module === 'object' && module.exports)
factory(require('random-js'), require('fingerprintjs2'));
else
factory(root.Random, root.Fingerprint2);
}(this, function(Random, Fingerprint2) {
'use strict';
var maxInt = Number.MAX_SAFE_INTEGER;
var body = document.body;
var ls = (function(localStorage) {
var test = '__ls_testing__';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return localStorage;
} catch(e) {
console.warn('Detected your browser does not support localStorage.\nGacha results will not be saved.');
return null;
}
})(window.localStorage);
var log10 = Math.log10 || function(v) {
return Math.log(v) * Math.LOG10E;
};
// Called when clicked somewhere to gacha
function setTitle(text) {
document.title = text;
}
// Called when get something special in gacha
function notify(text) {
alert('Congrats! You got a ' + text + ' card!');
}
function mdbLookup(x, y) {
if(!(x >= 0 && y >= 0))
return 0;
x = ~~x;
y = ~~y;
var r = 0;
for(var m = 1, o = 0; (x >= m || y >= m) && m < maxInt; m <<= 1)
r |= (x & m) << o++ | (y & m) << o;
return r;
}
function mdbMaxValue(x, y) {
x = Math.min(x, y) + 1;
x |= x >> 0x01;
x |= x >> 0x02;
x |= x >> 0x04;
x |= x >> 0x08;
x |= x >> 0x10;
return (x + 1) >> 1;
}
function getDiffPerUnit(w, h) {
var s = mdbMaxValue(w, h);
return 1 / mdbLookup(s - 1, s - 1);
}
function getMdbValue(x, y, w, h) {
var s = mdbMaxValue(w, h);
return mdbLookup(x / w * s, y / h * s) / mdbLookup(s - 1, s - 1);
}
var hs, isHsReady = false, lastTimeHash, rndEngine, rnd, refValue;
var cards = ls && ls.getItem('rare');
cards = cards ? JSON.parse(cards) : [
{ text: '-', count: 0, chance: 0 },
{ text: 'N', count: 0 },
{ text: 'R', count: 0 },
{ text: 'SR', count: 0 },
{ text: 'SSR', count: 0 },
{ text: 'UR', count: 0 },
{ text: 'LR', count: 0 },
{ text: 'HR', count: 0 }
];
new Fingerprint2().get(function(result) {
hs = Number.parseInt(result.substr(0, 12), 16);
isHsReady = true;
});
function getTimeHash() {
return Math.floor(Date.now() / 86400000);
}
function seed() {
if(!rndEngine) rndEngine = Random.engines.mt19937();
rndEngine.seedWithArray([hs, lastTimeHash = getTimeHash(), cards[0].chance || 0]);
if(!rnd) rnd = new Random(rndEngine);
refValue = rnd.real(0, 1);
}
body.addEventListener('click', function(e) {
if(!isHsReady) return;
if(getTimeHash() !== lastTimeHash) seed();
var w = body.clientWidth, h = body.clientHeight;
var deltaRange = getDiffPerUnit(w, h) / 2;
var rare = Math.max(
Math.min(
-Math.floor(
log10(
Math.abs(
getMdbValue(e.pageX, e.pageY, w, h)
+ rnd.real(-deltaRange, deltaRange)
- refValue
)
)
), cards.length - 1
), 0
);
cards[rare].count++;
if(rare > 2) {
notify(cards[rare].text);
cards[0].chance = rnd.integer(0, maxInt);
seed();
}
var disp = '';
for(var i = cards.length - 1; i > 0; i--) {
if(cards[i].count < 1) continue;
if(disp.length) disp += ', ';
disp += cards[i].text + 'x' + cards[i].count;
}
setTitle(disp);
if(ls) ls.setItem('rare', JSON.stringify(cards));
});
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment