Skip to content

Instantly share code, notes, and snippets.

@emmenko
Created May 9, 2014 07:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emmenko/a32ea421a33e7a08c134 to your computer and use it in GitHub Desktop.
Save emmenko/a32ea421a33e7a08c134 to your computer and use it in GitHub Desktop.
Animated typing terminal prompt
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Animated typing terminal prompt</title>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/stylesheets/main.css" media="screen">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="intro">
<pre class="panel-body output-container">
<span data-bind="html: output"></span>
<span class="cursor"></span>
</pre>
</div>
</div>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<script src="/static/javascripts/intro.js"></script>
</body>
</html>
(($, ko) ->
getPrompt = ->
"""
<span>me@mac:~$ </span>
"""
class MainViewModel
constructor: (@_opts = {}) ->
# Define elems bindings
@output = ko.observable(getPrompt())
###*
* Init Knockout
###
vm = new MainViewModel()
ko.applyBindings(vm)
# All stuff on document ready
$(document).ready ->
messages = [
'Hi, I\'m a terminal prompt.'
'My messages are automatically displayed as someone would be typing on me.'
'Have fun! :)'
]
printMessage = (message, fn) ->
return fn() unless message
c = 0
if message.length > 0
interval = setInterval ->
vm.output(vm.output() + message[c++])
if c is message.length
clearInterval(interval)
fn()
, 80
start = ->
m = 0
writing = false
interval = setInterval ->
unless writing
writing = true
vm.output(vm.output() + '\n' + getPrompt())
printMessage messages[m++], -> writing = false
if m > messages.length
vm.output(vm.output())
clearInterval(interval)
, 200
start()
)(jQuery, ko)
body { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased;
display: block; text-align: left; line-height: 19px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: normal; font-size: 14px; color: #6D778E; margin: 0; padding: 0; padding-top: 70px;
}
.output-container { white-space: pre-line; font-family: 'Courier new'; background-color: #111;
color: #fff; font-weight: bold; margin-bottom: 0;
}
/*
Cursor-like terminal animation
*/
span.cursor {
font-family: monospace; font-size: 1em;
&:after { content:"_"; opacity: 0; -webkit-animation: cursor 1s infinite; }
}
@-moz-keyframes cursor {
0% { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 1; }
90% { opacity: 1; }
100% { opacity: 0; }
}
@-webkit-keyframes cursor {
0% { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 1; }
90% { opacity: 1; }
100% { opacity: 0; }
}
@-o-keyframes cursor {
0% { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 1; }
90% { opacity: 1; }
100% { opacity: 0; }
}
@-ms-keyframes cursor {
0% { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 1; }
90% { opacity: 1; }
100% { opacity: 0; }
}
@keyframes cursor {
0% { opacity: 0; }
40% { opacity: 0; }
50% { opacity: 1; }
90% { opacity: 1; }
100% { opacity: 0; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment