KOMPOOS.NL

transition - shrink / flip

home » javascripts » transitions » shrink-flip-transition.html

sitemap


voorbeeld transition

image-manipulatie

uitleg procedure shrink/flip

Om het bovenstaande transitie-voorbeeld op jouw website te plaatsen moet je, op de plaats waar je de transitie wilt hebben, de html-regels plaatsen. Als je ook het javascript zo laag als mogelijk in de body-sectie van jouw pagina hebt geplaatst, en de links in het script verwijzen naar geldige adressen (url) van plaatjes, zal de transitie probleemloos werken. Het script heeft duidelijke variabele-namen. Je kan eenvoudig "het gedrag" van het script aanpassen. De code is foutloos volgens de strenge regels van JSLint, en de pagina valideert voor de rest op alle mogelijke manieren.

html code voorbeeld transitie


<p>
    <img id="transitie" src="http://static.dns5.nl/shrink-flip.png" alt="image-manipulatie" width="125" height="185" />
</p>

javascript voor de shrink/flip transitie


<script>
/*global window: false */
var animeer_tijd = 0.5;
var transition_pauze = 4.5;
var transitie_lijst = [
"http://static.dns5.nl/shrink-flip-1.jpg",
"http://static.dns5.nl/shrink-flip-2.jpg", 
"http://static.dns5.nl/shrink-flip-3.jpg",
 "http://static.dns5.nl/shrink-flip-4.jpg"
];
var shrink_flip,
animatie = function() {};
shrink_flip = function(ifrom, flip_string) {
    this.imageLoaded = false;
    this.startOnLoad = false;
    this.is_running = false;
    var init = this.initialize(ifrom, flip_string);
    if (!init) {
        return;
    }
    return this;
};
shrink_flip.prototype.is_klaar = null;
shrink_flip.prototype.de_interval = null;
shrink_flip.prototype.background = null;
shrink_flip.prototype.vertraging = 0.000;
shrink_flip.prototype.roteertijd = 0.500;
shrink_flip.prototype.de_shrink_diepte = 1.000;
shrink_flip.prototype.minimale_resolutie = 125;
shrink_flip.prototype.maximale_resolutie = 125;
shrink_flip.prototype.cursor = 0;
shrink_flip.prototype.transition_herhalen = true;
shrink_flip.prototype.flip_gaat_linksom = true;
shrink_flip.prototype.initialize = function(ifrom, flip_string) {
    this.canvas = document.createElement("div");
    this.canvas.style.position = "relative";
    this.imgBase = new shrink_flip.Image(this.canvas);
    var ebase = this.imgBase.fromElement(ifrom);
    if (!ebase) {
        return;
    }
    this.canvasWidth = ebase.offsetWidth;
    this.canvasHeight = ebase.offsetHeight;
    ebase.parentNode.insertBefore(this.canvas, ebase);
    var flip_lijst;
    if (typeof(flip_string) == "string") {
        flip_lijst = [ebase.src, flip_string];
        this.transition_herhalen = false;
    } else {
        flip_lijst = flip_string;
        this.transition_herhalen = true;
    }
    this.imgBuffer = [];
    var __this = this;
    var __len = flip_lijst.length;
    var trigcheck = function(flip_element) {
        for (var i = 0; i < __len; i++) {
            if (!__this.imgBuffer[i].loaded) {
                return;
            }
        }
        __this.imageLoaded = true;
        if (__this.startOnLoad) {
            __this.startOnLoad = false;
            __this.beginanimatie();
        }
    };
    for (var i = 0; i < flip_lijst.length; i++) {
        this.imgBuffer[i] = new shrink_flip.Image(this.canvas);
        this.imgBuffer[i].onLoad = trigcheck;
        this.imgBuffer[i].fromURL(flip_lijst[i]);
    }
    return true;
};
shrink_flip.appendEvent = function(flip_element, type, func) {
    if (flip_element.addEventListener) {
        return flip_element.addEventListener(type, func, false);
    } else if (flip_element.attachEvent) {
        return flip_element.attachEvent("on" + type, func);
    }
};
shrink_flip.prototype.shrink_en_flip = function() {
    if (this.is_running) {
        return;
    }
    if (this.imageLoaded) {
        this.beginanimatie();
    } else {
        this.startOnLoad = true;
    }
};
shrink_flip.prototype.beginanimatie = function() {
    if (this.background) {
        this.canvas.style.background = this.background;
    }
    var curnext = this.nextCursor(this.cursor);
    this.imgBase.flip_element.style.visibility = "hidden";
    this.rotation = this.flip_gaat_linksom ? 0.0: 1.0;
    if (this.flip_gaat_linksom) {
        this.plaatje_links = this.imgBuffer[this.cursor];
        this.plaatje_rechts = this.imgBuffer[curnext];
    } else {
        this.plaatje_links = this.imgBuffer[curnext];
        this.plaatje_rechts = this.imgBuffer[this.cursor];
    }
    this.richting_transition = this.flip_gaat_linksom;
    this.is_running = true;
    this.timer = new shrink_flip.Timer(this);
    this.timer.start();
};
shrink_flip.prototype.nextCursor = function(cur) {
    if (this.flip_gaat_linksom) {
        cur++;
        cur = cur % this.imgBuffer.length;
    } else {
        cur--;
        if (cur < 0) {
            cur += this.imgBuffer.length;
        }
    }
    return cur;
};
shrink_flip.prototype.dispEdge = function() {
    if (this.timer) {
        if (this.timer.is_running()) {
            this.timer.stop();
        }
        this.timer = null;
    }
    if (!this.is_running) {
        return;
    }
    this.plaatje_links.hideClip(0);
    this.plaatje_rechts.hideClip(0);
    if (this.richting_transition == this.flip_gaat_linksom) {
        this.cursor = this.nextCursor(this.cursor);
    }
    this.richting_transition = null;
    this.imgBase.flip_element.src = this.imgBuffer[this.cursor].flip_element.src;
    this.imgBase.flip_element.style.width = this.canvasWidth + "px";
    this.imgBase.flip_element.style.height = this.canvasHeight + "px";
    this.imgBase.flip_element.style.visibility = "visible";
};
shrink_flip.prototype.volgende_transitie = function() {
    this.dispEdge();
    var __this = this;
    var func = function() {
        if (!__this.is_running) {
            return;
        }
        __this.beginanimatie();
    };
    if (this.de_interval) {
        this.de_interval(this.cursor);
    }
    if (!this.is_running) {
        return;
    }
    setTimeout(func, this.vertraging * 1000);
};
shrink_flip.prototype.finish = function() {
    this.dispEdge();
    this.is_running = false;
    if (this.is_klaar) {
        this.is_klaar(this.cursor);
    }
};
shrink_flip.prototype.loop = function(secs, diff, count) {
    if (!this.is_running) {
        return;
    }
    if (!this.flip_gaat_linksom) {
        diff = -diff;
    }
    this.rotation += diff * 0.001 / this.roteertijd;
    var fincheck = false;
    if (this.rotation > 1.0) {
        this.rotation = 1.0;
        fincheck = true;
    } else if (this.rotation < 0.0) {
        this.rotation = 0.0;
        fincheck = true;
    }
    this.display(this.rotation);
    if (fincheck) {
        if (this.transition_herhalen) {
            this.volgende_transitie();
        } else {
            this.finish();
        }
        return false;
    } else {
        return true;
    }
};
shrink_flip.prototype.display = function(prog) {
    var alpha = (1.0 - 2.0 * prog) / 4.0 * Math.PI;
    var sina = Math.sin(alpha);
    var cosa = Math.cos(alpha);
    var ah = this.de_shrink_diepte / (this.de_shrink_diepte + (cosa + sina));
    var bh = 1;
    var ch = this.de_shrink_diepte / (this.de_shrink_diepte + (cosa - sina));
    var aw = cosa * ah;
    var bw = sina;
    var cw = -cosa * ch;
    var ow = 0;
    if (aw > Math.SQRT1_2) {
        ow = aw - Math.SQRT1_2;
    }
    if (cw < -Math.SQRT1_2) {
        ow = cw + Math.SQRT1_2;
    }
    if (ow) {
        aw -= ow;
        bw -= ow;
        cw -= ow;
    }
    if (aw > bw) {
        this.dispPanel(this.plaatje_rechts, bw, bh, aw, ah);
    } else {
        this.plaatje_rechts.hideClip(0);
    }
    if (cw < bw) {
        this.dispPanel(this.plaatje_links, cw, ch, bw, bh);
    } else {
        this.plaatje_links.hideClip(0);
    }
};
shrink_flip.prototype.dispPanel = function(img, x1, h1, x2, h2) {
    if (x1 > x2) {
        var x0 = x1;
        x1 = x2;
        x2 = x0;
        var h0 = h1;
        h1 = h2;
        h2 = h0;
    }
    var lx = Math.round(Math.SQRT1_2 * this.canvasWidth * (x1 + Math.SQRT1_2));
    var lh = Math.round(this.canvasHeight * h1);
    var ly = Math.round((this.canvasHeight - lh) / 2);
    var rx = Math.round(Math.SQRT1_2 * this.canvasWidth * (x2 + Math.SQRT1_2));
    var rh = Math.round(this.canvasHeight * h2);
    var ry = Math.round((this.canvasHeight - rh) / 2);
    var reso = this.canvasWidth;
    if (ry != ly) {
        reso = Math.round(Math.abs(2.0 * (rx - lx) / (ry - ly)));
        if (reso > this.maximale_resolutie) {
            reso = this.maximale_resolutie;
        }
        if (reso < this.minimale_resolutie) {
            reso = this.minimale_resolutie;
        }
    }
    var ww = rx - lx;
    var clipnum = 0;
    for (var ix = lx; ix < rx; ix += reso) {
        var prog = (ix - lx) / (rx - lx);
        var iy = Math.round(ly + (ry - ly) * prog);
        var ih = Math.round(lh + (rh - lh) * prog);
        var iw = reso;
        if (ix + iw > this.canvasWidth) {
            iw = this.canvasWidth - ix;
        }
        img.dispClip(clipnum, ix, iy, iw, ih, prog, ww);
        clipnum++;
    }
    img.hideClip(clipnum);
};
shrink_flip.Image = function(work) {
    this.plane = null;
    this.work = work;
    this.flip_element = null;
    this.onLoad = null;
    this.clipbuf = [];
    this.loaded = false;
    this.lasthided = null;
    return this;
};
shrink_flip.Image.prototype.getClip = function(num) {
    if (this.clipbuf[num]) {
        return this.clipbuf[num];
    }
    var line = this.flip_element.cloneNode(true);
    line.style.position = "absolute";
    line.style.display = "";
    line.style.visibility = "hidden";
    this.clipbuf[num] = line;
    return line;
};
shrink_flip.Image.prototype.hideClip = function(num) {
    var lastclip = this.clipbuf.length;
    if (this.lasthided !== null) {
        lastclip = this.lasthided;
    }
    for (var i = num; i < lastclip; i++) {
        this.clipbuf[i].style.visibility = "hidden";
    }
    this.lasthided = num;
};
shrink_flip.Image.prototype.dispClip = function(num, left, top, width, height, prog, xcomp) {
    var line = this.getClip(num);
    var offset = Math.round(xcomp * prog);
    var lijn_style = line.style;
    lijn_style.left = (left - offset) + "px";
    lijn_style.width = xcomp + "px";
    lijn_style.top = top + "px";
    lijn_style.height = height + "px";
    lijn_style.visibility = "visible";
    lijn_style.clip = "rect(0px," + (offset + width) + "px," + (height) + "px," + offset + "px)";
    this.work.appendChild(line);
};
shrink_flip.Image.prototype.fromElement = function(flip_element) {
    if (typeof flip_element == "string") {
        flip_element = document.getElementById(flip_element);
    }
    if (!flip_element) {
        return;
    }
    if (flip_element.tagName != "IMG") {
        return;
    }
    this.flip_element = flip_element;
    this.loaded = true;
    return flip_element;
};
shrink_flip.Image.prototype.fromURL = function(url) {
    var flip_element = document.createElement("img");
    flip_element.src = url;
    flip_element.style.visibility = "hidden";
    flip_element.style.position = "absolute";
    this.work.appendChild(flip_element);
    this.checkLoaded(flip_element);
    this.flip_element = flip_element;
    return flip_element;
};
shrink_flip.Image.prototype.checkLoaded = function(orig) {
    var check = orig.cloneNode(true);
    var __this = this;
    var ldfunc = function(e) {
        if (!e && window.event) {
            e = window.event;
        }
        __this.loaded = true;
        check.parentNode.removeChild(check);
        if (__this.onLoad) {
            __this.onLoad();
        }
    };
    shrink_flip.appendEvent(check, "load", ldfunc);
    this.work.appendChild(check);
};
shrink_flip.Timer = function(target) {
    this.target = target;
    this.started = false;
    this.stoped = false;
    this.count = 0;
    var __this = this;
    this.next = function() {
        if (__this.stoped) {
            return;
        }
        var now_time = (new Date()).getTime();
        if (!__this.begin_time) {
            __this.begin_time = now_time;
        }
        if (!__this.prev_time) {
            __this.prev_time = now_time;
        }
        var spent_time = now_time - __this.begin_time;
        var diff_time = now_time - __this.prev_time;
        __this.prev_time = now_time;
        var flag = __this.target.loop(spent_time, diff_time, __this.count++);
        if (flag) {
            setTimeout(__this.next, 1);
        } else {
            __this.stop();
        }
    };
    return this;
};
shrink_flip.Timer.prototype.start = function() {
    this.started = true;
    this.stoped = false;
    this.next();
};
shrink_flip.Timer.prototype.now = function() {
    return (new Date()).getTime();
};
shrink_flip.Timer.prototype.stop = function() {
    this.stoped = true;
};
shrink_flip.Timer.prototype.is_running = function() {
    return (this.started && !this.stoped);
};
var flip_een;
function kb_init() {
    flip_een = new shrink_flip("transitie", transitie_lijst);
    flip_een.roteertijd = animeer_tijd;
    flip_een.vertraging = transition_pauze;
}
function begin_de_transition() {
    if (!flip_een) {
        setTimeout(function() {
            kb_init();
        },
        200);
    }
    setTimeout(function() {
        flip_een.shrink_en_flip();
    },
    200);
}
setTimeout(function(){begin_de_transition();},600);
</script>
Gebruik voor alle voorbeelden op de http://kompoos.nl een valide html5 pagina.