/*jslint browser: true, devel: true */
//*********************** Constants **************************
var FPS = 30;
var ANIMATIONOBJECTX = 1;
var ANIMATIONOBJECTY = 2;
var ANIMATIONOBJECTOPACITY = 3;
var ANIMATIONOBJECTWIDTH = 4;
var ANIMATIONOBJECTHEIGHT = 5;
var ANIMATIONOBJECTROTATION = 6;
//*********************** Rotation **************************
function setRotation(view, angle) {
"use strict";
view.css({
"-webkit-transform" : "rotate(" + angle + "deg)",
"-moz-transform" : "rotate(" + angle + "deg)",
"-ms-transform" : "rotate(" + angle + "deg)",
"-o-transform" : "rotate(" + angle + "deg)",
"transform" : "rotate(" + angle + "deg)"
});
view.angle = angle; //For getting the angle later
}
//*********************** Classes **************************
var AnimationObject = function (start, end, time, isSmooth, type, object) {
"use strict";
this.type = type;
this.stages = [];
var dif = end - start,
a,
b,
steps = time * FPS;
if (isSmooth) {
for (a = 0; a < steps; a += 1) {
if (a <= steps / 2) {
//Normal parabola
b = (2.0 / 9) * Math.pow(a, 2) * Math.pow(1.0 / time, 2);
} else {
//Upside down parabola
b = (-2.0 / 9) * Math.pow(a - (FPS * time), 2) * Math.pow(1.0 / time, 2) + 100;
}
this.stages.push(b / 100 * dif + start);
}
} else {
for (a = 0; a < steps; a += 1) {
this.stages.push(a / steps * dif + start);
}
}
//Applies animation value differently depending on type
if (type === ANIMATIONOBJECTX) {
this.applyAnimation = function (step) {
object.css("left", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTY) {
this.applyAnimation = function (step) {
object.css("top", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTOPACITY) {
this.applyAnimation = function (step) {
object.css("opacity", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTWIDTH) {
this.applyAnimation = function (step) {
object.css("width", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTHEIGHT) {
this.applyAnimation = function (step) {
object.css("height", this.stages[step]);
};
} else if (type === ANIMATIONOBJECTROTATION) {
this.applyAnimation = function (step) {
setRotation(object, this.stages[step]);
};
}
};
var AnimationManager = function (time, completionMethod) {
"use strict";
this.animationObjects = [];
this.time = time;
this.add = function (animationObject) {
this.animationObjects.push(animationObject);
};
this.completionMethod = completionMethod;
this.currentStage = 0;
this.maximumStage = this.time * FPS;
this.tick = function () {
this.currentStage += 1;
if (this.currentStage < this.maximumStage) {
setTimeout(this.tick.bind(this), 1000.0 / FPS);
} else {
//Set manager to nil in the completion method
this.completionMethod();
}
var i;
for (i = 0; i < this.animationObjects.length; i += 1) {
this.animationObjects[i].applyAnimation(this.currentStage);
}
};
//Call this to start
this.startAnimation = function () {
this.timer = setTimeout(this.tick.bind(this), 1000.0 / FPS);
};
};
//*********************** Animate Objects **************************
function animatePosition(object, manager, x, y, smooth) {
"use strict";
var curX = parseFloat(object.position().left),
curY = parseFloat(object.position().top);
manager.add(
new AnimationObject(curX, x, manager.time, smooth, ANIMATIONOBJECTX, object)
);
manager.add(
new AnimationObject(curY, y, manager.time, smooth, ANIMATIONOBJECTY, object)
);
}
function animateSize(object, manager, w, h, smooth) {
"use strict";
var curW = parseFloat(object.css("width")),
curH = parseFloat(object.css("height"));
manager.add(
new AnimationObject(curW, w, manager.time, smooth, ANIMATIONOBJECTWIDTH, object)
);
manager.add(
new AnimationObject(curH, h, manager.time, smooth, ANIMATIONOBJECTHEIGHT, object)
);
}
function animateOpacity(object, manager, opacity) {
"use strict";
var curO = parseFloat(object.css("opacity"));
manager.add(
new AnimationObject(curO, opacity, manager.time, false, ANIMATIONOBJECTOPACITY, object)
);
}
function animateRotation(object, manager, angle, smooth) {
"use strict";
console.log(object.angle);
if (object.angle === undefined) {
object.angle = 0;
}
manager.add(
new AnimationObject(object.angle, angle, manager.time, smooth, ANIMATIONOBJECTROTATION, object)
);
}
var view;
function doSomething() {
"use strict";
view = $("#test");
var manager;
view.html("animating");
var complete = function () {
view.html("complete");
manager = null;
setTimeout(doSomething, 100);
};
manager = new AnimationManager(Math.random() * 1.0, complete);
animatePosition(view, manager, Math.random() * 400, Math.random() * 500, true);
animateOpacity(view, manager, Math.random());
animateSize(view, manager, Math.random() * 500, Math.random() * 500, true);
animateRotation(view, manager, Math.random() * 360, Math.round(Math.random()));
manager.startAnimation();
}
当我按下按钮时,底部的doSomething方法会运行。 animateRotation方法检测到object.angle未定义并将其设置为0.在动画期间,调用setRotation并将object.angle设置为它的角度(我也可以将console.log设置得很好)。但是当调用complete函数并且动画再次启动时,对象(doSomething方法中的视图).angle将再次重置为undefined。这是怎么回事?
答案 0 :(得分:0)
就像现在一样,view = $("#test");
每次调用doSomething
时都会运行,它会选择相同的DOM节点,但每次都返回一个不同的jQuery对象。
解决此问题的最简单方法是执行以下操作:
view = view || $("#test");
但是,您应该重构代码,使其不依赖于全局变量。
一旦你解决了这个问题,你会发现对象上会存在angle
属性,但在动画结束时它仍然是未定义的。那是因为上一次setRotation
被调用,angle
也是undefined
。