Skip to content

Instantly share code, notes, and snippets.

@superposition
Created July 27, 2018 04:59
Show Gist options
  • Save superposition/3053fdcc401fe4ae984cc6027ab1ae22 to your computer and use it in GitHub Desktop.
Save superposition/3053fdcc401fe4ae984cc6027ab1ae22 to your computer and use it in GitHub Desktop.
Kiosk Event Schedule — A Concept
<main>
<section v-for="(day, index) in schedule">
<header>
Day {{index+1}} &mdash; {{day.date | date}}
</header>
<ul>
<li v-for="slot in day.agenda" v-bind:class="{ current: checkTime(slot.range[0], slot.range[1]) }">
<h3><b>{{slot.display.h}}</b>{{slot.display.m}}{{slot.display.a}}</h3>
<div v-html="slot.desc"></div>
<div><small v-html="slot.location"></small></div>
</li>
<li class="after-hours">
<div>
<b>Day {{index+1}}</b>
<br />Before / After Hours
<br /><small><small>Click the Event Scroller</small></small>
</div>
</li>
</ul>
</section>
</main>
<aside>
<div class="clock">
<h3>{{time}}</h3>
</div>
<div class="control" v-bind:class="{ show: showTimeTraveller }">
<header v-on:click="showTimeTraveller = !showTimeTraveller">
<div><b>Event Scroller</b></div>
<button><span>_</span></button>
</header>
<div>
<p><input type="range" min="0" max="23.9" step="0.1" v-model="now" id="traveler" /></p>
<p>To-do: Multi-day Traversing</p>
</div>
</div>
<h1>Coinvention</h1>
<svg class="logo" viewBox="0 0 300 300">
<path d=""></path>
<path d="M177.832 138.417 C 162.089 155.760,169.908 184.435,192.333 191.598 C 220.200 200.501,244.954 171.302,231.731 145.126 C 230.159 142.014,225.344 135.864,224.868 136.360 C 224.457 136.787,220.000 144.673,220.000 144.974 C 220.000 145.171,220.521 146.057,221.158 146.944 C 229.404 158.421,225.273 174.618,212.513 180.845 C 191.460 191.117,170.367 166.950,183.391 147.478 C 184.305 146.111,185.004 144.878,184.943 144.739 C 184.482 143.671,180.119 136.338,179.945 136.336 C 179.823 136.335,178.872 137.271,177.832 138.417 M219.344 264.250 L 219.333 277.000 220.828 277.000 L 222.323 277.000 222.411 268.046 L 222.500 259.093 231.654 268.713 C 236.688 274.004,240.851 278.333,240.904 278.333 C 240.957 278.333,241.000 272.558,241.000 265.500 L 241.000 252.667 239.500 252.667 L 238.000 252.667 237.996 261.750 L 237.991 270.833 234.903 267.667 C 233.205 265.925,229.012 261.575,225.585 258.000 L 219.355 251.500 219.344 264.250 M322.000 264.333 L 322.000 277.000 323.495 277.000 L 324.989 277.000 325.078 267.992 L 325.167 258.985 334.288 268.576 C 339.305 273.851,343.542 278.217,343.705 278.278 C 343.873 278.341,344.000 272.859,344.000 265.528 L 344.000 252.667 342.339 252.667 L 340.677 252.667 340.589 261.679 L 340.500 270.692 331.500 261.208 C 326.550 255.992,322.387 251.711,322.250 251.695 C 322.112 251.680,322.000 257.367,322.000 264.333 M66.000 252.437 C 53.266 255.346,52.827 273.841,65.412 277.192 C 67.774 277.820,71.216 277.787,73.295 277.116 L 75.000 276.565 75.000 273.140 L 75.000 269.715 73.103 270.858 C 68.374 273.705,62.785 271.013,62.401 265.704 C 61.905 258.847,69.321 255.118,74.250 259.745 L 75.000 260.450 75.000 256.923 L 75.000 253.396 73.454 252.869 C 71.276 252.127,68.150 251.946,66.000 252.437 M93.927 252.324 C 81.719 254.530,79.781 272.189,91.251 276.708 C 100.075 280.183,109.551 274.686,109.955 265.858 C 110.375 256.687,103.220 250.645,93.927 252.324 M295.095 252.799 C 281.361 257.271,284.693 277.455,299.167 277.455 C 315.817 277.455,316.308 252.926,299.667 252.435 C 297.643 252.375,295.993 252.506,295.095 252.799 M119.667 264.833 L 119.667 277.000 122.500 277.000 L 125.333 277.000 125.333 264.833 L 125.333 252.667 122.500 252.667 L 119.667 252.667 119.667 264.833 M136.000 264.833 L 136.000 277.000 138.827 277.000 L 141.654 277.000 141.744 269.457 L 141.833 261.914 148.142 269.457 L 154.451 277.000 157.059 277.000 L 159.667 277.000 159.667 264.833 L 159.667 252.667 156.840 252.667 L 154.013 252.667 153.923 260.237 L 153.833 267.807 147.500 260.246 L 141.167 252.685 138.583 252.676 L 136.000 252.667 136.000 264.833 M167.976 253.417 C 168.137 253.829,170.249 259.342,172.669 265.667 C 175.089 271.992,177.208 277.525,177.377 277.963 C 177.547 278.401,177.757 278.688,177.844 278.600 C 178.049 278.396,187.665 253.249,187.666 252.917 C 187.667 252.477,184.416 252.635,184.250 253.083 C 184.165 253.313,182.700 257.294,180.994 261.930 C 179.289 266.567,177.790 270.242,177.663 270.097 C 177.536 269.952,176.022 265.972,174.299 261.252 L 171.167 252.670 169.425 252.668 C 167.754 252.667,167.695 252.697,167.976 253.417 M196.333 264.833 L 196.333 277.000 202.667 277.000 L 209.000 277.000 209.000 275.667 L 209.000 274.333 204.167 274.333 L 199.333 274.333 199.333 269.833 L 199.333 265.333 204.167 265.333 L 209.000 265.333 209.000 263.833 L 209.000 262.333 204.167 262.333 L 199.333 262.333 199.333 258.833 L 199.333 255.333 204.167 255.333 L 209.000 255.333 209.000 254.000 L 209.000 252.667 202.667 252.667 L 196.333 252.667 196.333 264.833 M249.667 254.000 L 249.667 255.333 252.667 255.333 L 255.667 255.333 255.667 266.167 L 255.667 277.000 257.167 277.000 L 258.667 277.000 258.667 266.167 L 258.667 255.333 261.667 255.333 L 264.667 255.333 264.667 254.000 L 264.667 252.667 257.167 252.667 L 249.667 252.667 249.667 254.000 M273.333 264.833 L 273.333 277.000 274.833 277.000 L 276.333 277.000 276.333 264.833 L 276.333 252.667 274.833 252.667 L 273.333 252.667 273.333 264.833 M302.916 256.001 C 310.287 259.257,310.697 269.590,303.611 273.515 C 299.685 275.690,294.425 274.521,291.627 270.852 C 285.599 262.949,293.906 252.022,302.916 256.001 M99.836 258.288 C 102.658 259.570,104.178 262.320,103.933 265.704 C 103.314 274.263,90.353 274.263,89.734 265.704 C 89.316 259.925,94.715 255.962,99.836 258.288 " transform="translate(159.603449, 185.823334) rotate(180.000000) translate(-159.603449, -185.823334)"></path>
</svg>
</aside>

Kiosk Event Schedule — A Concept

Trying to learn Vue.js... This is a remix of one of my previous pens that we used at work for an internal hackathon. Converted this to Vue.js from AngularJS. Boo! Firefox doesn't like CSS writing-mode yet.

A Pen by adammmanka on CodePen.

License.

((window) => {
let now = moment()
// JSON DATA
let schedule = [
{
date: now,
agenda: [
{range: ['08:00', '08:59'], display: {h:8, m:'', a: 'am'}, location: '', desc: 'Morning Reception'},
{range: ['09:00', '09:10'], display: {h:9, m:'', a: 'am'}, location: '', desc: 'Opening Remarks - The Future Will Be In Blockchain'},
{range: ['09:15', '09:34'], display: {h:9, m:15, a: 'am'}, location: '', desc: ''},
{range: ['09:35', '09:54'], display: {h:9, m:35, a: 'am'}, location: 'Thomas Jay Rush (*MORE TBA*)', desc: 'Fireside Chat: The Value Of Blockchains'},
{range: ['09:55', '10:10'], display: {h:9, m:55, a: 'am'}, location: 'Bryan Dube', desc: 'Building the Infrastructure of Change: Educating and educating the future generation'},
{range: ['10:10', '10:39'], display: {h:10, m:10, a: 'am'}, location: '', desc: 'Community Engagements Within Blockchain Technology'},
{range: ['10:40', '10:59'], display: {h:10, m:40, a: 'am'}, location: 'Simon Manka', desc: 'Careers in Cryptocurrency'},
{range: ['11:00', '11:25'], display: {h:11, m:'', a: 'am'}, location: '', desc: 'Cryptoeconomics - Blockchain governance mechanisms, consensus mechanisms, chain interoperability'},
{range: ['11:30', '11:59'], display: {h:11, m:30, a: 'am'}, location: 'Kevin Owocki', desc: 'Developers Developers Developers: The Job Market in a Blockchain World'},
{range: ['12:00', '12:14'], display: {h:'Noon', m:'', a: '-ish'}, location: '', desc: 'TBA'},
{range: ['12:15', '12:44'], display: {h:12, m:15, a: 'pm'}, location: '', desc: 'Legal - Regulations, Utility vs Equity, ICO vs STO, Decentralized business models and the law'},
{range: ['12:45', '13:39'], display: {h:12, m:45, a: 'pm'}, location: '', desc: 'LUNCH'},
{range: ['13:40', '14:24'], display: {h:1, m:40, a: 'pm'}, location: '', desc: 'ICO/STO Presentation Period'},
{range: ['14:25', '14:45'], display: {h:2, m:25, a: 'pm'}, location: '', desc: 'The Philadelphia Blockchain Community: <br> Discussing Philadelphia’s Blockchain Strengths, Weaknesses, and Future'},
{range: ['14:55', '15:14'], display: {h:2, m:55, a: 'pm'}, location: 'Alexandra Levin Kramer Esq.', desc: ''},
{range: ['15:15', '15:35'], display: {h:3, m:15, a: 'pm'}, location: '', desc: ''},
{range: ['15:40', '15:54'], display: {h:3, m:40, a: 'pm'}, location: 'Ready set crypto, Crypto Love, (*More TBA*)', desc: 'Youtube influencer panel: Their picks, their thoughts and their vision of the Future in Blockchain'},
{range: ['15:55', '16:19'], display: {h:3, m:55, a: 'pm'}, location: '', desc: 'The Great Healthcare & Data Exchange: The implications and social impact of bringing blockchain technology to forefront of healthcare markets.'},
{range: ['16:20', '16:35'], display: {h:4, m:20, a: 'pm'}, location: '', desc: 'TBA'},
{range: ['16:40', '17:59'], display: {h:4, m:40, a: 'pm'}, location: 'Samson Williams', desc: 'Humans - The only customers you’ve got til AIs take over'},
{range: ['17:00', '17:24'], display: {h:5, m:10, a: 'pm'}, location: '', desc: 'TBA'},
{range: ['17:25', '17:40'], display: {h:5, m:25, a: 'pm'}, location: 'Philip Forte and Tyler Wellner', desc: 'Block Venture Coalition'},
{range: ['17:45', '17:59'], display: {h:5, m:45, a: 'pm'}, location: '', desc: 'TBA'},
{range: ['18:00', '18:29'], display: {h:6, m:'', a: 'pm'}, location: '', desc: 'Self Sovereign Identity & Data Privacy- The protection of our data is growing ever more important with the rise of decentralized systems.<br> These experts are working on not letting data become compromised in an open network.'},
{range: ['18:30', '18:49'], display: {h:6, m:30, a: 'pm'}, location: '', desc: 'TBA'},
{range: ['18:50', '19:00'], display: {h:6, m:50, a: 'pm'}, location: '', desc: 'Closing Remarks'}
]
// },
// {
// date: moment(now).add(1, 'day'),
// agenda: [
// {start: 0, end: 859, display: {h:8, m:30, a: 'am'}, location: 'Underscore Coffee Bar', desc: 'Breakfast Club Donuts + Coffee'},
// {start: 900, end: 959, display: {h:9, m:'', a: 'am'}, location: 'Solaris Terminal', desc: 'Aspirin Session Open forum to discuss headaches and pains, Q&A, tools & tricks, etc.'},
// {start: 1000, end: 1159, display: {h:10, m:'', a: 'am'}, location: '', desc: 'Hacking Session 3'},
// {start: 1200, end: 1229, display: {h:'Noon', m:'', a: '-ish'}, location: 'Break Room', desc: 'LUNCH: Taco Tuesday!'},
// {start: 1230, end: 1529, display: {h:12, m:30, a: 'pm'}, location: '', desc: 'Hacking Session 4'},
// {start: 1530, end: 1900, display: {h:3, m:30, a: 'pm'}, location: 'Underscore Coffee Bar', desc: 'Team Check-in'},
// {start: 1901, end: 1959, display: {h:7, m:'', a: 'pm'}, location: 'Hackers Bar & Grill <br /><small>@ Second and Main</small>', desc: 'Dinner!'}
// ]
// },
// {
// date: moment(now).add(2, 'day'),
// agenda: [
// {start: 0, end: 829, display: {h:8, m:30, a: 'am'}, location: 'Underscore Coffee Bar', desc: 'Breakfast Club Donuts + Coffee'},
// {start: 1000, end: 1159, display: {h:10, m:'', a: 'am'}, location: '', desc: 'Hacking Session 5'},
// {start: 1200, end: 1229, display: {h:'Noon', m:'', a: '-ish'}, location: 'Break Room', desc: 'LUNCH: Taco Tuesday!'},
// {start: 1230, end: 1529, display: {h:12, m:30, a: 'pm'}, location: '', desc: 'am Hacking Session 6'},
// {start: 1530, end: 1900, display: {h:3, m:30, a: 'pm'}, location: 'Underscore Coffee Bar', desc: 'Show & Tell Happy Hour'},
// ]
}
]
let timeFromNum = (num, sep, ampm) => {
let hh = parseInt(num)
let mm = Math.round((num-hh) * 60)
sep = sep || ''
return (hh>12&&ampm?hh-12:hh)+sep+('00'+mm).substr(-2)+(ampm?(hh>11?' pm':' am'):'')
}
let numFromTime = (time) => {
let set = time.split(/[.:]/)
let hh = parseInt(set[0])
let mm = set[1] ? parseInt(set[1]) : 0
return parseFloat((hh + mm / 60).toFixed(1))
}
let app = new Vue({
el: 'aside',
data: {
now: numFromTime(moment(now).format('HH:mm')),
time: moment().format('h:mm a'),
showTimeTraveller: false
}
})
let sked = new Vue({
el: 'main',
filters: {
date: function(date) {
return date.format('ddd, MMM D');
}
},
data: {
now: numFromTime(moment(now).format('HH:mm')),
schedule: schedule
},
methods: {
checkTime: function(ts, te) {
return (this.now >= numFromTime(ts) && this.now < numFromTime(te))
}
}
})
let setClockPos = () => {
setTimeout(() => {
let anchor = document.querySelector('.current')
let t = '1em'
if(anchor) {
t = Math.round(anchor.getBoundingClientRect().top) + 'px'
}
document.documentElement.style.setProperty('--y', t)
}, 350)
}
let timeTraveler
let setTime = function() {
let now = moment()
app.now = sked.now = numFromTime(moment(now).format('HH:mm'))
app.time = moment(now).format('h:mm a')
}
let runTimer = () => {
setClockPos()
timeTraveler = setInterval(function() {
setTime()
}, 30000)
}
runTimer()
document.querySelector('#traveler').addEventListener('input', (e) => {
app.time = timeFromNum(e.target.value, ':', true)
sked.now = e.target.value
setClockPos()
clearInterval(timeTraveler)
}, false)
document.querySelector('.control header').addEventListener('click', (e) => {
setTime()
runTimer()
}, false)
let randum = function(min, max) {
return Math.round((Math.random() * min) + (Math.random() * max));
}
let randex = function() {
return '#' + ( '00' + Math.floor( Math.random() * 16777216 ).toString(16) ).substr(-6)
}
let colorizer = () => {
let hex = randex()
let reverseHex = '#' + hex.replace('#', '').split("").reverse().join("")
document.documentElement.style.setProperty('--bg', hex)
document.documentElement.style.setProperty('--accent', reverseHex)
}
let transformer = () => {
document.documentElement.style.setProperty('--transform', 'translate(-50%, -50%) rotate(' + randum(-360, 360) + 'deg)');
}
setTimeout(() => {
colorizer()
}, 1000)
setTimeout(() => {
transformer()
}, 100)
let adventureTime = window.setInterval(function() {
colorizer()
}, 7500);
let partyTime = window.setInterval(function() {
transformer()
}, 12000);
// resize capture
let resizeTimer
window.addEventListener('resize', (e) => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(() => {
setClockPos()
}, 60);
}, false)
})(window)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
@import url('https://fonts.googleapis.com/css?family=News+Cycle');
:root {
--font: 'News Cycle', Helvetica, sans-serif;
--accent: #9ccf5e;
--bg: #403638;
--transform: translate(-50%, -50%);
}
// primary layout
aside {
position: relative;
flex: 1;
order: 1;
}
main {
position: relative;
flex: 1;
order: 2;
overflow: auto;
height: 100vh;
section {
display: flex;
min-height: 100vh;
}
}
svg.logo {
position: absolute;
pointer-event: none;
font-size: 100vmax;
width: 1em;
height: 400px;
top: 50%;
left: 50%;
will-change: transform;
transform: var(--transform);
transition: transform 12000ms ease-in-out;
mix-blend-mode: overlay;
path {
fill: var(--accent);
transition: fill 3000ms linear;
}
}
// schedule listing
main {
background: rgba(#001, .8);
color: #fff;
header {
flex: 0 0 auto;
writing-mode: vertical-rl;
padding: 1em .5em;
color: rgba(#001, .4);
background: #fff;
}
ul {
list-style: none;
margin: 0;
padding: 2rem;
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
li {
position: relative;
transition: font-size 300ms ease-in, opacity 300ms ease-in;
font-size: .5em;
opacity: .2;
line-height: 1.2;
&.current {
font-size: 1em;
opacity: 1;
&::after {
content: '';
position: absolute;
top: 0;
left: -2rem;
transform: translateY(-.5rem);
border: .5em solid;
border-width: 1em 0 1em .625em;
border-color: transparent;
border-left-color: currentColor;
}
~ li {
opacity: .4;
}
+ li {
font-size: .675em;
opacity: .7;
}
}
}
}
h1 {
position: relative;
top: .65em;
left: .65em;
margin: 0;
line-height: 1;
display: inline;
}
h3 {
margin: 0;
text-transform: uppercase;
font-weight: 200;
font-size: 1.325em;
b {
font-weight: 900;
}
}
// playground
.clock {
position: absolute;
font-size: 1em;
top: 1em;
right: 1em;
transform: translate(0, calc(-1.3em + var(--y)));
transition: transform 300ms ease-out;
}
small {
font-size: .75em;
color: var(--accent);
transition: color 3000ms linear;
small {
font-size: .85em;
}
}
// before/after hours
main li.after-hours {
animation: fade-in 1000ms ease-in 80ms forwards;
position: fixed;
font-size: 1.2em;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(#000, .85);
line-height: 1.5;
width: 100vw;
height: 100vh;
display: flex;
opacity: 0;
// z-index: 1;
text-align: center;
align-items: center;
justify-content: center;
}
main li.current ~ li.after-hours {
display: none;
opacity: 0;
}
// multi-day presentation
// main section + section {
// ul {
// box-shadow: 0 1px 0 0 inset;
// }
// header {
// box-shadow: 0 1px 0 0 inset;
// }
// }
// animations
@keyframes fade-in {
100% {opacity: 1;}
}
// demo
.control {
position: absolute;
z-index: 2;
bottom: 0;
right: 0;
font-size: .5em;
background: rgba(#000, .7);
transform: translateY(calc(100% - 2em));
transition: transform 300ms ease-out;
header {
display: flex;
justify-content: space-between;
align-items: center;
text-transform: uppercase;
cursor: pointer;
div {
padding-left: 1em;
}
}
> div {
padding: 1em;
}
p {
margin: 0;
+ p {
margin-top: 1em;
}
}
input[type=range] {
padding: 0;
border: 0;
width: 15em;
vertical-align: middle;
border-radius: 1em;
background: rgba(#fff, 0.3);
font-size: 1rem;
line-height: 1;
appearance: none;
outline: none;
transition: all .3s;
outline-offset: 0;
margin: 0;
&::-webkit-slider-thumb {
appearance: none;
width: 1em;
height: 1em;
border: none;
border-radius: 1em;
background: #E2E4E6;
background-image: none;
transform: scale(2);
transition: all .3s;
}
}
button {
font: inherit;
border: none;
color: inherit;
width: 2em;
height: 2em;
font-size: 1em;
font-weight: 100;
background: rgba(#fff, .4);
outline: none;
display: flex;
align-items: center;
justify-content: center;
line-height: 0;
transform: rotate(180deg);
}
&.show {
transform: translateY(0%);
button {
transform: rotate(0deg);
}
}
}
// boring
*, *::before, *::after {box-sizing: border-box;}
html, body {
background: var(--bg); // fixes chrome 58+ mix-blend-mode bug
}
body {
margin: 0;
min-height: 100vh;
display: flex;
flex-flow: row wrap;
justify-content: center;
overflow: hidden;
font-family: var(--font);
font-size: calc(1em + 1.5vmin);
// background: var(--bg);
transition: background 1500ms linear;
color: #fff;
}
// safari fix
main header {
height: 100%;
}
// firefox fix
main header {
width: 0px;
padding: 1em 1.25em;
line-height: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment