How to create an animated old letter

How to create an animated old letter

6 67860
An old letter

How to create an animated old letter

Today we will create an animated old letter. In this letter, we will use an animated pen. When the pen dries out – we’ll dip it in the ink. And even more, we add the feature to emulate the errors that will be erased during typing. Now let’s look at the implementation.

Live Demo

Step 1. HTML

As the first step, we should prepare basic html file with our letter:


    <div id="letter"></div>
    <img id="inkwell1" src="inkwell1.gif" alt="inkwell1" />
    <img id="inkwell2" src="inkwell2.gif" alt="inkwell2" />
    <div id="letter_src">
A man named Grant once foi|und a box of old Papers in his dwelling||||||||house. Grant didn't like old things. So he burned most of the papers. But one of these papers was a letter. He read it. A well-known writer had written it.<br><br>
'About a million|||||||hundred years ago nobody know about him|||this writer,' thought Grant. 'Nobody read his books. But now everybody reads him. Some people like to buy old letters. I can get a lot of money for this letter.'<br><br>
But the letter looked dirty. So Grant decided to wash |||||clean it. He worked hard and soon the letter looked new. Grant was not|||||||was very happy.<br><br>
He took the letter to a shop in London where they bought and sold old papers. 'I want to sell this letter,' Grant said to the man in shop. 'It is a well-known writer's letter. How much will you give me for it?'<br><br>
The man looked at the letter for a long time. 'I'll give you two pounds for it,' he said at last.<br><br>
'Only two pounds!' said Grant. 'But people pay ten pounds for old letters. And I have even cleaned it.'<br><br>
'I can see that,' said the man. 'That's the mistake. People who buy old papers like dirty papers more than clean papers.'<br><br>

There are a letter source (which will be hidden), an empty container for future letter, and 2 fixed images (to display an ink and dipping pen in the ink.

Step 2. CSS

Before we start preparing the main JavaScript code, let’s customize our design:


body {
    background: url('bg.jpg') no-repeat center center fixed;
   -webkit-background-size: cover;
   -moz-background-size: cover;
   -o-background-size: cover;
   background-size: cover;
#inkwell1 {
    bottom: 100px;
    left: 140px;
    position: fixed;
#inkwell2 {
    bottom: 100px;
    left: 140px;
    position: fixed;
    visibility: hidden;
#letter {
    font-family: Comic Sans MS;
    font-size: 18px;
    font-weight: bold;
    margin: 50px auto;
    position: relative;
    width: 75%;
#letter_src {
    display: none;

As you can see – both ink images are fixed, and letter source is hidden by default.

Step 3. JavaScript

Now we are ready to the main javascript code:


window.onload = function(){
    // public variables
    var vLetter = document.getElementById('letter');
    var iSpeedInk = 5;
    // other variables
    var sText = document.getElementById('letter_src').innerHTML;
    var iCurChar = 0;
    var sChars = '<span>';
    var iCurInk = 0;
    var sCurCaret = '';
    var sCaret = "&nbsp;<img src='pen.gif' style='position:absolute' />";
    var doStep = function () {
        // current char
        var sChar = sText.charAt(iCurChar);
        // default char delay
        var iDelay = 32;
        if (sChar == '') {
            sCurCaret = '';
        } else if (sChar == '|') { // we use | symbol to emulate 'error' symbol
            sChar = '';
            sChars = sChars.substring(0, sChars.length-1);
            iDelay = 64;
        } else if (sChar == '<') { // pass tags
            var iPos = sText.indexOf('>', iCurChar);
            sChar = sText.substring(iCurChar, iPos + 1);
            iCurChar = iPos;
        } else if (sChar == '&') { // pass html entities
            var iPos = sText.indexOf(';', iCurChar);
            sChar = sText.substring(iCurChar, iPos + 1);
            iCurChar = iPos;
        } else if (sChar == '.') { // custom delay in case of . symbol
            iDelay = 300;
        } else if (sChar == ',') { // custom delay in case of , symbol
            iDelay = 100;
        } else if (sChar == ' ') { // custom delay in case of space symbol
            iDelay = 32;
        } else if (iCurChar > 5) {
            sCurCaret = sCaret;
        // expenditure of ink
        if (sChar == ' ') {
            iCurInk += iSpeedInk;
            sChar = '</span><span style="color:RGB(' + (iCurInk) + ',' + (iCurInk) + ',' + (iCurInk) + ')">' + sChar;
        if (document.getElementById('inkwell2').style.visibility == 'visible') {
            sCurCaret = sCaret;
            document.getElementById('inkwell2').style.visibility = 'hidden';
            sChar = '</span><span style="color:RGB(0,0,0)">' + sChar;
        // refresh Ink
        if (iCurInk > 160) {
            iCurInk = 0;
            document.getElementById('inkwell2').style.visibility = 'visible';
            iDelay = 1000;
            sCurCaret = '';
        // add current char to chars
        sChars += sChar;
        // hide the caret at the end of the letter
        if (iCurChar == sText.length - 1)
            sCurCaret = '';
        // update letter with new chars
        vLetter.innerHTML = sChars + sCurCaret;
        // goto next char
        // next step
        if (iCurChar < sText.length) {
            setTimeout(doStep, 20 + iDelay);

The main idea – to produce all the symbols of the letter one by one. Depending on a current character we can set different delays and simulate errors. In order to simulate ‘the expenditure of ink’ – we check for space symbol, in the result – each word has own color (gray gradation). When this color is pretty white – we ‘dip’ it into our ‘inkwell’.

Live Demo


download package



I hope that everything is clean in today’s tutorial. If you have any suggestions about further ideas for articles – you are welcome to share them with us. Good luck in your work!


Understanding Closures

0 24600


  1. This is handy code that can also be used as an intro to a website…thanks for the great job on this piece of software…can this be connected to a mysql db that can provide the data? IF so, please let me know…

    • Hello jmk,
      Of course you can, why do you ask it? :-)
      But in this case you have to change JS code a bit, as you can see, at the line 7 script obtains inner html of letter source element,
      so, try to assign your custom code (which you take from database) before this moment, and everything will be ok

  2. I’m a bid late to see this article but it gave me good idea for website to make an about page.
    Can you use or modify this code to also let it drawn the website layout itself?

    ==> by this i mean for example: first drawn a box than put picture in box, than write some text, than draw an art gallery?

  3. Good evening Andrew

    a beautifull code,i have tested it,it works nicely on mosilla firfox and other browsers
    but in internet Explorerr(8),the pen picture do not appear,
    can you please give a solution for that,thanks so much.

    I really liked your code and it is fully customizable .


Leave a Reply