assets/js/boxeffects.js

194 lines
6.9 KiB
JavaScript

unitLoad('boxeffects', null, function (unitObj) {
function getTickCount () {
var T = new Date();
return T.getMilliseconds() + T.getSeconds() * 1000 + T.getMinutes() * 60000 + T.getHours() * 3600000 + T.getDay() * 86400000;
}
function cssEffect (el, duration, behaviour, from, to, callback) { // Style-effekt: behaviour=Funktion:[0..1]-->[0..1] from,to=Objekt mit Style-Eigenschaften
function splitNum (s) {
var a = new Array('');
for (var i = 0; i < s.length; i++) {
if ((s.charCodeAt(i) >= 48 && s.charCodeAt(i) <= 57 || s.charCodeAt(i) == 45) || (s.charAt(i) == '.' && a[a.length-1].charAt(0) == '0')) { if (a[a.length-1].charAt(0) != '0') a.push('0'); }
else { if (a[a.length-1].charAt(0) == '0') { a[a.length-1] = parseFloat(a[a.length-1].substring(1)); a.push(''); } }
a[a.length-1] += s.charAt(i);
}
if (a[a.length-1].charAt(0) == '0') a[a.length-1] = parseFloat(a[a.length-1].substring(1));
return a;
}
duration = parseInt(duration);
if (behaviour == null) behaviour = function (s) { return s; };
if (!from) from = window.getComputedStyle(el);
else for (var key in from) el.style[key] = from[key];
for (var key in to) {
from[key] = splitNum(from[key]);
to[key] = splitNum(to[key]);
}
var startTime = getTickCount();
var stop = false;
function f (end) {
if (stop) return;
var t = getTickCount();
if ((end == 0) || (end == 1) && (startTime + duration > t)) {
s = behaviour((t - startTime) / duration);
for (var key in to) {
var v = '';
var r = 0;
for (var i = 0; i < to[key].length; i++) {
if (typeof to[key][i] == 'string') { if (to[key][i].indexOf('rgb') != -1) r = 3; v += to[key][i]; }
else if (r > 0) { v += (from[key][i] * (1-s) + to[key][i] * s); r--; }
else v += (from[key][i] * (1-s) + to[key][i] * s);
}
el.style[key] = v;
}
window.setTimeout(f, 10, 1);
} else {
stop = true;
for (var key in to) el.style[key] = to[key].join('');
if (callback) callback();
}
}
f(0);
if (duration == 0) window.setTimeout(f, 0, 2);
else window.setTimeout(f, 10, 1);
return function (finish) {
if (stop) return;
if (finish) f(2);
else {
stop = true;
if (callback) callback();
}
};
}
function move (el, duration, behaviour, blendIn, callback, dir) {
var p = el.offsetParent;
var d = 0;
var t;
switch (dir) {
case 1 :
t = 'top';
d = el.offsetTop + el.offsetHeight;
break;
case 2 :
t = 'left';
d = el.offsetLeft + el.offsetWidth;
break;
case 3 :
t = 'left';
d = - p.offsetWidth + el.offsetLeft;
break;
case 4 :
t = 'top';
d = - p.offsetHeight + el.offsetTop;
break;
}
var s = window.getComputedStyle(el);
if (s.position != 'fixed' && s.position != 'absolute' && s.position != 'relative') el.style.position = 'relative';
var from = new Object();
var to = new Object();
from[t] = parseFloat(s[t]) - ((blendIn)?d:0) + 'px';
to[t] = parseFloat(s[t]) - ((blendIn)?0:d) + 'px';
return cssEffect(el, duration, behaviour, from, to, callback);
}
function clip (el, duration, behaviour, blendIn, callback, dir) {
var st = window.getComputedStyle(el);
var oldOverflow = el.style.overflow;
var oldPosition = el.style.position;
var oldTop = el.style.top;
var oldLeft = el.style.left;
var oldWidth = el.style.width;
var oldHeight = el.style.height;
el.style.overflow = 'hidden';
if (st.position != 'absolute' && st.position != 'fixed') {
var x = el.offsetLeft;
var y = el.offsetTop;
var w = el.offsetWidth;
var h = el.offsetHeight;
el.style.position = 'absolute';
el.style.top = y+'px';
el.style.left = x+'px';
el.style.height = h+'px';
el.style.width = w+'px';
}
switch (dir) {
case 1:
var from = { clip:'rect(0px,'+el.offsetWidth+'px,'+el.offsetHeight+'px,0px)' };
var to = { clip:'rect('+(el.offsetHeight/2)+'px,'+el.offsetWidth+'px,'+(el.offsetHeight/2)+'px,0px)' };
break;
case 2:
var from = { clip:'rect(0px,'+el.offsetWidth+'px,'+el.offsetHeight+'px,0px)' };
var to = { clip:'rect(0px,'+(el.offsetWidth/2)+'px,'+el.offsetHeight+'px,'+(el.offsetWidth/2)+'px)' };
break;
}
if (blendIn) { var r = from; from = to; to = r; }
return cssEffect(el, duration, behaviour, from, to, function () {
el.style.position = oldPosition;
el.style.top = oldTop;
el.style.left = oldLeft;
el.style.width = oldWidth;
el.style.height = oldHeight;
el.style.overflow = oldOverflow;
el.style.clip = 'auto';
if (callback) callback();
});
}
function torteFillFilter (el, duration, b, i, callback) {
var startTime = getTickCount();
var stop = false;
function f (end) {
if (stop) return;
var t = getTickCount();
var s = (t - startTime) / duration;
if ((end == 0) || (end == 1) && (s < 1)) {
var angle = 2 * Math.PI * s;
if (s < 0.25) el.style.clipPath = 'polygon(50% 50%, 50% -250%, '+(50 + 300*Math.sin(angle))+'% '+(50 - 300*Math.cos(angle))+'%)';
else if (s < 0.5) el.style.clipPath = 'polygon(50% 50%, 50% -250%, 350% 50%, '+(50 + 300*Math.sin(angle))+'% '+(50 - 300*Math.cos(angle))+'%)';
else if (s < 0.75) el.style.clipPath = 'polygon(50% 50%, 50% -250%, 350% 50%, 50% 350%, '+(50 + 300*Math.sin(angle))+'% '+(50 - 300*Math.cos(angle))+'%)';
else el.style.clipPath = 'polygon(50% 50%, 50% -250%, 350% 50%, 50% 350%, -250% 50%, '+(50 + 300*Math.sin(angle))+'% '+(50 - 300*Math.cos(angle))+'%)';
window.setTimeout(f, 10, 1);
} else {
stop = true;
el.style.clipPath = 'initial';
if (callback) callback();
}
}
f(0);
if (duration == 0) window.setTimeout(f, 0, 2);
else window.setTimeout(f, 10, 1);
return function (finish) {
if (stop) return;
if (finish) f(2);
else {
stop = true;
if (callback) callback();
}
};
}
/*
el : element to perform the effect on
d : duration
b : behaviour - a function [0,1] -> [0,1] to modify the progress speed
i : true for blend in, false for blend out
c : callback
*/
this.boxEffects = {
torteFill : function (el, d, b, i, c) { return torteFillFilter(el, d, b, i, c); },
blend : function (el, d, b, i, c) { return cssEffect(el, d, b, {opacity:(i)?'0':'1'}, {opacity:(i)?'1':'0'}, c); },
moveTop : function (el, d, b, i, c) { return move(el, d, b, i, c, 1); },
moveLeft : function (el, d, b, i, c) { return move(el, d, b, i, c, 2); },
moveRight : function (el, d, b, i, c) { return move(el, d, b, i, c, 3); },
moveBottom : function (el, d, b, i, c) { return move(el, d, b, i, c, 4); },
clipHorizontal : function (el, d, b, i, c) { return clip(el, d, b, i, c, 1); },
clipVertical : function (el, d, b, i, c) { return clip(el, d, b, i, c, 2); },
evaporate : function (el, d, b, i, c) { return cssEffect(el, d, b, {opacity:'1', transform:'translate(0px,0px) scale(1,1)', filter:'blur(0px)'}, {opacity:'0', transform:'translate(0px,-50px) scale(1.5,1.7)', filter:'blur(5px)'}, c); }
};
// unit loaded
unitObj.unit = this;
unitObj.onload();
});