Here is my attempt using HTML/Javascript and the GSAPI animation library. It took me just over an hour to do. The code (86 lines) is included below. I ran it as a browser source in OBS Studio to create the video. Enjoy:
<!DOCTYPE html>
Copyright licence: CC0 [Public Domain]
To the extent possible under law, the creator has waived all
copyright and related or neighboring rights to this HTML file.
-->
<html>
<head>
<title>TTY</title>
<meta charset="UTF-8">
<meta name="description" content="Typewriter text on screen">
<meta name="keywords" content="TTY, typewriter, text animation">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Neil (elusien.co.uk)">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.0/gsap.min.js"></script>
<style>
:root {
--font-size : 40px;
--line-height: 1.0;
}
html, body {background-color: black; width: 100%; height: 100%;}
body * {
margin:0; padding:0; background-color: black;
font-family: 'VT323', monospace;
font-size : var(--font-size);
line-height: var(--line-height);
color: #fff;
text-shadow: 0 0 1px #fff, 0 0 2px #fff, 0 0 3px #0f0, 0 0 4px #0f0;
}
table {border-collapse: collapse;}
pre {height: 1em; display: inline-block; position: relative; overflow: hidden; opacity: 0;}
pre>div {display: block; width: 400em; position: absolute; top: 0; left: 0; height: 1.2em;}
span {display: inline-block; width: 1em; height: 1em;}
</style>
</head>
<body>
<table>
<tbody>
<tr><td><pre id="c0"><div><span class="cursor">></span></div>- In space, no-one can hear you scream.</pre></td></tr>
<tr><td><pre id="c1"><div><span class="cursor">></span></div>- The force is strong with this one.</pre></td></tr>
<tr><td><pre id="c2"><div><span class="cursor">></span></div>- The needs of the many</pre></td></tr>
<tr><td><pre id="c3"><div><span class="cursor">></span></div> outweigh the needs of the few.</pre></td></tr>
<tr><td><pre id="c4"><div><span class="cursor">></span></div>- Open the pod bay doors Hal.</pre></td></tr>
<tr><td><pre id="c5"><div><span class="cursor">></span></div>- <i>I'm sorry, Dave. I'm afraid I can't do that.</i></pre></td></tr>
<tr><td><pre id="c6"><div><span class="cursor">></span></div> </pre></td></tr>
</tbody>
</table>
<script>
function animate_tty(){
var pre = document. getElementsByTagName('PRE');
var nchars = [];
for (let i = 0; i < pre.length; i++) {
nchars[i] = pre[i].innerText.length - 2; // minus 2 is to allow for the cursor plus a hidden char
}
var tl_cursor_blink = gsap.timeline({repeat: -1});
tl_cursor_blink.to(".cursor", {opacity: 0, duration: 0.2, ease: SteppedEase.config(1)})
.to(".cursor", {opacity: 1, duration: 0.2, ease: SteppedEase.config(1)});
var tl_cover_move = gsap.timeline();
tl_cover_move.set("#c0" , {opacity: 1} )
.to ("#c0 div", {x: pre[0].clientWidth, duration: nchars[0]*0.2, ease: SteppedEase.config(nchars[0])})
.set("#c1" , {opacity: 1})
.to ("#c1 div", {x: pre[1].clientWidth, duration: nchars[1]*0.2, ease: SteppedEase.config(nchars[1])}, '>3')
.set("#c2" , {opacity: 1})
.to ("#c2 div", {x: pre[2].clientWidth, duration: nchars[2]*0.2, ease: SteppedEase.config(nchars[2])}, '>3')
.set("#c3" , {opacity: 1})
.to ("#c3 div", {x: pre[3].clientWidth, duration: nchars[3]*0.2, ease: SteppedEase.config(nchars[3])}, '>1')
.set("#c4" , {opacity: 1})
.to ("#c4 div", {x: pre[4].clientWidth, duration: nchars[4]*0.2, ease: SteppedEase.config(nchars[4])}, '>3')
.set("#c5" , {opacity: 1})
.to ("#c5 div", {x: pre[5].clientWidth, duration: nchars[5]*0.2, ease: SteppedEase.config(nchars[4])}, '>3')
.set("#c6" , {opacity: 1});
window.onload = animate_tty;
</script>
</body>
</html>