Edit in JSFiddle


              
<style>
        @-o-viewport {
            width: device-width;
            zoom: 1;
            user-zoom: fixed;
        }
        @font-face {
            /* LCD font by Samuel Reynolds */
            /* License: http://www.spinwardstars.com/scrfonts/aaastdlicense.html */
            font-family: 'LCD';
            src: url('http://media.shinydemos.com/inbox-attack/fonts/lcd.eot') format('embedded-opentype'),
                 url('http://media.shinydemos.com/inbox-attack/fonts/lcd.woff') format('woff'),
                 url('http://media.shinydemos.com/inbox-attack/fonts/lcd.ttf') format('truetype'),
                 url('http://media.shinydemos.com/inbox-attack/fonts/lcd.svg#LCD') format('svg');
        }
        #txt_time, #txt_score, #txt_result {
            font-family: 'LCD', monospace;
        }
    </style>
    <script type="text/javascript"><![CDATA[
    function launch() {
        /*
         * Configurable options
         */
        var TOTAL_TIME = 20; // Total time (progress countdown) in seconds
        var DROP_TIME = 300; // Final mail drop time - lower is more difficult
        
        /*
         * Non-configurable stuff from here on
         */
         // Cache global variables for speed         
        var win = window;
        var doc = document;
        
        // Resize game to fit screen
        var default_width = 980;
        var default_height = 630;
        var case_ratio = default_width / default_height; // Optimal size ratio is roughly 1.55:1
        var svg = doc.getElementsByTagName('svg')[0];
        var screen_width = win.innerWidth;
        var screen_height = win.innerHeight;
        var case_width, case_height;
        
        // Ensure game is in landscape format
        var screen_ratio = screen_width / screen_height;
        if (case_ratio > screen_ratio) {
            case_width = screen_width;
            case_height = case_width / case_ratio;
        } else {
            case_width = screen_width;
            case_height = screen_height;
        }
        
        var scalex = case_width / default_width;
        var scaley = case_height / default_height;
    
        svg.setAttribute('width', case_width);
        svg.setAttribute('height', case_height);
        
        // DOM elements - gotta catch 'em all
        var progress = doc.getElementById('progress');
        var lbl_reset = doc.getElementById('lbl_reset');
        var lbl_inbox = doc.getElementById('lbl_inbox');
        var lbl_attack = doc.getElementById('lbl_attack');
        var txt_time = doc.getElementById('txt_time');
        var txt_score = doc.getElementById('txt_score');
        var txt_result = doc.getElementById('txt_result');
        var btn_reset = doc.getElementById('btn_reset');
        var btn_left = doc.getElementById('btn_left');
        var btn_right = doc.getElementById('btn_right');
        var inbox = doc.getElementById('inbox');
        var head = doc.getElementById('head');
        var btn_left = doc.getElementById('btn_left');
        var btn_right = doc.getElementById('btn_right');
        var btn_surround = doc.getElementById('button_surround');
        var users = [];
        for (var i = 0; i < 5; i++) {
            users[i] = doc.getElementById('user' + i);
        }
        // Other global constants
        var SVGNS = "http://www.w3.org/2000/svg";
        var XLINKNS = "http://www.w3.org/1999/xlink";
        var ENV_GAP = 25;
        var ENV_HEIGHT = 28;
        var MAIL_STEP = ENV_GAP + ENV_HEIGHT;
        var HAND_POS = 356;
        var TICK_RATE = 100; // Time (ms) between each iteration of tick function
        var TICK_GAP = case_width / 163.333;
        var TICK_X = case_width / 2.841;
        var TICK_Y = case_height / 3.841;
        var PROGRESS_LENGTH = 50; // Initial length of the progress bar in ticks
        var CHANNELS = [305, 395, 535, 625];
        //var CHANNELS = [case_width / 3.213, case_width / 2.481, case_width / 1.832, case_width / 1.568];
        var SUPPORTS_TOUCH = 'createTouch' in doc;
        // Global variables
        var last_channel;
        // Global counters
        var count;
        var count_time;
        var count_progress;
        var count_caught;
        var count_mails;
        var total_mails;
        // Global objects
        var face = { // Paths for facial expressions
            'panic' : 'm 0,0 C -5,-3 -13,3 -18,7 c -2,-6 -16,-2 -6,4 -2,2 -2,2 -5,5 14,3 2,23 -5,10 -3,5 -2,13 1,16 8,9 19,11 29,-6 12,-17 17,-34 4,-36 z',
            'big-smile' : 'm 0,0 c -5,-3 -13,3 -18,7 -2,-6 -16,-2 -6,4 -2,2 -2,2 -5,5 7,1 6,5 11,5 -4,2 -7,7 -16,5 -3,5 -2,13 1,16 8,9 19,11 29,-6 12,-17 17,-34 4,-36 z',
            'smile' : 'm 0,0 c -5,-3 -13,3 -18,7 -2,-6 -16,-2 -6,4 -2,2 -2,2 -5,5 7,1 6,5 9,8 -4,2 -5,4 -14,2 -3,5 -2,13 1,16 8,9 19,11 29,-6 12,-17 17,-34 4,-36 z',
            'so-so' : 'm 0,0 c -5,-3 -13,3 -18,7 -2,-6 -16,-2 -6,4 -2,2 -2,2 -5,5 7,1 5,8 8,11 -4,2 -4,0 -13,-1 -3,5 -2,13 1,16 8,9 19,11 29,-6 12,-17 17,-34 4,-36 z',
            'sad' : 'm 0,0 c -5,-3 -13,3 -18,7 -2,-6 -16,-2 -6,4 -2,2 -2,2 -5,5 7,1 3,10 6,14 -4,-1 -2,-3 -11,-4 -3,5 -2,13 1,16 8,9 19,11 29,-6 12,-17 17,-34 4,-36 z'
        };
        
        // Position labels
        lbl_reset.setAttributeNS(null, 'font-size', 22 * scalex);
        lbl_reset.setAttributeNS(null, 'x', 112 * scalex);
        lbl_reset.setAttributeNS(null, 'y', 168 * scaley);
        
        lbl_inbox.setAttributeNS(null, 'font-size', 30 * scalex);
        lbl_inbox.setAttributeNS(null, 'x', 782 * scalex);
        lbl_inbox.setAttributeNS(null, 'y', 130 * scaley);
        
        lbl_attack.setAttributeNS(null, 'font-size', 30 * scalex);
        lbl_attack.setAttributeNS(null, 'x', 774 * scalex);
        lbl_attack.setAttributeNS(null, 'y', 176 * scaley);
        
        txt_time.setAttributeNS(null, 'font-size', 22 * scalex);
        txt_time.setAttributeNS(null, 'x', 300 * scalex);
        txt_time.setAttributeNS(null, 'y', 183 * scaley);
        
        txt_score.setAttributeNS(null, 'font-size', 22 * scalex);
        txt_score.setAttributeNS(null, 'x', 656 * scalex);
        txt_score.setAttributeNS(null, 'y', 183 * scaley);
        
        txt_result.setAttributeNS(null, 'font-size', 22 * scalex);
        txt_result.setAttributeNS(null, 'x', 466 * scalex);
        txt_result.setAttributeNS(null, 'y', 230 * scaley);

        // Make the buttons large on small screens
        if (screen_width < 360 ) {
            btn_left.setAttribute('r', '10%');
            btn_left.setAttribute('stroke-width', '0.2%');
            btn_right.setAttribute('r', '10%');
            btn_right.setAttribute('stroke-width', '0.2%');
            btn_surround.setAttribute('r', '11.5%');
        }
        
        /*
         * Reset variables to re-start game
         */
        function doReset() {
            count = 1;
            count_time = TOTAL_TIME;
            count_progress = PROGRESS_LENGTH;
            count_caught = 0;
            count_mails = 0;
            total_mails = 0;
            txt_score.textContent = count_caught;
            txt_time.textContent = count_time;
            txt_result.textContent = '';
            head.setAttributeNS(null, 'd', face['panic']);
            user.resize();
            user.set(1);
            progress_bar.reset();
        }
        
        /*
         * User class
         */
        function User() {
            var channel_id;
            
            /*
             * Move the user left or right
             */
            this.move = function(direction) {
                if (direction === 'left' && this.channel_id > 0) {
                    this.channel_id -= 1;
                    this.set(this.channel_id);
                } else if (direction === 'right' && this.channel_id < 3) {
                    this.channel_id += 1;
                    this.set(this.channel_id);
                }
            };
            
            /*
             * Display the user in a particular position (channel)
             */
            this.set = function(channel_id) {
                this.channel_id = channel_id;
                for (var i = 0, len = users.length; i < len; i++) {
                    if (i === this.channel_id) {
                        users[i].setAttributeNS(null, 'opacity', 1);
                    } else {
                        users[i].setAttributeNS(null, 'opacity', 0);
                    }
                }
            };
            
            /*
             * Resize and move the user based on the case size
             */
            this.resize = function() {
                var x = case_width / 3.37;
                var y = case_height / 2.06;
                for (var i = 0, len = users.length; i < len; i++) {
                    users[i].setAttributeNS(null, 'transform', 'translate(' + x + ', ' + y + ') scale(' + scalex + ', ' + scaley + ')');
                }
            };
        }
        
        /*
         * Actions for clicking direction buttons
         */
        function doButtonPress(event, direction) {
            if (direction === 'left') {
                btn_left.setAttributeNS(null, 'fill', 'url(#btn_rubber_pressed)');
                btn_left.setAttributeNS(null, 'aria-pressed', 'true');
            } else {
                btn_right.setAttributeNS(null, 'fill', 'url(#btn_rubber_pressed)');
                btn_right.setAttributeNS(null, 'aria-pressed', 'true');
            }
            user.move(direction);
        }
        function doButtonRelease(event, direction) {
            if (direction === 'left') {
                btn_left.setAttributeNS(null, 'fill', 'url(#btn_rubber)');
                btn_left.setAttributeNS(null, 'aria-pressed', 'false');
            } else {
                btn_right.setAttributeNS(null, 'fill', 'url(#btn_rubber)');
                btn_right.setAttributeNS(null, 'aria-pressed', 'false');
            }
        }
        
        /*
         * Actions for clicking reset (reload) button
         */
        function doResetPress(event) {
            btn_reset.setAttributeNS(null, 'fill', 'url(#btn_small_pressed)');
            btn_reset.setAttributeNS(null, 'aria-pressed', 'true');
        }
        function doResetRelease(event) {
            btn_reset.setAttributeNS(null, 'fill', 'url(#btn_small_pressed)');
            btn_reset.setAttributeNS(null, 'aria-pressed', 'false');
            win.location = win.location.href;
        }
        
        /*
         * Add event listeners. Doing it this way to make it cross-browser as easily as possible.
         * UPDATE (26/06/2010): Added support for touchscreen devices.
         * Hat tip for touch support to http://mir.aculo.us/2010/06/04/making-an-ipad-html5-app-making-it-really-fast/
         */
        var mouse_down = (SUPPORTS_TOUCH ? 'ontouchstart' : 'onmousedown');
        var mouse_up = (SUPPORTS_TOUCH ? 'ontouchend' : 'onmouseup');
        btn_left[mouse_down] = function(event) {
            doButtonPress(event, 'left');
        };
        btn_left[mouse_up] = function(event) {
            doButtonRelease(event, 'left');
        };		
        btn_right[mouse_down] = function(event) {
            doButtonPress(event, 'right');
        };
        btn_right[mouse_up] = function(event) {
            doButtonRelease(event, 'right');
        };
        btn_reset[mouse_down] = function(event) {
            doResetPress(event);
        };
        btn_reset[mouse_up] = function(event) {
            doResetRelease(event);
        };
        
        /*
         * Enable keyboard use: Arrow keys or [Z] and [X], [space] or [up] for reset.
         */
        doc.onkeydown = function(event) {
            var keyCode = (win.event) ? win.event.keyCode : event.which;
            
            switch (keyCode) {
                case 37: case 90: case 65: case 97: case 44: case 49:
                    doButtonPress(event, 'left');
                break;
                case 39: case 88: case 83: case 115: case 46: case 50:
                    doButtonPress(event, 'right');
                break;
                case 32: case 27: case 81: case 38:
                    doResetPress(event);
                break;
            }
        };
        doc.onkeyup = function(event) {
            var keyCode = (win.event) ? win.event.keyCode : event.which;
            
            switch (keyCode) {
                case 37: case 90: case 65: case 97: case 44: case 49:
                    doButtonRelease(event, 'left');
                break;
                case 39: case 88: case 83: case 115: case 46: case 50:
                    doButtonRelease(event, 'right');
                break;
                case 32: case 27: case 81: case 38:
                    doResetRelease(event);
                break;
            }
        };
        
        /*
         * Show the user's score and a facial expression to match
         */
        function showResult(count_caught, count_mails) {
            var result = count_caught / count_mails;
            
            if (result > 0.75) {
                head.setAttributeNS(null, 'd', face['big-smile']);
                if (result === 1) {
                    user.set(4);
                }
            } else if (result > 0.5) {
                head.setAttributeNS(null, 'd', face['smile']);
            } else if (result > 0.25) {
                head.setAttributeNS(null, 'd', face['so-so']);
            } else {
                head.setAttributeNS(null, 'd', face['sad']);
            }
            
            txt_result.textContent = count_caught + '/' + count_mails;
        }
        
        /*
         * Mail class
         */
        function Mail(channel_id) {
            // Create new #envelope element when mail object is created
            var new_mail = doc.createElementNS(SVGNS, 'use');
            new_mail.setAttributeNS(null,'transform', 'scale(' + scalex + ', ' + scaley + ')');
            new_mail.setAttributeNS(null,'x', CHANNELS[channel_id]);
            new_mail.setAttributeNS(null, 'y', HAND_POS - ((MAIL_STEP * 4) - (ENV_GAP * 2)));
            new_mail.setAttributeNS(XLINKNS, 'href', '#envelope');
            inbox.appendChild(new_mail);
            
            /*
             * Show mail pouring down. Just like real life.
             */
            this.animate = function(sec) {
                var status, mail_pos;
                var drop = setInterval(function() {
                    mail_pos = new_mail.getAttributeNS(null, 'y') * 1; // Multiplying by 1 is more efficient than parseInt()
                    if ((mail_pos + MAIL_STEP) < HAND_POS) {
                        // Draw dropping mail
                        new_mail.setAttributeNS(null, 'y', mail_pos + MAIL_STEP);
                    } else if (!status) {
                        count_mails += 1;
                        // Decide whether the mail has been caught
                        if (channel_id === user.channel_id) {
                            // Caught - show open envelope
                            new_mail.setAttributeNS(XLINKNS, 'href', '#envelope_open');
                            status = 'caught';
                            count_caught += 1;
                            txt_score.textContent = count_caught;
                        } else {
                            // Missed - show black envelope
                         new_mail.setAttributeNS(XLINKNS, 'href', '#envelope_inverse');
                            new_mail.setAttributeNS(null, 'y', mail_pos + (MAIL_STEP));
                            status = 'missed';
                        }
                    } else {
                        // Stop drawing mail
                        inbox.removeChild(new_mail);
                        clearInterval(drop);
                    }
                    // If all mails have dropped, show the result
                    if (count_mails === total_mails) {
                        showResult(count_caught, count_mails);
                    }
                }, sec);
            };
        }
        
        /*
         * The main timer function
         */
        function tick() {
            var mail, rnd_channel, speed;
            var tick_sec = 1000 / TICK_RATE;
            
            // There's probably a better way to do this...
            if (count % (500 / TICK_RATE) === 0) {
                if (count % tick_sec === 0) {
                    // Per-second tasks
                    count_time -= 1;
                    if (count_time >= 0) {
                        // Show time remaining on screen
                        txt_time.textContent = count_time;
                    } else {
                        // Time's up! Stop timer but let remaining mails continue.
                        clearInterval(timer);
                        return;
                    }
                }
                
                //if (count > 110 || (count % tick_sec === 0)) {
                if (count % tick_sec === 0) {
                    // Drop mail, making sure it's not in the same channel as the previous mail
                    do {
                        rnd_channel = (Math.random() * 4) | 0; // Generate a random number between 0 and 3. Bitwise operator for efficiency
                    } while (rnd_channel === last_channel);
                    mail = new Mail(rnd_channel);
                    total_mails++;
                    // Make speed gradually increase based on progress
                    speed = DROP_TIME + (DROP_TIME * 1 * (count_progress / PROGRESS_LENGTH));
                    mail.animate(speed);
                    last_channel = rnd_channel;
                }
            }
            
            if (count % (((TOTAL_TIME / PROGRESS_LENGTH) * tick_sec)) === 0) {
                if (count_progress > 0) {
                    // Who says progress bars have to count up?
                    progress_bar.reduce();
                }
            }
            
            count += 1;
        }
        
        /*
         * ProgressBar Class
         */
        function ProgressBar() {
            var bar;
            
            /*
             * Reset (draw) the progress bar
             */
            this.reset = function() {
                progress.setAttributeNS(null, 'aria-valuemax', PROGRESS_LENGTH);
            
                for (var i = 0; i < count_progress; i++) {
                    bar = doc.createElementNS(SVGNS, 'use');
                    bar.setAttributeNS(null,'x', (i * TICK_GAP) + TICK_X);
                    bar.setAttributeNS(null,'y', TICK_Y);
                    bar.setAttributeNS(XLINKNS, 'href', '#bar');
                    bar.setAttributeNS(null, 'id', 'bar' + i);
                    progress.appendChild(bar);
                }
            }
            
            /*
             * Remove one line from the progress bar
             */
            this.reduce = function() {
                count_progress -= 1;
                bar = doc.getElementById('bar' + (count_progress));
                progress.removeChild(bar);
                progress.setAttributeNS(null, 'aria-valuenow', count_progress);
            }
        }
        
        var progress_bar = new ProgressBar();
        var user = new User();
        doReset();
        
        // OK, let's get this baby started
        var timer = setInterval(tick, TICK_RATE);
        user.move('right');
    }

    window.onload = launch;
    ]]></script>
    <title>Inbox Attack</title>
    <desc>A progress bar built into an SVG game.
    Use the left and right arrow keys or "Z" and "X" to move.</desc>
    <defs>
        <!-- Case definitions -->
        <linearGradient id="case_grad" x1="0%" y1="0%" x2="0%" y2="50%">
            <stop stop-color="#aa1122" offset="0%"/>
            <stop stop-color="#880000" offset="100%"/>
        </linearGradient>
        <linearGradient id="metal_grad" x1="0%" y1="0%" x2="0%" y2="50%">
            <stop stop-color="#ffffee" offset="0%"/>
            <stop stop-color="#ddccaa" offset="100%"/>
        </linearGradient>
        
        <!-- Progress bar definitions -->
        <line id="bar" x1="0" y1="0" x2="0" y2="2.4%" stroke="#111111" stroke-width="0.5%" stroke-linejoin="round" stroke-linecap="round"/>
        
        <!-- Button definitions -->
        <circle id="button_surround" cx="0" cy="0" r="7.3%" fill="#990000" stroke="#330000" stroke-width="0.2%"/>
        <linearGradient id="btn_rubber" x1="0%" y1="0%" x2="0%" y2="50%">
            <stop stop-color="#ff9999" offset="0%"/>
            <stop stop-color="#cc3333" offset="100%"/>
        </linearGradient>
        <linearGradient id="btn_rubber_pressed" x1="0%" y1="0%" x2="0%" y2="50%">
            <stop stop-color="#ee7777" offset="0%"/>
            <stop stop-color="#bb2222" offset="100%"/>
        </linearGradient>
        <linearGradient id="btn_small" x1="0%" y1="0%" x2="0%" y2="30%">
            <stop stop-color="#eeeeee" offset="0%"/>
            <stop stop-color="#bbbbbb" offset="100%"/>
        </linearGradient>
        <linearGradient id="btn_small_pressed" x1="0%" y1="0%" x2="0%" y2="30%">
            <stop stop-color="#dddddd" offset="0%"/>
            <stop stop-color="#aaaaaa" offset="100%"/>
        </linearGradient>
        
        <!-- Envelope definitions -->
        <path id="envelope" d="m0,0 l0,25 l50,0 l0,-25 l-50,0 l25,12 l25,-12" stroke="#111111" stroke-width="0.4%" stroke-linejoin="round" stroke-linecap="round" fill="none"/>
        <path id="envelope_open" d="m0,0 l0,25 l50,0 l0,-25 l-25,12 l-25,-12 l25,-12 l25,12" stroke="#111111" stroke-width="0.4%" stroke-linejoin="round" stroke-linecap="round" fill="none"/>
        <path id="envelope_inverse" d="m0,0 l0,25 l50,0 l0,-25 l-50,0 l25,12 l25,-12" stroke="#ccddaa" stroke-width="0.4%" stroke-linejoin="round" stroke-linecap="round" fill="#111111"/>
        
        <!-- User definitions -->
        <path id="head" d="m 0,0 C -5,-3 -13,3 -18,7 c -2,-6 -16,-2 -6,4 -2,2 -2,2 -5,5 14,3 2,23 -5,10 -3,5 -2,13 1,16 8,9 19,11 29,-6 12,-17 17,-34 4,-36 z" fill="#111111" stroke="none"/>
        <path id="body" d="m-15,0 l -14,43 c -10,48 68,48 58,0 l -14,-43 c -4,-20 -26,-20 -30,0" fill="#111111" stroke="none"/>
        <path id="hand" d="m 0,0 l 26,0 c 8,0 8,14 0,12 l -26,-6 c -4,0 -4,-7 0,-6 z" fill="#111111" stroke="none"/>
        <path id="foot" d="m0,15 l 35,0 l -26,-26 c -20,-20 -40,26 -10,26" fill="#111111" stroke="none"/>
    </defs>
    <g>
        <title>Case</title>
        <rect id="case" x="0" y="0" width="100%" height="100%" fill="url(#case_grad)" stroke="none"/>
        <rect id="metal" x="3.1%" y="4.8%" width="93.9%" height="90.5%" rx="0.6%" ry="0.9%" fill="url(#metal_grad)" stroke="#330000" stroke-width="0.2%"/>
        <rect id="inset" x="27%" y="20.6%" width="45.9%" height="58.7%" rx="1%" ry="1.6%" fill="#990000" stroke="#330000" stroke-width="0.2%"/>
    </g>
    <g>
        <title>Screen</title>
        <rect id="screen_outer" x="28.1%" y="22.2%" width="43.9%" height="55.6%" rx="1%" ry="1.6%" fill="#333333" stroke="none"/>
        <rect id="screen_inner" x="29.1%" y="23.8%" width="41.8%" height="52.4%" rx="1%" ry="1.6%" fill="#ccddaa" stroke="none"/>
    </g>

    <g>
        <title>Game title: Inbox Attack</title>
        <text id="lbl_inbox" fill="#000000" font-family="monospace">INBOX</text>
        <text id="lbl_attack" fill="#000000" font-family="monospace">ATTACK</text>
    </g>
    <g>
        <title>Reset button</title>
            <rect x="10.7%" y="12.7%" width="7.7%" height="7.9%" rx="2.5%" ry="5%" fill="#990000" stroke="#330000" stroke-width="0.2%"/>
            <rect id="btn_reset" x="11.7%" y="14.3%" width="5.6%" height="4.8%" rx="1.5%" ry="3%" fill="url(#btn_small)" stroke="#330000" stroke-width="0.1%"/>
        <text id="lbl_reset" fill="#000000" font-family="monospace">RESET</text>
    </g>
    <g>
        <title>Left button</title>
        <use x="15.3%" y="70.6%" xlink:href="#button_surround"/>
        <!-- Using <circle> here because mobile Safari can't add events to <use> elements. -->
        <circle id="btn_left" cx="15.3%" cy="70.6%" r="6.1%" fill="url(#btn_rubber)" stroke="#330000" stroke-width="0.1%" role="button"/>
    </g>
    <g>
        <title>Right button</title>
        <use x="84.7%" y="70.6%" xlink:href="#button_surround"/>
        <!-- Using <circle> here because mobile Safari can't add events to <use> elements. -->
        <circle id="btn_right" cx="84.7%" cy="70.6%" r="6.1%" fill="url(#btn_rubber)" stroke="#330000" stroke-width="0.1%" role="button"/>
    </g>

    <g id="time">
        <title>Time remaining</title>
        <text id="txt_time" fill="#111111" font-family="monospace"></text>
    </g>
    <g id="progress" role="progressbar" aria-valuemin="0">
        <title>Progress bar</title>
    </g>
    <g id="score">
        <title>Current score</title>
        <text id="txt_score" fill="#111111" font-family="monospace"></text>
    </g>
    <g id="result">
        <title>Final result</title>
        <text id="txt_result" fill="#111111" font-family="monospace" x="40%" y ="40%">Loading...</text>
    </g>
    <g id="inbox">
        <title>Mail</title>
    </g>

    <g id="user0" opacity="0">
        <title>User (far left)</title>
        <use x="200" y="10" xlink:href="#head"/>
        <use x="200" y="75" transform="rotate(-20, 200, 125)" xlink:href="#body"/>
        <use x="35" y="73" xlink:href="#hand"/>
        <use x="150" y="150" xlink:href="#foot"/>
        <use x="260" y="135" transform="rotate(120, 260, 135)" xlink:href="#foot"/>
    </g>
    <g id="user1" opacity="0">
        <title>User (left)</title>
        <use x="225" y="5" xlink:href="#head"/>
        <use x="200" y="75" xlink:href="#body"/>
        <use x="125" y="73" xlink:href="#hand"/>
        <use x="150" y="150" xlink:href="#foot"/>
        <use x="-250" y="150" transform="matrix(-1 0 0 1 0 0)" xlink:href="#foot"/>
    </g>
    <g id="user2" opacity="0">
        <title>User (right)</title>
        <use x="-175" y="5" transform="matrix(-1 0 0 1 0 0)" xlink:href="#head"/>
        <use x="200" y="75" xlink:href="#body"/>
        <use x="-275" y="73" transform="matrix(-1 0 0 1 0 0)" xlink:href="#hand"/>
        <use x="150" y="150" xlink:href="#foot"/>
        <use x="-250" y="150" transform="matrix(-1 0 0 1 0 0)" xlink:href="#foot"/>
    </g>
    <g id="user3" opacity="0">
        <title>User (far right)</title>
        <use x="-200" y="10" transform="matrix(-1 0 0 1 0 0)" xlink:href="#head"/>
        <use x="200" y="75" transform="rotate(20, 200, 125)" xlink:href="#body"/>
        <use x="-365" y="73" transform="matrix(-1 0 0 1 0 0)" xlink:href="#hand"/>
        <use x="140" y="135" transform="rotate(14, 140, 135)" xlink:href="#foot"/>
        <use x="-250" y="150" transform="matrix(-1 0 0 1 0 0)" xlink:href="#foot"/>
    </g>
    <g id="user4" opacity="0">
        <title>User (finished)</title>
        <use x="225" y="5" xlink:href="#head"/>
        <use x="200" y="75" xlink:href="#body"/>
        <use x="135" y="-20" transform="rotate(67, 135, -20)" xlink:href="#hand"/>
        <use x="270" y="-20" transform="rotate(97, 270, -20)" xlink:href="#hand"/>
        <use x="150" y="150" xlink:href="#foot"/>
        <use x="-250" y="150" transform="matrix(-1 0 0 1 0 0)" xlink:href="#foot"/>
    </g>
</svg>
<script>
(function(window) {
    var inbox = document.querySelector('.inbox');
    inbox.width = window.innerWidth;
    inbox.height = window.innerHeight;
})(this);
</script>









HTML, BODY {
	height:100%;
	}
BODY {
	margin:0;
	padding:0;
	}
.inbox {
	position:absolute;
	top:0;
	right:0;
	bottom:0;
	left:0;