Mattias Sundberg

Mattias Sundberg Detta är min alldeles högst personliga blogg där jag skriver om än det ena än det andra. Ibland skriver jag ofta(re) ibland väldigt sällan. Jag skriver delvis säsongsbetonat då jag är ett stort Formel 1-fan och delvis om mitt jobb/hobby som programmerare. Mer om mig hittar du här.

Senaste inläggen

Nyligen kommenterat

Andra sidor

Visa min profil på LinkedIn.com
Bloggportalen.se
Mashit.se

Visar inlägg taggade med Prototype

Bildzoom

Nedan följer en demo på en bildzoomningsfunktion jag gjort åt Ewa i Walla vilken skall användas vid produktbeskrivningarna i deras nya webshop.

Bredd på Zoomfönster Höjd på Zoomfönster

/images/test1.jpg
/images/test5.jpg
 

Och här kommer källkoden

Event.observe(window, 'load', function() {
    var imagelist = new Array();
    if ($('imagezoomcontent'))
        $('imagezoomcontent').oldSrc = $('imagezoomcontent').src;
    $$('.zoomtm').each(function(el) {

        var i = new Image();
        i.src = el.getAttribute("alt");
        imagelist.push(i);
        el.offset = {
        left : 0,
        top : 0
        };
        el.xratio = 0;
        el.yratio = 0;
        el.zoomAreaXRatio = 0;
        el.zoomAreaYRatio = 0;
        el.imageZoomContentWidth = 0;
        el.imageZoomContentHeight = 0;
        el.tmWidth = el.getWidth();
        el.tmHeight = el.getHeight();
        el.offset = $(el.parentNode).cumulativeOffset();
        if (window.getComputedStyle)
            var parentNodeBorder = parseInt($(el.parentNode.parentNode).getStyle("border-top-width"));
        else

            var parentNodeBorder = parseInt($(el.parentNode.parentNode).getStyle("borderWidth"));
        parentNodeBorder = parentNodeBorder ? parentNodeBorder * 2 : 0;
        $(el.parentNode).setStyle( {
        width : el.tmWidth + 'px',
        height : el.tmHeight + 'px',
        top : (($(el.parentNode.parentNode).getHeight() - parentNodeBorder) - $(el.parentNode).getHeight()) / 2 + 'px'

        });
        el.parentNode.onmouseover = function() {
            var x = el.offset.left + el.tmWidth;
            var y = el.offset.top;
            $('imagezoom').setStyle( {
            left : x + 20 + 'px',
            top : y + 'px'

            });
            el.parentNode.appendChild($('zoomarea'));
            $('zoomarea').setStyle( {
                display : 'block'
            });
            $('imagezoomcontent').src = el.getAttribute("alt");
            el.imageZoomWidth = $('zoomview').getWidth();
            el.imageZoomHeight = $('zoomview').getHeight();
        }
        el.parentNode.onmouseout = function() {

            el.xratio = 0;
            el.yratio = 0;
            el.zoomAreaXRatio = 0;
            el.zoomAreaYRatio = 0;
            el.imageZoomContentWidth = 0;
            el.imageZoomContentHeight = 0;
            el.posx = 0;
            el.posy = 0;
            $('imagezoomcontent').src = $('imagezoomcontent').oldSrc;
            $('imagezoomcontent').setStyle( {
            top : 0,
            left : 0

            });
            $('zoomarea').setStyle( {
                display : 'none'
            });
        }
        el.parentNode.onmousemove = function(e) {
            if (el.imageZoomContentWidth < 30) {
                if ($('imagezoomcontent').getWidth() < 30) {
                    return false;
                } else {
                    el.imageZoomContentWidth = $('imagezoomcontent').getWidth();
                    el.imageZoomContentHeight = $('imagezoomcontent').getHeight();
                }
            }
            if (el.xratio == 0) {
                el.xratio = el.imageZoomContentWidth / el.tmWidth;
                el.yratio = el.imageZoomContentHeight / el.tmHeight;
                el.zoomAreaXRatio = el.imageZoomContentWidth / el.imageZoomWidth;
                el.zoomAreaYRatio = el.imageZoomContentHeight / el.imageZoomHeight;
                $('zoomarea').setStyle( {
                width : Math.round(el.tmWidth / el.zoomAreaXRatio) + 'px',
                height : Math.round(el.tmHeight / el.zoomAreaYRatio) + 'px'

                });
                el.zoomAreaHeight = $('zoomarea').getHeight();
                el.zoomAreaWidth = $('zoomarea').getWidth();
            }
            el.posx = (window.event ? window.event.clientX + document.documentElement.scrollLeft : e.pageX);
            el.posy = (window.event ? window.event.clientY + document.documentElement.scrollTop : e.pageY);
            var zx = el.posx - el.cumulativeOffset().left - Math.round((el.tmWidth / el.zoomAreaXRatio) / 2);
            var zy = el.posy - el.cumulativeOffset().top - Math.round((el.tmHeight / el.zoomAreaYRatio) / 2);
            if (zx < 0)
                zx = 0;
            if (zy < 0)
                zy = 0;
            var imzx = (zx * el.xratio);
            var imzy = (zy * el.yratio);
            if (zx > (el.tmWidth - el.zoomAreaWidth))
                zx = el.tmWidth - el.zoomAreaWidth;
            if (zy > (el.tmHeight - el.zoomAreaHeight))
                zy = el.tmHeight - el.zoomAreaHeight;
            if (imzx > el.imageZoomContentWidth - el.imageZoomWidth)
                imzx = el.imageZoomContentWidth - el.imageZoomWidth;
            if (imzy > el.imageZoomContentHeight - el.imageZoomHeight)
                imzy = el.imageZoomContentHeight - el.imageZoomHeight;
            $('imagezoomcontent').setStyle( {
            left : -(imzx) + 'px',
            top : -(imzy) + 'px'

            });
            $('zoomarea').setStyle( {
            left : zx + 'px',
            top : zy + 'px'
            });
        }
    });
});

Till detta behöver man lite CSS

div.thumb {
    height: 110px;

    width: 110px;
    float: left;
    margin-right: 6px;

    border: 1px solid #999;
    background: #fff;
}

.zoomThumb {
    position: relative;
    margin: auto auto;

    width: 0;
    line-height: 0px;
    font-size: 0px;

    border: 1px solid black;
}

#zoomarea {
    width: 30px;

    height: 30px;
    position: absolute;
    display: none;

    background: #fff;
    opacity: 0.4;
    filter: alpha(opacity =   40);

    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
}

#imagezoom {
    border: 1px solid #999;

    width: 200px;
    height: 200px;
    z-index: 10;

    margin-right: 10px;
    float: left;
    background: white;

}

#imagezoomcontent {
    position: absolute;
}

#zoomview {
    position: relative;

    width: 200px;
    height: 200px;
    line-height: 1px;

    font-size: 1px;
    overflow: hidden;
}

Och slutligen lite HTML

<div id="zoomarea"> </div>
<div id="imagezoom">

    <div id="zoomview">
        <img id="imagezoomcontent" src="/images/blank.gif" />

    </div>
</div>
<div class="thumb">
    <div class="zoomThumb">

        <img alt="/images/test1.jpg" class="zoomtm" src="/images/test1_t.jpg" />

    </div>
</div>
<div class="thumb">
    <div class="zoomThumb">

        <img alt="/images/test5.jpg" class="zoomtm" src="/images/test5_t.jpg" />

    </div>
</div>

Prototype speed-up

Sylvain Zimmer has found a way of speeding up the $$-selector in Prototype.
According to Sylvain his code is up to 20 times faster and he has even set up a test page.

Prototype's current code is quite elegant (as always!) but very slow, so I wrote an add-on that makes this function up to 20 times faster in most usual cases (tested on IE6, Firefox 1.5 and Opera).

So if you are using the $$-selector download his alternative code from his site.

Leaner and lighter

Stripped away about 200 lines of Javascript code today. Mostly obsolete stuff that wasn't in use but also some effects like the sortable "modules" in the right column. No need for it really.

The size of the file shrunk to 12Kb. But there's still about 96Kb of Javascript being loaded, Trimpath and Prototype being the largest. I can probably shrink that a lot by using the light version of Prototype but that mean I have to change a lot of the Ajax stuff so we'll se about that one...