console
new Vue({
el: '#queue',
data: {
queue: [],
today: new Date(),
oclock: false,
number: 2,
},
computed: {
timeString: function () {
return `${`0${this.today.getHours()}`.slice(-2)} ${`0${this.today.getMinutes()}`.slice(-2)}`;
},
},
methods: {
beforeEnterQueue (item) {
item.style.opacity = 0;
},
enterQueue (item, done) {
Velocity(item, {
opacity: 1,
}, {
duration: 900,
complete: () => {
item.classList.add('swinging');
done();
},
});
},
leaveQueue (item, done) {
item.classList.remove('swinging');
item.style.position = 'absolute';
Velocity(item, {
opacity: 0,
}, {
duration: 333,
complete: done,
});
},
generate (template = 'cc dddd cc') {
this.number = this.number + Math.random() * 20 >> 0;
return {
left: this.number,
symbol: ['↥', '↧'][Math.random() * 7 >> 0],
plate: template.split('').reduce((a, v) => a + (_ => {
switch (v) {
case 'c': return String.fromCharCode(65 + Math.random() * 1e4 % 26 >> 0);
case 'd': return Math.random() * 10 >> 0;
default: return v;
}
})(), ''),
};
},
simulate() {
if (
this.queue.length < 5 && (
this.queue.length === 0 || Math.random() >= 0.5
)
) this.queue.splice(Math.random() * 10, 0, this.generate());
else this.queue.splice(Math.random() * 10, 1);
setTimeout(this.simulate, 4000 + Math.random() * 2e3);
},
},
mounted: function () {
setInterval(() => this.today = new Date(), 1000);
setTimeout(() => {
this.oclock = true;
this.simulate();
}, 600);
},
});
#screen
#reflex
#queue
span#clock(:class="{ oclock }") {{ timeString }}
transition-group(
tag="ul"
:css="false"
@before-enter="beforeEnterQueue"
@enter="enterQueue"
@leave="leaveQueue"
)
li(v-for="(item, index) in queue"
class="queued-item"
:key="item.plate"
:data-index="index"
:data-reverse-index="queue.length - index - 1"
)
.item-content
.plate {{ item.plate }}
.countdown.blinking {{ item.left }}
.symbol {{ item.symbol }}
#title Queue Management Display app made for the local car service. Used Node, Vue, 1C:Enterprise.
html, body {
height: 100%;
}
body {
display: flex;
overflow: hidden;
font-size: 1.44em;
font-family: 'Open Sans', sans-serif;
background: linear-gradient(45deg,
}
position: absolute;
opacity: 0.5;
font-size: 0.5em;
width: 50%;
}
margin-top: 4em;
margin-left: 1em;
margin-right: 1em;
width: 20em;
border: solid
border-left-width: 0.24em;
border-top-left-radius: 0.2em;
border-top-right-radius: 0.2em;
border-bottom: none;
overflow: hidden;
margin-left: auto;
margin-right: auto;
transform: skewY(2deg) scaleX(0.98);
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
transition: all ease 0.33s;
&:hover {
transform: skewY(0.1deg);
border-left-width: 0.12em;
}
}
width: 5em;
height: 0.7em;
position: absolute;
transform: skewY(-5deg) translateX(-1em) translateY(1em);
border-bottom: solid 12em
border-top: solid 6em
z-index: 1;
transition: transform ease 0.33s;
}
transform: skewY(-7deg) translateX(2.3em) translateY(1em);
}
background-color:
min-height: 100%;
border: inset 0.05em
animation: rainbow 20s ease-in-out infinite;
ul {
transform-style: preserve-3d;
perspective: 190vw;
padding-left: 0;
> li.queued-item {
margin-bottom: 0.5em;
transition: transform ease-in 500ms;
width: 100%;
> .item-content {
display: flex;
align-items: baseline;
justify-content: space-between;
padding-left: 1.8em;
padding-right: 1.8em;
}
}
}
}
position: relative;
left: 15%;
top: -2em;
padding: 0.25em 0.33em;
border-radius: 0 0 0.1em 0.1em;
background-color:
color: white;
transition: top ease 1s;
&.oclock {
top: 0;
}
&::after {
content: ":";
position: absolute;
right: 2.567ch;
bottom: .5ch;
animation: blinking 1s ease infinite;
}
}
$swings: 8;
$swinging-degree: 12deg;
.plate {
font-size: 2em;
line-height: 90%;
word-break: break-word;
margin-right: 0.25em;
padding: 0.27em 0.33em;
border-radius: 0.1em;
color:
background-color: white;
text-transform: uppercase;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
animation: swinging 1s * $swings cubic-bezier(0.45, 0.05, 0.55, 0.95);
animation-play-state: paused;
}
.swinging .plate {
animation-play-state: running;
}
@keyframes swinging {
@for $i from 1 through 2 * $swings - 1 {
transform: rotateY($swinging-degree * (2 * $swings - $i) / (2 * $swings - 1) * ($i % 2 * 2 - 1));
}
}
}
.countdown {
font-size: 1.5em;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.12);
color: white;
.symbol {
float: right;
margin-right: -0.67em;
color:
}
}
@keyframes rainbow {
33% { background-color:
67% { background-color:
}
.blinking {
animation: blinking 1s ease 5;
}
@keyframes blinking {
50% { opacity: 0; }
}