KOMPOOS.NL

morphing images

home » javascripts » image-effects » morph-image.html

sitemap


morph image

uitleg morph procedure

Plaats de onderstaande html-code in de body-tag van jouw pagina. Plaats ook het javascript voor de morph-procedure in de body, en wel liefst zo laag als mogelijk. Er staan genoeg variabelen in het script om het morph-effect naar jouw eigen wensen aan te passen. De variabelen hebben duidelijke omschrijvende namen, dus het zou niet zo moeilijk moeten zijn om het één en ander te wijzigen. Het javascript van de morph is foutloos volgens de JSLint norm en de gehele pagina valideert op alle mogelijke manieren.

code voor html (in de body)


<p>
    <img  id="morph_id" src='http://static.dns5.nl/morph.png' alt="morph image" width="147" height="200" />
</p>

morphing script


<script>
/*global window: false */
var morphing = function() {};
morphing.raster = function(de_inhoud, de_source) {
    this.initialized = false;
    this.startOnLoad = false;
    this.started = false;
    this.finished = false;
    this.linebuf = [];
    this.trush = [];
    this.onComplete = null;
    this.initialize(de_inhoud, de_source);
    return this;
};
var morph_object;
function begin_morph_procedure() {
    if (morph_object) {
        morph_object.finish();
    }
    var canvas = document.getElementById('morph_id');
    morph_object = new morphing.raster(canvas);
    morph_object.in_sec_naar_beneden = 1.5;
    morph_object.in_sec_faden = 1;
    morph_object.hoogte_per_lijn = 0.9;
    morph_object.wave_snelheid = 0.3;
    morph_object.wave_hoogte = 0.7;
    morph_object.clip = true;
    morph_object.background = "transparent";
    morph_object.scroll();
}
morphing.raster.prototype.initialize = function(de_inhoud, de_source) {
    if (typeof de_inhoud == "string") {
        de_inhoud = document.getElementById(de_inhoud);
    }
    this.outer = document.createElement("div");
    this.outer.style.position = "relative";
    this.canvas = document.createElement("div");
    this.canvas.style.position = "absolute";
    this.outer.appendChild(this.canvas);
    if (de_source) {
        de_inhoud.appendChild(this.outer);
        this.origineel = document.createElement("img");
        this.origineel.src = de_source;
        this.origineel.style.visibility = "hidden";
        this.outer.appendChild(this.origineel);
        this.getImageSize(this.origineel);
    } else {
        de_inhoud.parentNode.insertBefore(this.outer, de_inhoud);
        this.origineel = de_inhoud;
        this.origineel.style.visibility = "hidden";
        this.canvasWidth = this.origineel.offsetWidth;
        this.canvasHeight = this.origineel.offsetHeight;
        this.initialized = true;
    }
};
morphing.raster.prototype.clipCanvas = function() {
    if (!this.canvasWidth || !this.canvasHeight) {
        return;
    }
    this.canvas.style.width = this.canvasWidth + "px";
    this.canvas.style.height = this.canvasHeight + "px";
    if (this.clip) {
        this.canvas.style.clip = "rect(0px," + (this.canvasWidth) + "px," + (this.canvasHeight) + "px,0px)";
    }
};
morphing.raster.prototype.clickToFinish = function() {
    var __this = this;
    var clfunc = function(e) {
        if (!e && window.event) {
            e = window.event;
        }
        if (!__this.initialized) {
            return;
        }
        if (!__this.started) {
            return;
        }
        if (__this.finished) {
            return;
        }
        __this.finish();
    };
    this.appendEvent(this.canvas, "click", clfunc);
};
morphing.raster.prototype.appendEvent = function(elem, type, func) {
    if (elem.addEventListener) {
        return elem.addEventListener(type, func, false);
    } else if (elem.attachEvent) {
        return elem.attachEvent("on" + type, func);
    }
};
morphing.raster.SinCache = [];
morphing.raster.prototype.get_sin_table = function(intrv) {
    if (morphing.raster.SinCache[intrv]) {
        return morphing.raster.SinCache[intrv];
    }
    var sintable = [];
    for (var i = 0; i < intrv; i++) {
        sintable[i] = Math.sin(2.0 * Math.PI * i / intrv);
    }
    morphing.raster.SinCache[intrv] = sintable;
    return sintable;
};
morphing.raster.prototype.begin_morphen = function() {
    if (this.background) {
        this.canvas.style.background = this.background;
    }
    var sinsize = Math.floor(this.canvasHeight / this.hoogte_per_lijn);
    this.sinTable = this.get_sin_table(sinsize);
    this.clipCanvas();
    this.clickToFinish();
    var lines = Math.floor(this.canvasHeight / this.hoogte_per_lijn);
    for (var i = lines; i >= 0; i--) {
        this.cloneLine(i, this.hoogte_per_lijn);
    }
    this.timer = new morphing.raster.Timer(this);
    this.timer.start();
};
morphing.raster.prototype.scroll = function() {
    this.started = true;
    if (this.initialized) {
        this.begin_morphen();
    } else {
        this.startOnLoad = true;
    }
};
morphing.raster.prototype.cloneLine = function(top, lines) {
    if (this.linebuf[top]) {
        return this.linebuf[top];
    }
    var newline = this.origineel.cloneNode(true);
    newline.style.position = "absolute";
    newline.style.visibility = "hidden";
    newline.style.clip = "rect(" + (top * lines) + "px," + (this.canvasWidth) + "px," + ((top + 1) * lines) + "px,0px)";
    this.canvas.appendChild(newline);
    this.linebuf[top] = newline;
    return newline;
};
morphing.raster.prototype.loop = function(secs, count) {
    var lines = Math.floor(this.canvasHeight / this.hoogte_per_lijn);
    secs *= 0.001;
    var wavy = this.canvasHeight * this.wave_hoogte;
    var y = 0;
    var top = 0;
    if (secs < this.in_sec_naar_beneden) {
        var prog1 = secs / this.in_sec_naar_beneden;
        y = Math.floor(prog1 * this.canvasHeight) - this.canvasHeight;
        y -= y % this.hoogte_per_lijn;
        top = Math.floor(lines * (1.0 - prog1));
    } else if (secs < this.in_sec_naar_beneden + this.in_sec_faden) {
        var prog3 = (secs - this.in_sec_naar_beneden) / this.in_sec_faden;
        wavy *= (1.0 - prog3);
    } else {
        this.finish();
        return false;
    }
    var wavecnt = Math.floor(secs * this.sinTable.length * this.wave_snelheid);
    for (var i = top; i <= lines; i++) {
        var x = Math.floor(wavy * this.sinTable[(i - top + wavecnt) % this.sinTable.length]);
        this.linebuf[i].style.left = x + "px";
        this.linebuf[i].style.top = y + "px";
        this.linebuf[i].style.visibility = "visible";
    }
    return true;
};
morphing.raster.prototype.finish = function() {
    if (this.timer) {
        if (this.timer.is_running()) {
            this.timer.stop();
        }
        this.timer = null;
    }
    if (this.finished) {
        return;
    }
    this.origineel.style.visibility = "visible";
    this.canvas.style.background = "";
    for (var i = 0; i < this.linebuf.length; i++) {
        if (!this.linebuf[i]) {
            continue;
        }
        if (!this.linebuf[i].parentNode) {
            continue;
        }
        this.linebuf[i].parentNode.removeChild(this.linebuf[i]);
        this.linebuf[i] = null;
    }
    for (i = 0; i < this.trush.length; i++) {
        if (!this.trush[i]) {
            continue;
        }
        if (!this.trush[i].parentNode) {
            continue;
        }
        this.trush[i].parentNode.removeChild(this.trush[i]);
        this.trush[i] = null;
    }
    this.finished = true;
    if (this.onComplete) {
        this.onComplete(this.origineel);
    }
};
morphing.raster.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 tijd_nu = (new Date()).getTime();
        if (!__this.begin_tijd) {
            __this.begin_tijd = tijd_nu;
        }
        var tijd_bezig = tijd_nu - __this.begin_tijd;
        var vlag = __this.target.loop(tijd_bezig, __this.count++);
        if (vlag) {
            setTimeout(__this.next, 1);
        } else {
            __this.stop();
        }
    };
    return this;
};
morphing.raster.Timer.prototype.start = function() {
    this.started = true;
    this.stoped = false;
    this.next();
};
morphing.raster.Timer.prototype.stop = function() {
    this.stoped = true;
};
morphing.raster.Timer.prototype.is_running = function() {
    return (this.started && !this.stoped);
};
setTimeout(function() {
    begin_morph_procedure();
},
200);
</script>
Gebruik voor alle voorbeelden op de http://kompoos.nl een valide html5 pagina.