1
0
This repository has been archived on 2021-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
gallery3-contrib/js/animation.js
2011-04-29 07:17:57 +02:00

197 lines
6.9 KiB
JavaScript

// we need the browser-specific name of the CSS 2D Transform property
window.transformName = (function() {
var prefixedTransformNames = ["transform", "msTransform", "MozTransform", "WebkitTransform", "OTransform"];
var tempDiv = document.createElement("div");
for (var i = 0; i < prefixedTransformNames.length; ++i) {
if (typeof tempDiv.style[prefixedTransformNames[i]] != 'undefined')
return prefixedTransformNames[i];
}
return "noTransform";
})();
var aniList = new Object();
var transformRegExs = {
"scale" : /scale\(\s*([\d\.\-]+)\s*\)/,
"rotate" : /rotate\(\s*([\d\.\-]+)\s*(deg|rad)\s*\)/
};
function AniItem(htmlElement, styleProperty, valueType, startValues, endValues, duration) {
function DoOneUpdate(now) {
var elapsed = now - this.startTime;
// we're done when we're at the end
this.done = !(elapsed < duration);
function linearInterpolate(start, end) {
if (elapsed < duration) {
return start + elapsed * (end - start) / duration;
} else {
return end;
}
}
function formatTransform(strValueNow, transformFunction, currentTransform)
{
var strValue = transformFunction + "(" + strValueNow + ")";
if (currentTransform)
{
var rxFunction = transformRegExs[transformFunction];
if (currentTransform.match(rxFunction))
strValue = currentTransform.replace(rxFunction, strValue);
else
strValue = currentTransform + " " + strValue;
}
return strValue;
}
function formatValue(valueNow, valueType) {
var strValue;
switch (valueType) {
case 'pixels':
strValue = valueNow.toString() + "px";
break;
case 'scaleTransform':
strValue = formatTransform(valueNow.toString(), "scale", htmlElement.style[styleProperty]);
break;
case 'rotateTransform':
strValue = formatTransform(valueNow.toString() + "deg", "rotate", htmlElement.style[styleProperty]);
break;
case 'rotateAndScaleTransform':
strValue = formatTransform(valueNow[0].toString() + "deg", "rotate", htmlElement.style[styleProperty]);
strValue = formatTransform(valueNow[1].toString(), "scale", strValue);
break;
default:
strValue = valueNow.toString();
break;
}
return strValue;
}
var valuesNow;
if (typeof startValues.length != 'undefined') {
valuesNow = new Array();
for (var i = 0; i < startValues.length; ++i)
valuesNow.push(linearInterpolate(startValues[i], endValues[i]));
}
else {
valuesNow = linearInterpolate(startValues, endValues);
}
htmlElement.style[styleProperty] = formatValue(valuesNow, valueType);
}
// the object properties
this.AnimateFrame = DoOneUpdate;
this.startTime = new Date().getTime();
this.done = false;
}
function getCurrentTransformFunctionValue(htmlElement, transformFunction, defaultValue)
{
var currentValue = defaultValue;
var currentTransform = htmlElement.style[window.transformName];
if (currentTransform) {
var m = currentTransform.match(transformRegExs[transformFunction]);
if (m)
{
currentValue = parseFloat(m[1]);
if (transformFunction == "rotate" && m[2] == "rad")
currentValue = currentValue * 180 / Math.PI;
}
}
return currentValue;
}
function getCurrentStringValue(htmlElement, styleProperty)
{
var currentStyleProp = htmlElement.style[styleProperty];
if (currentStyleProp == null || currentStyleProp == '')
currentStyleProp = htmlElement.currentStyle ? htmlElement.currentStyle[styleProperty] :
window.getComputedStyle(htmlElement, null).getPropertyValue(styleProperty);
return currentStyleProp;
}
function getCurrentNumberValue(htmlElement, styleProperty)
{
return parseFloat(getCurrentStringValue(htmlElement, styleProperty));
}
function getCurrentTransformScale(htmlElement) {
return getCurrentTransformFunctionValue(htmlElement, "scale", 1);
}
function getCurrentTransformRotate(htmlElement) {
return getCurrentTransformFunctionValue(htmlElement, "rotate", 0);
}
function animateTransformScale(htmlElement, endScale, duration) {
var currentScale = getCurrentTransformScale(htmlElement);
aniList[htmlElement.id + "st"] = new AniItem(htmlElement, window.transformName, "scaleTransform", currentScale, endScale, duration);
}
function animateTransformRotate(htmlElement, endRotate, duration) {
var currentRotate = getCurrentTransformRotate(htmlElement);
aniList[htmlElement.id + "rt"] = new AniItem(htmlElement, window.transformName, "rotateTransform", currentRotate, endRotate, duration);
}
function animateTransformRotateAndScale(htmlElement, endRotate, endScale, duration) {
animateTransformRotate(htmlElement, endRotate, duration);
animateTransformScale(htmlElement, endScale, duration);
}
function animateOpacity(htmlElement, endOpacity, duration)
{
var currentOpacity = getCurrentNumberValue(htmlElement, "opacity");
aniList[htmlElement.id + "op"] = new AniItem(htmlElement, "opacity", "number", currentOpacity, endOpacity, duration);
}
//var lastAnimate = new Date().getTime();
function _intervalAnimator() {
var now = new Date().getTime() + 18; // look ahead to the next 18ms beat;
// var logged = false;
for (var name in aniList) {
if (aniList[name] instanceof AniItem)
{
if (!aniList[name].done)
{
// if (!logged)
// {
// Debug("Animating at " + (now - lastAnimate) + 'ms');
// lastAnimate = now;
// logged = true;
// }
aniList[name].AnimateFrame(now);
}
}
}
}
window.setInterval(_intervalAnimator, Math.floor(1000 / 60));
function _aniListCleaner() {
var nDeleted = 0;
var startTime = new Date().getTime();
for (var name in aniList) {
if (aniList[name] instanceof AniItem) {
if (aniList[name].done) {
delete aniList[name];
++nDeleted;
}
}
}
// Debug(new Date().toTimeString() + ": done cleaning. " + nDeleted + " items deleted from aniList in " + (new Date().getTime() - startTime).toString() + "ms.");
}
window.setInterval(_aniListCleaner, 5000);