jQuery: miniMap

based upon: http://samcroft.co.uk/mini-map/ helper: http://draft.local-box.org/2010-04-24/

HTML

<div id="state"></div>

<div id="wrapper">
    <header>
        <h1>Heading 1</h1>
    </header>
    <nav>
        <ul>
            <li>1st</li>
            <li>2nd</li>
            <li>3rd</li>
        </ul>
    </nav>
    <section>
        <h1>Heading 2</h1>
        <p>Just a short line of text, for better interpretation.</p>
        <p>b</p>
    </section>
    <article>
        <h1>Heading 1</h1>
        <h2>Heading 2</h2>
        <p>Just a short line of text, for better interpretation.</p>
        <p>a</p>
        <ul>
            <li>1st</li>
            <li>2nd</li>
            <li>3rd</li>
            <li>4th</li>
        </ul>
        <footer>Footer</footer>
    </article>
    <aside>
        <ol>
            <li>1st</li>
            <li>2nd</li>
        </ol>
    </aside>
    <footer>
        <p>Just a short line of text, for better interpretation.</p>
    </footer>
    <header>
        <h1>Heading 1</h1>
    </header>
    <nav>
        <ul>
            <li>1st</li>
            <li>2nd</li>
            <li>3rd</li>
        </ul>
    </nav>
    <section>
        <h1>Heading 2</h1>
        <p>Just a short line of text, for better interpretation.</p>
        <p>b</p>
    </section>
    <article>
        <h1>Heading 1</h1>
        <h2>Heading 2</h2>
        <p>Just a short line of text, for better interpretation.</p>
        <p>a</p>
        <ul>
            <li>1st</li>
            <li>2nd</li>
            <li>3rd</li>
            <li>4th</li>
        </ul>
        <footer>Footer</footer>
    </article>
    <aside>
        <ol>
            <li>1st</li>
            <li>2nd</li>
        </ol>
    </aside>
    <footer>
        <p>Just a short line of text, for better interpretation.</p>
    </footer>
    <header>
        <h1>Heading 1</h1>
    </header>
    <nav>
        <ul>
            <li>1st</li>
            <li>2nd</li>
            <li>3rd</li>
        </ul>
    </nav>
    <section>
        <h1>Heading 2</h1>
        <p>Just a short line of text, for...

CSS

#state {position:fixed; top:0; left:0}

#miniMap {
    position: fixed;
    z-index: 21;
    top: 0;
    right: 0;
    width: 60px;
    opacity: 1;
    -webkit-transition: opacity .5s ease;
       -moz-transition: opacity .5s ease;
         -o-transition: opacity .5s ease;
            transition: opacity .5s ease;
}
#miniMap.hidden {
    opacity: 1;
}
#miniMap #viewport {
    width: 60px;
    margin: -1px 0 0 0;
    z-index: 22;
    position: absolute;
    background: #333;
    opacity: 0.8
}
#miniMap div {
    position: absolute;
    background: #EAEAEA;
    width: 100%;
}
#miniMap div.h1 {
    background: #666;
}
#miniMap div.h2 {
    background: #999;
}
#miniMap div.h3 {
    background: #CCC;
}
#miniMap div.p {
    background: #F9F9F9;
}
#miniMap div.ul {
    background: #FCC;
}
#miniMap div.ol {
    background: #F60;
}
#miniMap div.figure {
    background: #F4F4F4;
}
#miniMap div.pre {
    background: #0Cf;
}

JavaScript

(function($, window) {
    $.fn.miniMap = function() {
        var miniMap;
        var miniMapViewport;
        var offset;
        var mapIconY;
        var mouseMoved = false;

        var el = this;
        var elPosition = el.offset();

        function init() {
            if (!$('#miniMap').length) {
                var map = document.createElement('div');
                map.id = 'miniMap';
                el.after(map);
                miniMap = $(map);
                miniMap.addClass('hidden');

                var viewport = document.createElement('div');
                viewport.id = 'viewport';
                miniMap.append(viewport);
            }

            els = el.children().children();

            els.each(function(i, el) {
                var articleCoords = $(this).offset();
                var mapIconHeight = $(this).height() / 8;
                var mapIconMarginTop = parseInt($(this).css('marginTop'), 10) / 8;
                var mapIconMarginBottom = parseInt($(this).css('marginBottom'), 10) / 8;

                if (i === 0) {
                    mapIconY = (articleCoords.top / 8) - mapIconMarginTop;
                } else {
                    mapIconY = (articleCoords.top / 8) + offset;
                }

                offset = mapIconMarginTop + mapIconMarginBottom;

                var mapIcon = $(document.createElement('div'));
                mapIcon.css({
                    height: mapIconHeight,
                    marginTop: mapIconMarginTop,
                    marginBottom: mapIconMarginBottom,
                    top: mapIconY
                }).addClass(el.tagName.toLowerCase());

                mapIcon.appendTo(miniMap);
            });

            mapView();
        }

        function mapView() {
            var miniMapHeight = 0;
            $.each(miniMap.find('div'), function() {
                miniMapHeight += parseInt($(this).outerHeight(true), 10);
            });
            //miniMapHeight -= 20;
       ...