From a95222a00e64935cc608332d214df8451354517d Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Sun, 31 Jul 2016 00:58:53 -0700 Subject: [PATCH] Restore two commands. --- public/js/app.js | 4 +- public/js/kh.js | 833 +++++++++++++++++++++++++++++++++++++++ public/js/libdoge.min.js | 1 + 3 files changed, 836 insertions(+), 2 deletions(-) create mode 100644 public/js/kh.js create mode 100644 public/js/libdoge.min.js diff --git a/public/js/app.js b/public/js/app.js index 576933d4..871adce3 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -795,7 +795,7 @@ $(window).load(function() { }); OutgoingChatHandler.addListener('katamari', function(msg) { - var i, s, ss = ['http://kathack.com/js/kh.js', 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js']; + var i, s, ss = ['/js/kh.js']; for (i = 0; i != ss.length; i++) { s = document.createElement('script'); s.src = ss[i]; @@ -806,7 +806,7 @@ $(window).load(function() { OutgoingChatHandler.addListener('doge', function(msg) { var e = document.createElement('script'); - e.src = 'https://raw.github.com/martindale/libdoge/master/libdoge/libdoge.min.js'; + e.src = '/js/libdoge.min.js'; document.body.appendChild(e); }); diff --git a/public/js/kh.js b/public/js/kh.js new file mode 100644 index 00000000..da191281 --- /dev/null +++ b/public/js/kh.js @@ -0,0 +1,833 @@ +/* +Copyright Alex Leone, David Nufer, David Truong, 2011-03-11. kathack.com + +javascript:var i,s,ss=['http://kathack.com/js/kh.js','http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js'];for(i=0;i!=ss.length;i++){s=document.createElement('script');s.src=ss[i];document.body.appendChild(s);}void(0); + +*/ +var BORDER_STYLE = "1px solid #bbb", + CSS_TRANSFORM = null, + CSS_TRANSFORM_ORIGIN = null, + POSSIBLE_TRANSFORM_PREFIXES = ['-webkit-', '-moz-', '-o-', '-ms-', ''], + khFirst = false; + +/* When running twice on one page, update pick-uppable nodes instead of + * creating more. + */ +if (!window.khNodes) { + khFirst = true; + window.khNodes = new StickyNodes(); +} + +function getCssTransform() { + var i, d = document.createElement('div'), pre; + for (i = 0; i < POSSIBLE_TRANSFORM_PREFIXES.length; i++) { + pre = POSSIBLE_TRANSFORM_PREFIXES[i]; + d.style.setProperty(pre + 'transform', 'rotate(1rad) scaleX(2)', null); + if (d.style.getPropertyValue(pre + 'transform')) { + CSS_TRANSFORM = pre + 'transform'; + CSS_TRANSFORM_ORIGIN = pre + 'transform-origin'; + return; + } + } + alert("Your browser doesn't support CSS tranforms!"); + throw "Your browser doesn't support CSS tranforms!"; +} +getCssTransform(); + +/** + * Returns true if the circle intersects the element rectangle. + * 0 | 1 | 2 + * ------------------ + * 3 | 4 | 5 + * ------------------ + * 6 | 7 | 9 + */ +function circleGridObjInt(cx, cy, cr, cr2, go) { + var dx, dy; + if (cx < go.left) { + dx = go.left - cx; + if (cy < go.top) { /* zone 0. */ + dy = go.top - cy; + return ((dx * dx + dy * dy) <= cr2); + } else if (cy <= go.bottom) { /* zone 3. */ + return (dx <= cr); + } else { /* zone 6. */ + dy = cy - go.bottom; + return ((dx * dx + dy * dy) <= cr2); + } + } else if (cx <= go.right) { + if (cy < go.top) { /* zone 1. */ + return ((go.top - cy) <= cr); + } else if (cy <= go.bottom) { /* zone 4. */ + return true; + } else { /* zone 7. */ + return ((cy - go.bottom) <= cr); + } + } else { + dx = cx - go.right; + if (cy < go.top) { /* zone 2. */ + dy = go.top - cy; + return ((dx * dx + dy * dy) <= cr2); + } else if (cy <= go.bottom) { /* zone 5. */ + return (dx <= cr); + } else { /* zone 9. */ + dy = cy - go.bottom; + return ((dx * dx + dy * dy) <= cr2); + } + } +} + +/** + * Returns [x,y] where the rectangle is closest to (cx, cy). + * 0 | 1 | 2 + * ------------------ + * 3 | 4 | 5 + * ------------------ + * 6 | 7 | 9 + */ +function getClosestPoint(cx, cy, go) { + var dx, dy; + if (cx < go.left) { + dx = go.left - cx; + if (cy < go.top) { /* zone 0. */ + return [go.left, go.top]; + } else if (cy <= go.bottom) { /* zone 3. */ + return [go.left, cy]; + } else { /* zone 6. */ + return [go.left, go.bottom]; + } + } else if (cx <= go.right) { + if (cy < go.top) { /* zone 1. */ + return [cx, go.top]; + } else if (cy <= go.bottom) { /* zone 4. */ + return [cx, cy]; + } else { /* zone 7. */ + return [cx, go.bottom]; + } + } else { + dx = cx - go.right; + if (cy < go.top) { /* zone 2. */ + return [go.right, go.top]; + } else if (cy <= go.bottom) { /* zone 5. */ + return [go.right, cy]; + } else { /* zone 9. */ + return [go.right, go.bottom]; + } + } +} + +/** + * Returns the "volume" of the grid object. + */ +function gridObjVol(go) { + return go.w * go.h * Math.min(go.w, go.h); +} + +function StickyNodes() { + var domNodes = [], + grid = [], + GRIDX = 100, + GRIDY = 100, + REPLACE_WORDS_IN = { + a: 1, b: 1, big: 1, body: 1, cite:1, code: 1, dd: 1, div: 1, + dt: 1, em: 1, font: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, + i: 1, label: 1, legend: 1, li: 1, p: 1, pre: 1, small: 1, + span: 1, strong: 1, sub: 1, sup: 1, td: 1, th: 1, tt: 1 + }; + + function addDomNode(el) { + if (el !== undefined && el !== null) { + el.khIgnore = true; + el.style.border = BORDER_STYLE; + domNodes.push(el); + } + } + this.addDomNode = addDomNode; + + this.addWords = function (el) { + var textEls = []; + + function shouldAddChildren(el) { + return el.tagName && REPLACE_WORDS_IN[el.tagName.toLowerCase()]; + } + + function buildTextEls(el, shouldAdd) { + var i, len; + if (shouldAdd && el.nodeType === Node.TEXT_NODE && + el.nodeValue.trim().length > 0) { + textEls.push(el); + return; + } + if (!el.childNodes || el.khIgnore) { + return; + } + shouldAdd = shouldAddChildren(el); + for (i = 0, len = el.childNodes.length; i < len; i++) { + buildTextEls(el.childNodes[i], shouldAdd); + } + } + + function wordsToSpans(textEl) { + var p = textEl.parentNode, + words = textEl.nodeValue.split(/\s+/), + ws = textEl.nodeValue.split(/\S+/), + i, n, len = Math.max(words.length, ws.length); + /* preserve whitespace for pre tags. */ + if (ws.length > 0 && ws[0].length === 0) { + ws.shift(); + } + for (i = 0; i < len; i++) { + if (i < words.length && words[i].length > 0) { + n = document.createElement('span'); + n.innerHTML = words[i]; + p.insertBefore(n, textEl); + addDomNode(n); + } + if (i < ws.length && ws[i].length > 0) { + n = document.createTextNode(ws[i]); + p.insertBefore(n, textEl); + } + } + p.removeChild(textEl); + } + + buildTextEls(el, shouldAddChildren(el)); + textEls.map(wordsToSpans); + }; + + /* includes el. */ + this.addTagNames = function (el, tagNames) { + var tname = el.tagName && el.tagName.toLowerCase(), + i, j, els, len; + if (el.khIgnore) { + return; + } + if (tagNames.indexOf(tname) !== -1) { + addDomNode(el); + } + if (!el.getElementsByTagName) { + return; + } + for (i = 0; i < tagNames.length; i++) { + els = el.getElementsByTagName(tagNames[i]); + for (j = 0, len = els.length; j < len; j++) { + if (!els[j].khIgnore) { + addDomNode(els[j]); + } + } + } + }; + + this.finalize = function (docW, docH) { + var xi, yi, i, len, startXI, startYI, el, go, off, w, h, + endXI = Math.floor(docW / GRIDX) + 1, + endYI = Math.floor(docH / GRIDY) + 1; + /* initialize grid. */ + grid = new Array(endXI); + for (xi = 0; xi < endXI; xi++) { + grid[xi] = new Array(endYI); + } + /* add nodes into grid. */ + for (i = 0, len = domNodes.length; i < len; i++) { + el = domNodes[i]; + if (el.khPicked) { + continue; + } + off = jQuery(el).offset(); + w = jQuery(el).width(); + h = jQuery(el).height(); + go = { + el: domNodes[i], /* dom element. */ + left: off.left, + right: off.left + w, + top: off.top, + bottom: off.top + h, + w: w, + h: h, + x: off.left + (w / 2), /* center x. */ + y: off.top + (h / 2), /* center y. */ + diag: Math.sqrt(((w * w) + (h * h)) / 4), /* center to corner */ + + /* these are for removing ourselves from the grid. */ + arrs: [], /* which arrays we're in (grid[x][y]). */ + idxs: [] /* what indexes. */ + }; + startXI = Math.floor(go.left / GRIDX); + startYI = Math.floor(go.top / GRIDY); + endXI = Math.floor((go.left + go.w) / GRIDX) + 1; + endYI = Math.floor((go.top + go.h) / GRIDY) + 1; + for (xi = startXI; xi < endXI; xi++) { + for (yi = startYI; yi < endYI; yi++) { + if (grid[xi] === undefined) { + grid[xi] = []; + } + if (grid[xi][yi] === undefined) { + grid[xi][yi] = [go]; + } else { + grid[xi][yi].push(go); + } + go.arrs.push(grid[xi][yi]); + go.idxs.push(grid[xi][yi].length - 1); + } + } + } + }; + + function removeGridObj(go) { + var i; + for (i = 0; i < go.arrs.length; i++) { + go.arrs[i][go.idxs[i]] = undefined; + } + go.el.style.visibility = "hidden"; + go.el.khPicked = true; + delete go.arrs; + delete go.idxs; + } + + /** + * cb(gridObj) -> boolean true if the object should be removed. + */ + this.removeIntersecting = function (x, y, r, cb) { + var xi, yi, arr, i, r2 = r * r, go, + startXI = Math.floor((x - r) / GRIDX), + startYI = Math.floor((y - r) / GRIDY), + endXI = Math.floor((x + r) / GRIDX) + 1, + endYI = Math.floor((y + r) / GRIDY) + 1; + for (xi = startXI; xi < endXI; xi++) { + if (grid[xi] === undefined) { + continue; + } + for (yi = startYI; yi < endYI; yi++) { + arr = grid[xi][yi]; + if (arr === undefined) { + continue; + } + for (i = 0; i < arr.length; i++) { + go = arr[i]; + if (go !== undefined && + circleGridObjInt(x, y, r, r2, go) && + cb(go)) { + removeGridObj(go); + } + } + } + } + }; +} + +function PlayerBall(parentNode, stickyNodes, ballOpts, sounds) { + var x = 300, y = 300, + vx = 0, vy = 0, + radius = 20, + lastR = 0, /**< optimization: only resize when necessary. */ + docW = 10000, docH = 10000, + + attached = [], + attachedDiv, /* div to put attached nodes into. */ + canvas_el, + canvas_ctx, + color = ballOpts.color, + + accelTargetX = 0, accelTargetY = 0, + accel = false, + + VOL_MULT = ballOpts.VOL_MULT, + MAX_ATTACHED_VISIBLE = ballOpts.MAX_ATTACHED_VISIBLE, + CHECK_VOLS = ballOpts.CHECK_VOLS, + + /** + * which direction the ball is facing in the xy axis, in radians. + * th: 0 is facing dead East + * th: 1/2 PI is facing dead South + * note that this is like regular th on a graph with y inverted. + * Same rotation as css transform. + */ + th = 0, + + /** + * Ball angle in the rotation axis / z plane, in radians. + * phi: 0 is pointing in the direction the ball is rolling. + * phi: 1/2 PI is pointing straight up (out of the page). + * note that forward rotation means phi -= 0.1. + */ + phi = 0; + + this.init = function () { + canvas_el = document.createElement('canvas'); + canvas_el.width = radius * 2; + canvas_el.height = radius * 2; + canvas_el.style.cssText = 'position: absolute; z-index: 500;'; + parentNode.appendChild(canvas_el); + canvas_ctx = canvas_el.getContext('2d'); + + attachedDiv = document.createElement('div'); + parentNode.appendChild(attachedDiv); + }; + + this.setRadius = function (r) { + radius = r; + }; + + this.getState = function () { + return { + x: x, + y: y, + vx: vx, + vy: vy, + radius: radius, + th: th, + phi: phi, + }; + }; + + this.setState = function (s) { + x = s.x; + y = s.y; + vx = s.vx; + vy = s.vy; + radius = s.radius; + th = s.th; + phi = s.phi; + }; + + this.setXY = function (sx, sy) { + x = sx; + y = sy; + }; + + this.setTh = function (sth) { + th = sth; + }; + + this.setPhi = function (sphi) { + phi = sphi; + }; + + this.setColor = function (c) { + color = c; + }; + + this.setDocSize = function (w, h) { + docW = w; + docH = h; + }; + + this.setAccel = function (bool) { + accel = bool; + }; + + this.setAccelTarget = function (tx, ty) { + accelTargetX = tx; + accelTargetY = ty; + }; + + function getVol() { + return (4 * Math.PI * radius * radius * radius / 3); + } + + function grow(go) { + var newVol = getVol() + gridObjVol(go) * VOL_MULT; + radius = Math.pow(newVol * 3 / (4 * Math.PI), 1 / 3); + } + + function attachGridObj(go) { + var attXY = getClosestPoint(x, y, go), + dx = attXY[0] - x, + dy = attXY[1] - y, + r = Math.sqrt(dx * dx + dy * dy), + attTh = 0 - th, + offLeft = attXY[0] - go.left, + offTop = attXY[1] - go.top, + offTh = Math.atan2(dy, dx) - th, + attX = r * Math.cos(offTh), + attY = r * Math.sin(offTh), + el = go.el.cloneNode(true), + go_jel = jQuery(go.el), + newAtt = { + el: el, + attX: attX, + attY: attY, + attT: 'translate(' + Math.round(attX) + 'px,' + + Math.round(attY) + 'px) ' + + 'rotate(' + attTh + 'rad)', + r: r, + offTh: offTh, + offPhi: 0 - phi, + diag: go.diag, + removeR: r + go.diag, + visible: false, + display: go_jel.css('display') + }; + attached.push(newAtt); + grow(go); + el.style.position = 'absolute'; + el.style.left = (-offLeft) + 'px'; + el.style.top = (-offTop) + 'px'; + el.style.setProperty(CSS_TRANSFORM_ORIGIN, + offLeft + 'px ' + offTop + 'px', null); + el.style.display = 'none'; + /* copy computed styles from old object. */ + el.style.color = go_jel.css('color'); + el.style.textDecoration = go_jel.css('text-decoration'); + el.style.fontSize = go_jel.css('font-size'); + el.style.fontWeight = go_jel.css('font-weight'); + el.khIgnore = true; + attachedDiv.appendChild(el); + if (sounds) { + sounds.play_pop(); + } + } + + /** + * @return true if the object should be removed from stickyNodes. + */ + function removeIntCb(go) { + if (CHECK_VOLS && gridObjVol(go) > getVol()) { + return false; + } + attachGridObj(go); + return true; + } + + this.updatePhysics = function () { + var oldX = x, oldY = y, dx, dy, + bounce = false, + accelTh; + if (accel) { + accelTh = Math.atan2(accelTargetY - y, accelTargetX - x); + vx += Math.cos(accelTh) * 0.5; + vy += Math.sin(accelTh) * 0.5; + } else { + vx *= 0.95; + vy *= 0.95; + } + x += vx; + y += vy; + /* bounce ball on edges of document. */ + if (x - radius < 0) { + bounce = true; + x = radius + 1; + vx = -vx; + } else if (x + radius > docW) { + bounce = true; + x = docW - radius - 1; + vx = -vx; + } + if (y - radius < 0) { + bounce = true; + y = radius + 1; + vy = -vy; + } else if (y + radius > docH) { + bounce = true; + y = docH - radius - 1; + vy = -vy; + } + if (vx !== 0 || vy !== 0) { + th = Math.atan2(vy, vx); + dx = x - oldX; + dy = y - oldY; + /* arclen = th * r, so th = arclen / r. */ + phi -= Math.sqrt(dx * dx + dy * dy) / radius; + } + stickyNodes.removeIntersecting(x, y, radius, removeIntCb); + this.draw(); + if (bounce && sounds) { + sounds.play_bounce(); + } + }; + + function drawBall() { + var sx1, sy1, sx2, sy2, dx, dy, i, pct1, pct2, z1, z2; + /* move/resize canvas element. */ + canvas_el.style.left = (x - radius) + 'px'; + canvas_el.style.top = (y - radius) + 'px'; + if (radius != lastR) { + canvas_el.width = 2 * radius + 1; + canvas_el.height = 2 * radius + 1; + lastR = radius; + } + /* draw white circle. */ + canvas_ctx.clearRect(0, 0, 2 * radius, 2 * radius); + canvas_ctx.fillStyle = "#fff"; + canvas_ctx.beginPath(); + canvas_ctx.arc(radius, radius, radius - 1, 0, Math.PI * 2, true); + canvas_ctx.fill(); + /* draw outer border. */ + canvas_ctx.strokeStyle = color; + canvas_ctx.beginPath(); + canvas_ctx.arc(radius, radius, radius - 1, 0, Math.PI * 2, true); + canvas_ctx.stroke(); + /* draw stripes. */ + canvas_ctx.fillStyle = color; + sx1 = radius + radius * Math.cos(th + Math.PI / 16); + sy1 = radius + radius * Math.sin(th + Math.PI / 16); + sx2 = radius + radius * Math.cos(th - Math.PI / 16); + sy2 = radius + radius * Math.sin(th - Math.PI / 16); + dx = (radius + radius * Math.cos(th + Math.PI * 15 / 16)) - sx1; + dy = (radius + radius * Math.sin(th + Math.PI * 15 / 16)) - sy1; + for (i = 0; i < Math.PI * 2; i += Math.PI / 7) { + pct1 = (-Math.cos(phi + i) + 1) / 2; + pct2 = (-Math.cos(phi + i + Math.PI / 32) + 1) / 2; + z1 = Math.sin(phi + i); + z2 = Math.sin(phi + i + Math.PI / 32); + if (z1 > 0 && z2 > 0) { + canvas_ctx.beginPath(); + canvas_ctx.moveTo(sx1 + pct1 * dx, sy1 + pct1 * dy); + canvas_ctx.lineTo(sx1 + pct2 * dx, sy1 + pct2 * dy); + canvas_ctx.lineTo(sx2 + pct2 * dx, sy2 + pct2 * dy); + canvas_ctx.lineTo(sx2 + pct1 * dx, sy2 + pct1 * dy); + canvas_ctx.fill(); + } + } + } + + /** + * @return true if the attached object is roughly visible. + */ + function drawAttached(att) { + var oth = th + att.offTh, + ophi = phi + att.offPhi, + ox = att.r * Math.cos(oth), + oy = att.r * Math.sin(oth), + dx = (att.r * Math.cos((th - att.offTh) + Math.PI)) - ox, + dy = (att.r * Math.sin((th - att.offTh) + Math.PI)) - oy, + pct = (-Math.cos(ophi) + 1) / 2, + cx = ox + pct * dx, + cy = oy + pct * dy, + oz = att.r * Math.sin(ophi); + if (oz < 0 && Math.sqrt(cx * cx + cy * cy) + att.diag < radius) { + /* hidden behind circle. */ + if (att.visible) { + att.visible = false; + att.el.style.display = "none"; + } + return false; + } + /* attached node is visible. */ + if (!att.visible) { + att.visible = true; + att.el.style.display = att.display; + } + //att.el.style.zIndex = 500 + Math.round(oz); + att.el.style.zIndex = (oz > 0)? 501 : 499; + att.el.style.setProperty( + CSS_TRANSFORM, + 'translate(' + x + 'px,' + y + 'px) ' + + 'rotate(' + th + 'rad) ' + + 'scaleX(' + Math.cos(ophi) + ') ' + + att.attT, null); + return true; + } + + function onAttachedRemoved(att) { + attachedDiv.removeChild(att.el); + delete att.el; + } + + this.draw = function () { + var i, att, numAttachedVisible = 0; + drawBall(); + for (i = attached.length; --i >= 0;) { + att = attached[i]; + if (att.removeR < radius) { + attached.splice(i, 1).map(onAttachedRemoved); + } else if (drawAttached(att)) { + if (++numAttachedVisible > MAX_ATTACHED_VISIBLE) { + /* remove older items and stop. */ + attached.splice(0, i).map(onAttachedRemoved); + break; + } + } + } + }; +} + +function preventDefault(event) { + event.preventDefault(); + event.returnValue = false; + return false; +} + +function Game(gameDiv, stickyNodes, ballOpts) { + var stickyNodes, player1, physicsInterval, resizeInterval, listeners = []; + player1 = new PlayerBall(gameDiv, stickyNodes, ballOpts, false); + player1.init(); + player1.setXY(300, 300); + window.scrollTo(0, 200); + + function on_resize() { + player1.setDocSize(jQuery(document).width() - 5, + jQuery(document).height() - 5); + } + on_resize(); + + /* touch events - always on? */ + document.addEventListener('touchstart', function (event) { + if (event.touches.length === 1) { + player1.setAccel(true); + return preventDefault(event); + } + }, true); + document.addEventListener('touchmove', function (event) { + player1.setAccelTarget(event.touches[0].pageX, + event.touches[0].pageY); + }, true); + document.addEventListener('touchend', function (event) { + if (event.touches.length === 0) { + player1.setAccel(false); + return preventDefault(event); + } + }, true); + + if (ballOpts.MOUSEB !== -5) { + /* mouse buttons */ + document.addEventListener('mousemove', function (event) { + player1.setAccelTarget(event.pageX, event.pageY); + }, true); + document.addEventListener('mousedown', function (event) { + if (event.button === ballOpts.MOUSEB) { + player1.setAccel(true); + return preventDefault(event); + } + }, true); + document.addEventListener('mouseup', function (event) { + if (event.button === ballOpts.MOUSEB) { + player1.setAccel(false); + return preventDefault(event); + } + }, true); + + if (ballOpts.MOUSEB === 0) { + /* block click events. */ + document.addEventListener('click', function (event) { + if (event.button === 0) { + return preventDefault(event); + } + }, true); + } else if (ballOpts.MOUSEB === 2) { + /* block right-click context menu. */ + document.addEventListener('contextmenu', preventDefault, true); + } + } + + physicsInterval = setInterval(function () { + player1.updatePhysics(); + }, 25); + resizeInterval = setInterval(on_resize, 1000); +} + +function whenAllLoaded(gameDiv, popup, stickyNodes) { + stickyNodes.finalize(jQuery(document).width(), jQuery(document).height()); + jQuery('#loadingp').empty(); + jQuery('').click(function () { + var game, bgmusic, ballOpts; + if (jQuery('#bgmusicc').attr('checked')) { + if (!(bgmusic = document.getElementById('khbgmusic'))) { + bgmusic = document.createElement('audio'); + bgmusic.id = 'khbgmusic'; + bgmusic.loop = 'loop'; + bgmusic.src = 'http://kathack.com/js/katamari.mp3'; + gameDiv.appendChild(bgmusic); + } + bgmusic.play(); + } + ballOpts = { + color: jQuery('#khcolor').val(), + VOL_MULT: parseFloat(jQuery('#vol_mult').val()), + MAX_ATTACHED_VISIBLE: parseInt(jQuery('#maxAtt').val(), 10), + CHECK_VOLS: (jQuery('#checkv').attr('checked'))? true : false, + MOUSEB: parseInt(jQuery('#mouseb').val(), 10) + }; + gameDiv.removeChild(popup); + game = new Game(gameDiv, stickyNodes, ballOpts); + }).appendTo('#loadingp'); +} + +function buildPopup(gameDiv) { + var d = document.createElement('div'), b; + d.style.cssText = '\ +position: fixed;\ +left: 50%;\ +top: 50%;\ +width: 400px;\ +margin-left:-200px;\ +margin-top:-150px;\ +border:1px solid black;\ +background-color:white;\ +color:black;\ +padding:20px;\ +font-size:13px;\ +text-align:left;\ +z-index:501;'; + d.innerHTML = '

\ +\ +Katamari!

\ +\ +

Controls: Hold down to control the ball!

\ +
\ +
\ +
\ +
\ +
\ +
\ +

Loading!

'; + gameDiv.appendChild(d); + d.getElementsByTagName('button')[0].addEventListener('click', function () { + gameDiv.removeChild(d); + }, true); + return d; +} + +function main() { + var gameDiv, checkInterval, stickyNodes, popup; + + gameDiv = document.createElement('div'); + gameDiv.khIgnore = true; + document.body.appendChild(gameDiv); + popup = buildPopup(gameDiv); + + /* setTimeout so that the popup displays before we freeze. */ + setTimeout(function () { + var i, len, el; + window.khNodes.addWords(document.body); + for (i = 0, len = document.body.childNodes.length; i < len; i++) { + el = document.body.childNodes[i]; + window.khNodes.addTagNames(el, [ + 'button', 'canvas', 'iframe', 'img', 'input', 'select', + 'textarea' + ]); + } + + checkInterval = setInterval(function () { + if (window.jQuery) { + clearInterval(checkInterval); + whenAllLoaded(gameDiv, popup, window.khNodes); + } + }, 100); + }, 0); +} + +if (!window.noMain) { + main(); +} + diff --git a/public/js/libdoge.min.js b/public/js/libdoge.min.js new file mode 100644 index 00000000..d972c686 --- /dev/null +++ b/public/js/libdoge.min.js @@ -0,0 +1 @@ +LIBDOGE=(function(){var h={};var b=1;var e=["wow","so","such","so much","very","many","lots","most","beautiful","all the","the","very much","pretty","lol"];var k=["wow","plz","lol"];var d=["doge"];var j={a:true,able:true,about:true,across:true,after:true,all:true,almost:true,also:true,am:true,among:true,an:true,and:true,any:true,are:true,as:true,at:true,be:true,because:true,been:true,but:true,by:true,can:true,cannot:true,could:true,dear:true,did:true,"do":true,does:true,either:true,"else":true,ever:true,every:true,"for":true,from:true,get:true,got:true,had:true,has:true,have:true,he:true,her:true,hers:true,him:true,his:true,how:true,however:true,i:true,"if":true,"in":true,into:true,is:true,it:true,its:true,just:true,least:true,let:true,like:true,likely:true,may:true,me:true,might:true,most:true,must:true,my:true,neither:true,no:true,nor:true,not:true,of:true,off:true,often:true,on:true,only:true,or:true,other:true,our:true,own:true,rather:true,said:true,say:true,says:true,she:true,should:true,since:true,so:true,some:true,than:true,that:true,the:true,their:true,them:true,then:true,there:true,these:true,they:true,"this":true,tis:true,to:true,too:true,twas:true,us:true,wants:true,was:true,we:true,were:true,what:true,when:true,where:true,which:true,"while":true,who:true,whom:true,why:true,will:true,"with":true,would:true,yet:true,you:true,your:true};var a=null;var g=null;var c=false;var f=[];h.wagTail=function(n,m){return Math.floor(Math.random()*(m-n+1))+n};h.chew=function(m){return m.replace(/\W/g," ")};h.digest=function(o){var n={};var m=j;for(i in e){m[e[i]]=true}for(i in k){m[k[i]]=true}for(i in o){if(o[i].length<=2||o[i].length>20){continue}if(o[i] in m){continue}if(o[i] in n){n[o[i]]++;continue}if(parseInt(o[i]).toString()==o[i]){continue}n[o[i]]=1}return Object.keys(n)};h.tearMeta=function(n){var q;var m=[];m.push(document.title.trim());var p=["keywords","description","author"];var o=document.getElementsByTagName("meta");for(i in o){if(p.indexOf(o[i].name)!=-1&&typeof o[i].content!="undefined"){m.push(o[i].content.trim())}}q=h.chew(unescape(m.join(" ").toLowerCase())).split(/[\s\/]+/g);if(n!=null){q=q.concat(n)}return h.digest(q)};h.tearContent=function(){var o=document.createElement("div");o.innerHTML=document.body.innerHTML.replace(/>/g,"> ");var p=["script","style"];for(n in p){var m=o.getElementsByTagName(p[n]);for(var n=(m.length-1);n>=0;n--){m[n].parentElement.removeChild(m[n])}}var q=h.chew(unescape(o.textContent.toLowerCase().trim())).split(/[\s\/]+/g);return h.digest(q)};h.bark=function(){var p=[];var o=[];o.push((Math.random()<0.5)?g:a);if(Math.random()<0.4){o.push((Math.random()<0.5)?g:a)}p.push(e[h.wagTail(0,e.length-1)]);var n=[];for(i in o){var m=h.wagTail(0,o[i].length-1);if(n.indexOf(o[i][m])==-1){n.push(o[i][m])}}p.push(n.join(" "));if(Math.random()<=0.33){p.push(k[h.wagTail(0,k.length-1)])}return p.join(" ")};h.come=function(n){var m=document.createElement("div");m.setAttribute("id",n);m.innerHTML=h.bark();m.style.position="fixed";m.style.top=h.wagTail(0,(window.innerHeight*0.9))+"px";m.style.left=h.wagTail(0,(window.innerWidth*0.85))+"px";m.style.display="block";m.style.zIndex=999999;m.style.opacity=1;m.style.fontSize="3em";m.style.textShadow="-2px 0px 2px rgba(0, 0, 0, 1)";m.style.fontFamily="Comic Sans MS";m.style.color="rgb("+h.wagTail(0,255)+","+h.wagTail(0,255)+","+h.wagTail(0,255)+")";document.body.appendChild(m);setTimeout(function(){h.go(n,1)},h.wagTail(0,750))};h.go=function(o,m){var n=document.getElementById(o);n.style.opacity=m;if(m>0){setTimeout(function(){h.go(o,m-0.1)},100)}else{if(f.indexOf(o)!=-1){f.splice(f.indexOf(o),1)}n.parentElement.removeChild(n)}};h.stare=function(){var m=document.createElement("img");m.setAttribute("id","thedoge");m.setAttribute("src","https://raw.github.com/ljalonen/libdoge/master/img/doge.png");m.setAttribute("rel","bottom");m.style.position="fixed";m.style.left="0px";m.style.bottom="0px";m.style.zIndex=999999;c=true;document.body.appendChild(m);h.run(document.getElementById("thedoge"),h.wagTail(500,1000))};h.moar=function(){if(!c){h.stare()}if(a==null){a=h.tearMeta(d)}if(g==null){g=h.tearContent()}while(f.length<7){var m="doge_"+b;f.push(m);b++;setTimeout((function(n){return function(){h.come(n)}})(m),h.wagTail(0,2500))}};h.puke=function(){return{meta_words:a,content_words:g}};h.flip=function(p,n){var m=["transform","WebkitTransform","msTransform","MozTransform","OTransform"];var o={0:"bottom",270:"right",180:"top",90:"left"};p.setAttribute("rel",o[n]);for(i in m){p.style[m[i]]="rotate("+n+"deg)"}};var l=function(m){return{left:parseInt(m.style.left.replace("px","")),bottom:parseInt(m.style.bottom.replace("px","")),side:m.getAttribute("rel")}};h.teleport=function(r,p){var o=["top","bottom","left","right"];var n=o[h.wagTail(0,o.length-1)];r.setAttribute("rel",n);if(p==null){p=false}if(n=="top"){h.flip(r,180);var m=(p)?window.innerHeight:(window.innerHeight-r.clientHeight);r.style.bottom=m+"px";r.style.left=h.wagTail(0,window.innerWidth-r.clientWidth)+"px"}else{if(n=="bottom"){h.flip(r,0);var m=(p)?-r.clientHeight:0;r.style.bottom=m+"px";r.style.left=h.wagTail(0,window.innerWidth-r.clientWidth)+"px"}else{if(n=="left"){h.flip(r,90);r.style.bottom=h.wagTail(0,window.innerHeight-r.clientWidth)+"px";var q=(p)?-r.clientHeight:0;r.style.left=q+"px"}else{if(n=="right"){h.flip(r,270);r.style.bottom=h.wagTail(0,window.innerHeight-r.clientWidth)+"px";var q=(p)?window.innerWidth:(window.innerWidth-r.clientHeight);r.style.left=q+"px"}}}}};h.hide=function(o){var m=l(o);var n=false;if(m.side=="bottom"){o.style.bottom=(m.bottom-1)+"px";n=((m.bottom-1)==-o.clientHeight)}else{if(m.side=="right"){o.style.left=(m.left+1)+"px";n=((m.left+1)==window.innerWidth)}else{if(m.side=="top"){o.style.bottom=(m.bottom+1)+"px";n=((m.bottom+1)==window.innerHeight)}else{if(m.side=="left"){o.style.left=(m.left-1)+"px";n=((m.left-1)==-o.clientHeight)}}}}if(!n){setTimeout(function(){h.hide(o)},1)}else{setTimeout(function(){h.teleport(o,true);h.ambush(o)},h.wagTail(0,2500))}};h.ambush=function(o){var n=l(o);var m=false;if(n.side=="bottom"){o.style.bottom=(n.bottom+1)+"px";m=((n.bottom+1)==0)}else{if(n.side=="right"){o.style.left=(n.left-1)+"px";m=((n.left-1)==window.innerWidth-o.clientHeight)}else{if(n.side=="top"){o.style.bottom=(n.bottom-1)+"px";m=((n.bottom-1)==window.innerHeight-o.clientHeight)}else{if(n.side=="left"){o.style.left=(n.left+1)+"px";m=((n.left+1)==0)}}}}if(!m){setTimeout(function(){h.ambush(o)},1)}else{setTimeout(function(){h.plz(o)},h.wagTail(0,2500))}};h.plz=function(o){var m=l(o);if(Math.random()<0.5){var n=h.wagTail(500,1000);h.run(o,n)}else{h.hide(o)}};h.run=function(o,n){var m=l(o);if(m.side=="bottom"){if(m.left+o.clientWidth>=window.innerWidth){h.flip(o,270)}else{o.style.left=(m.left+1)+"px"}}else{if(m.side=="right"){if(m.bottom+o.clientWidth>=window.innerHeight){h.flip(o,180)}else{o.style.bottom=(m.bottom+1)+"px"}}else{if(m.side=="top"){if(m.left<=0){h.flip(o,90)}else{o.style.left=(m.left-1)+"px"}}else{if(m.side=="left"){if(m.bottom<=0){h.flip(o,0)}else{o.style.bottom=(m.bottom-1)+"px"}}}}}setTimeout(function(){if(--n<0){h.plz(o)}else{h.run(o,n)}},1)};return h}());setInterval(function(){LIBDOGE.moar()},1500); \ No newline at end of file