diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..cfa85aa --- /dev/null +++ b/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["es2015"], + "compact": false, +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..34fdc15 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.sass-cache +node_modules +prod.js.map +style.css.map \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..08482c2 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,76 @@ +/** + * A lot of directories are verbose without wildcards, largely a result of having a shared codebase with the backend code. + * + * TODO: Separate tasks for backend app! + */ +module.exports = function (grunt) { + + // Project configuration. + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + + /** + * Converts our Sass files to CSS. + */ + sass: { + compile: { + options: { + style: 'nested' + }, + files: { + 'public/css/style.css': 'style.scss' + } + } + }, + + + /** + * Watches for changes on all JS and CSS files. + * + * Live reload is working (servers running on localhost 35729 and 35728). + * You'll need a Live-reload plugin installed (https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei) + * + * Changes to grunt file will rerun the grunt script. + */ + watch: { + css: { + files: ['style.scss'], + tasks: ['sass:compile'] + }, + configFiles: { + files: ['Gruntfile.js'], + options: { + reload: true + } + } + }, + + /** + * Converts all ES6 Javascript into ES5 Javascript. + * + * .babelrc full configures Babel. + */ + babel: { + /** + * Transform ES6 JS files into ES5. + */ + es6: { + options: { + sourceMap: true, + presets: ['es2015'], + }, + files: { + // "client.js": "public/js/prod.js" + "public/js/prod.js": "client.js", + }, + }, + }, + }); + + grunt.loadNpmTasks('grunt-contrib-sass'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-babel'); + + grunt.registerTask('development', ['sass:compile', 'watch']); + grunt.registerTask('production', ['sass:compile', 'babel:es6']); +}; diff --git a/README.md b/README.md index f943f2c..6e14a81 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ -# afx \ No newline at end of file +# afx + +## Setup + +Install the package dependencies: `npm install`. + +Copy the pre-commit Git hook, to ensure the assets are compiled before you commit. +``` +cp pre-commit .git/hooks/. +``` + +## Development + +``` +grunt development +``` diff --git a/client.js b/client.js new file mode 100644 index 0000000..01ec7b0 --- /dev/null +++ b/client.js @@ -0,0 +1,254 @@ + +class TextScramble { + /** Modified version of Justin Windle's Text Scrambler: https://codepen.io/soulwire/pen/mErPAK */ + + constructor(el, scrambleSpeed, chars) { + this.el = el; + this.scrambleSpeed = scrambleSpeed || 25; + this.chars = chars || 'aphextwin'; + this.update = this.update.bind(this) + } + + setText(newText) { + window.countdowner.updateField = false; + const oldText = this.el.innerText; + const length = Math.max(oldText.length, newText.length); + this.queue = []; + + for (let i = 0; i < length; i++) { + const from = oldText[i] || ''; + const to = newText[i] || ''; + + const start = Math.floor(Math.random() * (this.scrambleSpeed)); + const end = start + Math.floor(Math.random() * (this.scrambleSpeed)); + + this.queue.push({ from, to, start, end }) + } + cancelAnimationFrame(this.frameRequest); + this.frame = 0; + this.update(); + } + + update() { + let output = ''; + let complete = 0; + for (let i = 0, n = this.queue.length; i < n; i++) { + let { from, to, start, end, char } = this.queue[i]; + if (this.frame >= end) { + complete++; + output += to + } else if (this.frame >= start) { + if (!char || Math.random() < 0.28) { + char = this.randomChar(); + this.queue[i].char = char + } + output += `${char}` + } else { + output += from + } + } + this.el.innerHTML = output; + if (complete === this.queue.length) { + window.countdowner.updateField = true; + return; + } else { + this.frameRequest = requestAnimationFrame(this.update); + this.frame++ + } + } + + randomChar() { + return this.chars[Math.floor(Math.random() * this.chars.length)] + } +} + +function padWithDots(str) { + let maxPadding = 40; + let numToAdd = maxPadding - str.length; + + let dots = ''; + for (let i=0; i < numToAdd; i++) { + dots = dots + "."; + } + + return str + dots; +} + +class Countdown { + constructor() { + let that = this; + let a = new Date().valueOf(); + let b = 1499119200000; + let d = 1496520000000; + + this.$el = $('#countdown'); + this.updateField = true; + this.c = b - a; + + this._setText(); + setInterval(function() { + that.c = Math.floor((that.c - (100 * ((b - a) / (d - a)) ) )) ; + that._setText(); + }, 100); + } + + _setText() { + if (this.updateField) { + this.$el.text( padWithDots(this.c + "") ); + } + } +} + +function initScramblers() { + window.countdowner = new Countdown(); + const countdownScrambler = new TextScramble(document.getElementById('countdown'), 15, 'aphex'); + + $('#nts-label').text(padWithDots("NTS")); + + let $paddingElements = $('.aphexDotPadding'); + let paddingScramblers = []; + $paddingElements.each( function(i) { + let $el = $($paddingElements[i]); + $el.length && $el.text( padWithDots("")); + + paddingScramblers.push( new TextScramble($paddingElements[i], 25, i % 2 === 0 ? 'twin' : 'aphex')); + }); + + let scrambleText = function() { + for(let i=0; i < paddingScramblers.length; i++) { + paddingScramblers[i].setText(padWithDots("")); + } + + countdownScrambler.setText( padWithDots(window.countdowner.c + "") ); + + let rangeInSeconds = 4.5; + let randomTimeout = Math.floor( (Math.random() * 1000) * rangeInSeconds); + + setTimeout(scrambleText, randomTimeout) + }; + + scrambleText(); +} + +let NTS_AFX = {}; +NTS_AFX.store = { + init: function() { + let config = { + apiKey: "AIzaSyCn2JexWTvW3fyvyvjWNcdwe-wDkgOw1c0", + authDomain: "nts-afx.firebaseapp.com", + databaseURL: "https://nts-afx.firebaseio.com", + projectId: "nts-afx", + storageBucket: "nts-afx.appspot.com", + messagingSenderId: "1740064170" + }; + firebase.initializeApp(config); + }, + post: function(message) { + let record = { message: message }; + let newPostKey = firebase.database().ref().child('messages').push().key; + let updates = {}; + updates['/messages/' + newPostKey] = record; + return firebase.database().ref().update(updates); + } +}; + +(function (i, s, o, g, r, a, m) { + i['GoogleAnalyticsObject'] = r; + i[r] = i[r] || function () { + (i[r].q = i[r].q || []).push(arguments) + }, i[r].l = 1 * new Date(); + a = s.createElement(o), + m = s.getElementsByTagName(o)[0]; + a.async = 1; + a.src = g; + m.parentNode.insertBefore(a, m) +})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); +ga('create', 'UA-6061419-3', 'auto'); + +class AudioPlayer { + constructor() { + this.el = document.getElementById('aphex-audio'); + + this.el.addEventListener('play', function(e) { + $('#player').addClass('playing'); + }); + this.el.addEventListener('pause', function(e) { + $('#player').removeClass('playing'); + }); + + this.el.volume = 0.8; + } + + play() { + this.el.play(); + } + + pause() { + this.el.pause(); + } + + isPlaying() { + return !this.el.paused; + } + + toggleAudio() { + this.isPlaying() + ? this.pause() + : this.play(); + } +} + +$(document).ready( function () { + ga('send', 'pageview', window.location.pathname); + + initScramblers(); + NTS_AFX.store.init(); + + window.audioPlayer = new AudioPlayer(); + + let $consoleEntryForm = $('#console-entry-form'); + + $consoleEntryForm.focus(); + $consoleEntryForm.submit( function(e) { + e.preventDefault(); + + ga('send', 'event', 'Aphex', 'PasswordAttempt'); + + let authenticated = NTS_AFX.store.post( + e.currentTarget.children['console-entry'].value + ).then(function(authenticated) { + + if (authenticated) { + let $msg = $('#success-message'); + $msg.addClass('display'); + + setTimeout(function() { + $msg.removeClass('display'); + },2000); + + authenticated.authenticate(); + } else { + let $msg = $('#error-message'); + $msg.addClass('display'); + + setTimeout(function() { + $msg.removeClass('display'); + }, 1500); + } + + e.currentTarget.children['console-entry'].value = ""; + }); + }); + + $('#nts-link').on('click', function() { + ga('send', 'event', 'Aphex', 'GoTo-NTS'); + }); + + $('#warp-link').on('click', function() { + ga('send', 'event', 'Aphex', 'GoTo-Warp'); + }); + + $('#player').on('click', function() { + window.audioPlayer.toggleAudio(); + }); +}); \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..188ab4a --- /dev/null +++ b/index.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + Aphex Twin | NTS + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ ERROR +
+ +
+ ACCESS GRANTED +
+ + + +
+ + +
+ +
+ +
+ +
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ + +
+
+
+ + +
+ +
+ + + + \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..f237187 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "afx", + "version": "1.0.0", + "description": "", + "main": "index.html", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ntslive/afx.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/ntslive/afx/issues" + }, + "homepage": "https://github.com/ntslive/afx#readme", + "devDependencies": { + "babel-preset-es2015": "^6.24.1", + "grunt": "^1.0.1", + "grunt-babel": "^6.0.0", + "grunt-contrib-sass": "^1.0.0", + "grunt-contrib-watch": "^1.0.0" + } +} diff --git a/pre-commit b/pre-commit new file mode 100755 index 0000000..9fd1f93 --- /dev/null +++ b/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +# +grunt production +git add public/. diff --git a/public/audio/afx.mp3 b/public/audio/afx.mp3 new file mode 100644 index 0000000..e1790f5 Binary files /dev/null and b/public/audio/afx.mp3 differ diff --git a/public/css/fontello.css b/public/css/fontello.css new file mode 100755 index 0000000..70dad0f --- /dev/null +++ b/public/css/fontello.css @@ -0,0 +1,59 @@ +@font-face { + font-family: 'fontello'; + src: url('../font/fontello.eot?17501704'); + src: url('../font/fontello.eot?17501704#iefix') format('embedded-opentype'), + url('../font/fontello.woff2?17501704') format('woff2'), + url('../font/fontello.woff?17501704') format('woff'), + url('../font/fontello.ttf?17501704') format('truetype'), + url('../font/fontello.svg?17501704#fontello') format('svg'); + font-weight: normal; + font-style: normal; +} +/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ +/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ +/* +@media screen and (-webkit-min-device-pixel-ratio:0) { + @font-face { + font-family: 'fontello'; + src: url('../font/fontello.svg?17501704#fontello') format('svg'); + } +} +*/ + + [class^="icon"]:before, [class*=" icon"]:before { + font-family: "fontello"; + font-style: normal; + font-weight: normal; + speak: none; + + display: inline-block; + text-decoration: inherit; + width: 1em; + margin-right: .2em; + text-align: center; + /* opacity: .8; */ + + /* For safety - reset parent styles, that can break glyph codes*/ + font-variant: normal; + text-transform: none; + + /* fix buttons height, for twitter bootstrap */ + line-height: 1em; + + /* Animation center compensation - margins should be symmetric */ + /* remove if not needed */ + margin-left: .2em; + + /* you can be more comfortable with increased icons size */ + /* font-size: 120%; */ + + /* Font smoothing. That was taken from TWBS */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + /* Uncomment for 3D effect */ + /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ +} + +.icon-play:before { content: '\e800'; } /* '' */ +.icon-pause:before { content: '\e802'; } /* '' */ \ No newline at end of file diff --git a/public/css/fonts/DecimaMonoPro.ttf b/public/css/fonts/DecimaMonoPro.ttf new file mode 100644 index 0000000..c036626 Binary files /dev/null and b/public/css/fonts/DecimaMonoPro.ttf differ diff --git a/public/css/fonts/decimamonopro-webfont.woff b/public/css/fonts/decimamonopro-webfont.woff new file mode 100755 index 0000000..174a2b8 Binary files /dev/null and b/public/css/fonts/decimamonopro-webfont.woff differ diff --git a/public/css/fonts/decimamonopro-webfont.woff2 b/public/css/fonts/decimamonopro-webfont.woff2 new file mode 100755 index 0000000..36c6efb Binary files /dev/null and b/public/css/fonts/decimamonopro-webfont.woff2 differ diff --git a/public/css/style.css b/public/css/style.css new file mode 100644 index 0000000..adc4f5c --- /dev/null +++ b/public/css/style.css @@ -0,0 +1,219 @@ +@import url(fontello.css); +@font-face { + font-family: 'Decima'; + src: url("fonts/decimamonopro-webfont.woff2") format("woff2"), url("fonts/decimamonopro-webfont.woff") format("woff"), url("fonts/DecimaMonoPro.ttf") format("ttf"); + font-weight: normal; + font-style: normal; } +html { + background-color: black; + color: white; + font-family: "Decima", courier; + min-width: 320px; } + +* { + box-sizing: border-box; } + +input[type="search"]::-webkit-search-decoration { + display: none; } + +input { + margin: 0; + outline: 0; + vertical-align: middle; + background: none; + border: none; + color: white; + font-family: "Decima", courier !important; + font-size: 1em; } + +input[type="reset"], input[type="submit"], input[type="button"] { + -webkit-appearance: none; + background: none; + border: 0; + cursor: pointer; + overflow: visible; + padding: 0; + width: auto; + font-family: "Decima", courier; } + +a { + text-decoration: none; + transition: opacity 0.2s linear; } + a:hover { + opacity: 0.7; } + a:visited { + color: white; } + a:-webkit-any-link { + color: white; } + +#aphex-page { + color: white; + width: 100%; + font-size: 19.5px; } + +#aphex-console-container { + position: absolute; + top: 50%; + left: 0; + width: 50%; + height: auto; + padding: 0 20px; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + max-width: 50%; + overflow: hidden; } + +#links-bottom { + margin-top: 20px; } + #links-bottom #warp-link { + float: left; } + #links-bottom #warp-link img { + height: 35px; } + #links-bottom #nts-link { + float: left; + margin-right: 10px; } + #links-bottom #nts-link img { + width: 35px; } + +#links-top, #console, #console-entry-form, #links-bottom > div { + max-width: 500px; + margin-left: auto; + margin-right: auto; } + +#console .console-row { + display: inline-block; } +#console .aphexDotPadding { + display: inline; } +#console #console-entry-form { + width: 500px; } + #console #console-entry-form #console-entry { + width: 100%; } + +#aphex-gif-container { + position: absolute; + float: right; + top: 50%; + right: 0; + width: 50%; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + text-align: center; } + #aphex-gif-container img { + max-width: 80%; } + +#error-message, #success-message { + position: absolute; + top: 50%; + left: 0; + right: 0; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + text-align: center; + font-size: 6em; + font-weight: lighter; + z-index: 99999; + visibility: hidden; + opacity: 0; + -webkit-transition: all 0.2s linear; + -moz-transition: all 0.2s linear; + -ms-transition: all 0.2s linear; + -o-transition: all 0.2s linear; + transition: all 0.2s linear; } + #error-message.display, #success-message.display { + visibility: visible; + opacity: 1; } + +#error-message { + color: #be0000; + text-shadow: 0 0 40px #ab0505; } + +#success-message { + color: #00d200; + text-shadow: 0 0 30px green; + overflow: hidden; } + +audio { + display: none; } + +#player { + position: absolute; + top: 10px; + right: 10px; + font-size: 2em; + cursor: pointer; + color: white; + opacity: 1; + z-index: 9999999999; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + -ms-transition: opacity 0.2s linear; + -o-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; } + #player:hover { + opacity: 0.7; + cursor: pointer; } + #player.playing #player-play { + display: none; } + #player.playing #player-pause { + display: block; } + +#player-pause { + display: none; } + +@media only screen and (max-width: 700px) { + #aphex-page { + position: absolute; + top: 50%; + left: 0; + right: 0; + font-size: 1.2em; + height: 450px; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); } + + #aphex-console-container { + position: relative; + display: block; + width: 300px; + height: auto; + max-width: 100%; + margin: 0 auto; + padding: 0; + top: 0; + overflow: hidden; + -webkit-transform: none; + -moz-transform: none; + -ms-transform: none; + -o-transform: none; + transform: none; } + #aphex-console-container #nts-link img { + width: 30px; } + + #aphex-gif-container { + position: relative; + width: 100%; + display: block; + overflow: auto; + top: 0; + padding-top: 0; + -webkit-transform: none; + -moz-transform: none; + -ms-transform: none; + -o-transform: none; + transform: none; } + #aphex-gif-container img { + width: 250px; } } + +/*# sourceMappingURL=style.css.map */ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..05548c5 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..9294fe0 Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.gif b/public/favicon.gif new file mode 100644 index 0000000..70545fa Binary files /dev/null and b/public/favicon.gif differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..7857ac4 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/font/fontello.eot b/public/font/fontello.eot new file mode 100755 index 0000000..4fedfca Binary files /dev/null and b/public/font/fontello.eot differ diff --git a/public/font/fontello.svg b/public/font/fontello.svg new file mode 100755 index 0000000..c00ae64 --- /dev/null +++ b/public/font/fontello.svg @@ -0,0 +1,14 @@ + + + +Copyright (C) 2017 by original authors @ fontello.com + + + + + + + + + + \ No newline at end of file diff --git a/public/font/fontello.ttf b/public/font/fontello.ttf new file mode 100755 index 0000000..d6785c1 Binary files /dev/null and b/public/font/fontello.ttf differ diff --git a/public/font/fontello.woff b/public/font/fontello.woff new file mode 100755 index 0000000..cd77117 Binary files /dev/null and b/public/font/fontello.woff differ diff --git a/public/font/fontello.woff2 b/public/font/fontello.woff2 new file mode 100755 index 0000000..571d038 Binary files /dev/null and b/public/font/fontello.woff2 differ diff --git a/public/img/afx_basic.gif b/public/img/afx_basic.gif new file mode 100644 index 0000000..6b0fe04 Binary files /dev/null and b/public/img/afx_basic.gif differ diff --git a/public/img/nts_white.png b/public/img/nts_white.png new file mode 100644 index 0000000..696990e Binary files /dev/null and b/public/img/nts_white.png differ diff --git a/public/img/socials.png b/public/img/socials.png new file mode 100644 index 0000000..a116a95 Binary files /dev/null and b/public/img/socials.png differ diff --git a/public/img/warp.png b/public/img/warp.png new file mode 100644 index 0000000..f65ff0e Binary files /dev/null and b/public/img/warp.png differ diff --git a/public/js/prod.js b/public/js/prod.js new file mode 100644 index 0000000..e616f0d --- /dev/null +++ b/public/js/prod.js @@ -0,0 +1,287 @@ +'use strict'; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var TextScramble = function () { + /** Modified version of Justin Windle's Text Scrambler: https://codepen.io/soulwire/pen/mErPAK */ + + function TextScramble(el, scrambleSpeed, chars) { + _classCallCheck(this, TextScramble); + + this.el = el; + this.scrambleSpeed = scrambleSpeed || 25; + this.chars = chars || 'aphextwin'; + this.update = this.update.bind(this); + } + + _createClass(TextScramble, [{ + key: 'setText', + value: function setText(newText) { + window.countdowner.updateField = false; + var oldText = this.el.innerText; + var length = Math.max(oldText.length, newText.length); + this.queue = []; + + for (var i = 0; i < length; i++) { + var from = oldText[i] || ''; + var to = newText[i] || ''; + + var start = Math.floor(Math.random() * this.scrambleSpeed); + var end = start + Math.floor(Math.random() * this.scrambleSpeed); + + this.queue.push({ from: from, to: to, start: start, end: end }); + } + cancelAnimationFrame(this.frameRequest); + this.frame = 0; + this.update(); + } + }, { + key: 'update', + value: function update() { + var output = ''; + var complete = 0; + for (var i = 0, n = this.queue.length; i < n; i++) { + var _queue$i = this.queue[i], + from = _queue$i.from, + to = _queue$i.to, + start = _queue$i.start, + end = _queue$i.end, + char = _queue$i.char; + + if (this.frame >= end) { + complete++; + output += to; + } else if (this.frame >= start) { + if (!char || Math.random() < 0.28) { + char = this.randomChar(); + this.queue[i].char = char; + } + output += '' + char + ''; + } else { + output += from; + } + } + this.el.innerHTML = output; + if (complete === this.queue.length) { + window.countdowner.updateField = true; + return; + } else { + this.frameRequest = requestAnimationFrame(this.update); + this.frame++; + } + } + }, { + key: 'randomChar', + value: function randomChar() { + return this.chars[Math.floor(Math.random() * this.chars.length)]; + } + }]); + + return TextScramble; +}(); + +function padWithDots(str) { + var maxPadding = 40; + var numToAdd = maxPadding - str.length; + + var dots = ''; + for (var i = 0; i < numToAdd; i++) { + dots = dots + "."; + } + + return str + dots; +} + +var Countdown = function () { + function Countdown() { + _classCallCheck(this, Countdown); + + var that = this; + var a = new Date().valueOf(); + var b = 1499119200000; + var d = 1496520000000; + + this.$el = $('#countdown'); + this.updateField = true; + this.c = b - a; + + this._setText(); + setInterval(function () { + that.c = Math.floor(that.c - 100 * ((b - a) / (d - a))); + that._setText(); + }, 100); + } + + _createClass(Countdown, [{ + key: '_setText', + value: function _setText() { + if (this.updateField) { + this.$el.text(padWithDots(this.c + "")); + } + } + }]); + + return Countdown; +}(); + +function initScramblers() { + window.countdowner = new Countdown(); + var countdownScrambler = new TextScramble(document.getElementById('countdown'), 15, 'aphex'); + + $('#nts-label').text(padWithDots("NTS")); + + var $paddingElements = $('.aphexDotPadding'); + var paddingScramblers = []; + $paddingElements.each(function (i) { + var $el = $($paddingElements[i]); + $el.length && $el.text(padWithDots("")); + + paddingScramblers.push(new TextScramble($paddingElements[i], 25, i % 2 === 0 ? 'twin' : 'aphex')); + }); + + var scrambleText = function scrambleText() { + for (var i = 0; i < paddingScramblers.length; i++) { + paddingScramblers[i].setText(padWithDots("")); + } + + countdownScrambler.setText(padWithDots(window.countdowner.c + "")); + + var rangeInSeconds = 4.5; + var randomTimeout = Math.floor(Math.random() * 1000 * rangeInSeconds); + + setTimeout(scrambleText, randomTimeout); + }; + + scrambleText(); +} + +var NTS_AFX = {}; +NTS_AFX.store = { + init: function init() { + var config = { + apiKey: "AIzaSyCn2JexWTvW3fyvyvjWNcdwe-wDkgOw1c0", + authDomain: "nts-afx.firebaseapp.com", + databaseURL: "https://nts-afx.firebaseio.com", + projectId: "nts-afx", + storageBucket: "nts-afx.appspot.com", + messagingSenderId: "1740064170" + }; + firebase.initializeApp(config); + }, + post: function post(message) { + var record = { message: message }; + var newPostKey = firebase.database().ref().child('messages').push().key; + var updates = {}; + updates['/messages/' + newPostKey] = record; + return firebase.database().ref().update(updates); + } +}; + +(function (i, s, o, g, r, a, m) { + i['GoogleAnalyticsObject'] = r; + i[r] = i[r] || function () { + (i[r].q = i[r].q || []).push(arguments); + }, i[r].l = 1 * new Date(); + a = s.createElement(o), m = s.getElementsByTagName(o)[0]; + a.async = 1; + a.src = g; + m.parentNode.insertBefore(a, m); +})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); +ga('create', 'UA-6061419-3', 'auto'); + +var AudioPlayer = function () { + function AudioPlayer() { + _classCallCheck(this, AudioPlayer); + + this.el = document.getElementById('aphex-audio'); + + this.el.addEventListener('play', function (e) { + $('#player').addClass('playing'); + }); + this.el.addEventListener('pause', function (e) { + $('#player').removeClass('playing'); + }); + + this.el.volume = 0.8; + } + + _createClass(AudioPlayer, [{ + key: 'play', + value: function play() { + this.el.play(); + } + }, { + key: 'pause', + value: function pause() { + this.el.pause(); + } + }, { + key: 'isPlaying', + value: function isPlaying() { + return !this.el.paused; + } + }, { + key: 'toggleAudio', + value: function toggleAudio() { + this.isPlaying() ? this.pause() : this.play(); + } + }]); + + return AudioPlayer; +}(); + +$(document).ready(function () { + ga('send', 'pageview', window.location.pathname); + + initScramblers(); + NTS_AFX.store.init(); + + window.audioPlayer = new AudioPlayer(); + + var $consoleEntryForm = $('#console-entry-form'); + + $consoleEntryForm.focus(); + $consoleEntryForm.submit(function (e) { + e.preventDefault(); + + ga('send', 'event', 'Aphex', 'PasswordAttempt'); + + var authenticated = NTS_AFX.store.post(e.currentTarget.children['console-entry'].value).then(function (authenticated) { + + if (authenticated) { + var $msg = $('#success-message'); + $msg.addClass('display'); + + setTimeout(function () { + $msg.removeClass('display'); + }, 2000); + + authenticated.authenticate(); + } else { + var _$msg = $('#error-message'); + _$msg.addClass('display'); + + setTimeout(function () { + _$msg.removeClass('display'); + }, 1500); + } + + e.currentTarget.children['console-entry'].value = ""; + }); + }); + + $('#nts-link').on('click', function () { + ga('send', 'event', 'Aphex', 'GoTo-NTS'); + }); + + $('#warp-link').on('click', function () { + ga('send', 'event', 'Aphex', 'GoTo-Warp'); + }); + + $('#player').on('click', function () { + window.audioPlayer.toggleAudio(); + }); +}); +//# sourceMappingURL=prod.js.map diff --git a/style.scss b/style.scss new file mode 100644 index 0000000..457cc1e --- /dev/null +++ b/style.scss @@ -0,0 +1,302 @@ +$font: 'Decima', courier; +$row-width: 500px; + +@import "fontello.css"; + +@font-face { + font-family: 'Decima'; + src: url('fonts/decimamonopro-webfont.woff2') format('woff2'), + url('fonts/decimamonopro-webfont.woff') format('woff'), + url('fonts/DecimaMonoPro.ttf') format('ttf'); + font-weight: normal; + font-style: normal; +} + +html { + background-color: black; + color: white; + + font-family: $font; + + min-width: 320px; +} + +* { + box-sizing: border-box; +} + +input[type="search"]::-webkit-search-decoration { + display: none; +} +input { + margin: 0; + outline: 0; + vertical-align: middle; + background: none; + border: none; + color: white; + font-family: $font !important; + font-size: 1em; +} +input[type="reset"], input[type="submit"], input[type="button"] { + -webkit-appearance: none; + background: none; + border: 0; + cursor: pointer; + overflow: visible; + padding: 0; + width: auto; + + font-family: $font; +} +input::-webkit-input-placeholder { } + +a { + text-decoration: none; + transition: opacity 0.2s linear; + &:hover { + opacity: 0.7; + } + &:visited { + color: white; + } + &:-webkit-any-link { + color: white; + } +} + +#aphex-page { + color: white; + width: 100%; + font-size: 19.5px; +} + +#aphex-console-container { + position: absolute; + + top: 50%; + left: 0; + width: 50%; + height: auto; + + padding: 0 20px; + + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + + max-width: 50%; + + overflow: hidden; +} + +#links-bottom { + margin-top: 20px; + + #warp-link { + float: left; + img { + height: 35px; + } + } + #nts-link { + float: left; + margin-right: 10px; + img { + width: 35px; + } + } +} + +#links-top, #console, #console-entry-form, #links-bottom > div { + max-width: $row-width; + margin-left: auto; + margin-right: auto; +} + +#console { + .console-row { + display: inline-block; + } + + .aphexDotPadding { + display: inline; + } + + #console-entry-form { + width: $row-width; + + #console-entry { + width: 100%; + } + } +} + +#aphex-gif-container { + position: absolute; + float: right; + top: 50%; + right: 0; + width: 50%; + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + + text-align: center; + + img { + max-width: 80%; + } +} + +#error-message, #success-message { + position: absolute; + top: 50%; + left: 0; right: 0; + + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + + text-align: center; + + font-size: 6em; + + font-weight: lighter; + z-index: 99999; + + visibility: hidden; + opacity: 0; + + &.display { + visibility: visible; + opacity: 1; + } + + -webkit-transition: all 0.2s linear; + -moz-transition: all 0.2s linear ; + -ms-transition: all 0.2s linear ; + -o-transition: all 0.2s linear ; + transition: all 0.2s linear ; +} +#error-message { + color: #be0000; + text-shadow: 0 0 40px #ab0505; +} +#success-message { + color: #00d200; + text-shadow: 0 0 30px green; + overflow: hidden; +} + +audio { + display: none; +} +#player { + position: absolute; + top: 10px; + right: 10px; + font-size: 2em; + cursor: pointer; + + color: white; + opacity: 1; + + //width: 45px; + //height: 36px; + + z-index: 9999999999; + + &:hover { + opacity: 0.7; + cursor: pointer; + } + + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear ; + -ms-transition: opacity 0.2s linear ; + -o-transition: opacity 0.2s linear ; + transition: opacity 0.2s linear ; + + &.playing { + #player-play { + display: none; + } + + #player-pause { + display: block; + } + } +} + +#player-pause { + display: none; +} + +@media only screen and (max-width: 700px) { + #aphex-page { + position: absolute; + top: 50%; + left: 0; right: 0; + + font-size: 1.2em; + height: 450px; + + -webkit-transform: translateY(-50%); + -moz-transform: translateY(-50%); + -ms-transform: translateY(-50%); + -o-transform: translateY(-50%); + transform: translateY(-50%); + } + #aphex-console-container { + position: relative; + display: block; + width: 300px; + height: auto; + max-width: 100%; + + margin: 0 auto; + padding: 0; + top: 0; + + overflow: hidden; + + -webkit-transform: none; + -moz-transform: none; + -ms-transform: none; + -o-transform: none; + transform: none; + + #nts-link img { + width: 30px; + } + } + + #aphex-gif-container { + position: relative; + width: 100%; + display: block; + overflow: auto; + + top: 0; + + padding-top: 0; + + -webkit-transform: none; + -moz-transform: none; + -ms-transform: none; + -o-transform: none; + transform: none; + + img { + width: 250px; + } + } +} +