Skip to content

Commit

Permalink
feat(pauseResume): Support pause/resume on jQuery delay fn.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jongmoon Yoon committed Mar 30, 2016
1 parent 8680b88 commit 8e27b6d
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 8 deletions.
61 changes: 56 additions & 5 deletions src/hook/pauseResume.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ eg.module("pauseResume", ["jQuery"], function($) {

var animateFn = $.fn.animate;
var stopFn = $.fn.stop;
var delayFn = $.fn.delay;
var uuid = 1;

function AniProperty(el, prop, optall) {
function AniProperty(type, el, prop, optall) {
this.el = el;
this.opt = optall;
this.start = -1;
Expand All @@ -18,6 +19,7 @@ eg.module("pauseResume", ["jQuery"], function($) {
this.uuid = uuid++;
this.easingNames = [];
this.prop = prop;
this.type = type;
}

/**
Expand Down Expand Up @@ -82,10 +84,10 @@ eg.module("pauseResume", ["jQuery"], function($) {
this.easingNames = [];
};

function addAniProperty(el, prop, optall) {
function addAniProperty(type, el, prop, optall) {
var newProp;

newProp = new AniProperty(el, prop, optall);
newProp = new AniProperty(type, el, prop, optall);
el.__aniProps = el.__aniProps || [];

//Animation is excuted immediately.
Expand All @@ -95,6 +97,13 @@ eg.module("pauseResume", ["jQuery"], function($) {
el.__aniProps.push(newProp);
}

function removeAniProperty(el) {
var removeProp = el.__aniProps.shift();
removeProp.clearEasingFn();

el.__aniProps[0] && el.__aniProps[0].init();
}

$.fn.animate = function(prop, speed, easing, callback) {
return this.each(function() {
//optall should be made for each elements.
Expand All @@ -107,6 +116,7 @@ eg.module("pauseResume", ["jQuery"], function($) {
var removeProp = this.__aniProps.shift();
removeProp.clearEasingFn();

// Callback should be called before aniProps.init()
if (userCallback && typeof userCallback === "function") {
userCallback.call(this);
}
Expand All @@ -116,7 +126,7 @@ eg.module("pauseResume", ["jQuery"], function($) {
};

//Queue animation property to recover the current animation.
addAniProperty(this, prop, optall);
addAniProperty("animate", this, prop, optall);
animateFn.call($(this), prop, optall);
});

Expand All @@ -135,6 +145,41 @@ eg.module("pauseResume", ["jQuery"], function($) {
return el.__aniProps[0].paused ? "paused" : "inprogress";
}

/**
* Set a timer to delay execution of subsequent items in the queue.
* And it internally manages "fx"queue to support pause/resume if "fx" type.
*
* @param {Number} An integer indicating the number of milliseconds to delay execution of the next item in the queue.
* @param {String} A string containing the name of the queue. Defaults to fx, the standard effects queue.
*/
$.fn.delay = function(time, type) {
var t;
var isCallByResume = arguments[2];//internal used value.

if (type && type !== "fx") {
return delayFn.call(this, time, type);
}

t = parseInt(time, 10);
t = isNaN(t) ? 0 : t;

return this.each(function() {
if (!isCallByResume) {
// Queue delay property to recover the current animation.
// Don't add property when delay is called by resume.
addAniProperty("delay", this, null, {duration: t});
}

var self = this;
delayFn.call($(this), time).queue(function(next) {
next();

// Remove delay property when delay has been expired.
removeAniProperty(self);
});
});
};

/**
* Pause animation
* @ko 에니메이션을 일시 정지한다
Expand Down Expand Up @@ -217,7 +262,13 @@ eg.module("pauseResume", ["jQuery"], function($) {
// If duration remains, request 'animate' with storing aniProps
if (p.opt.duration > 0 || p.elapsed === 0) {
i === 0 && p.init();
animateFn.call($(this), p.prop, p.opt);

if (p.type === "delay") {
// pass last parameter 'true' not to add an aniProperty.
$(this).delay(p.opt.duration, "fx", true);
} else {
animateFn.call($(this), p.prop, p.opt);
}
}

i++;
Expand Down
65 changes: 62 additions & 3 deletions test/manual/pauseResume.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,26 @@ <h1>Non-CSS Property animation by step/complete callback</h1>
counter();
</code>
</pre>
<div id="counter" class="test" style="float:left;background:yellow;color:#000;font-size:32px;padding:30px;display:inline-block;width:40px;height:40px;text-align:center">
<div id="counter" class="test" style="background:yellow;color:#000;font-size:32px;padding:30px;display:inline-block;width:40px;height:40px;text-align:center"></div>
<h1>Delay Test</h1>
<div class="notice">Test delay can be paused and resumed</div>
<pre>
<code class="js">
$delayBox
.animate({"left":"100px"}, function() {
startDelayCounter(delayDuration);
})
.delay(delayDuration)
.animate({"left":"+=100px"}, function() {
$.style(this, "left", 0);
}
</code>
</pre>
<div class="testBackground">
<div id="delayBox" class="test" style="left:0px;top:0px">
<div id="delayBoxText"></div>
<div id="delayCounter" class="test"></div>
</div>
</div>
<script type="text/javascript">
hljs.initHighlightingOnLoad();
Expand Down Expand Up @@ -304,14 +323,54 @@ <h1>Non-CSS Property animation by step/complete callback</h1>
}
});
};

function delayTest() {
var firstTime = true;
var $delayBox = $("#delayBox");
var $delayBoxText = $("#delayBoxText");
var delayDuration = 3000;
var $delayCounter = $("#delayCounter");

$delayBox
.animate({"left":"100px"}, function() {
startDelayCounter(delayDuration);
})
.delay(delayDuration)
.animate({"left":"+=100px"}, function() {
$.style(this, "left", 0);
delayTest();
});

function startDelayCounter(duration) {
$delayCounter.animate({Counter: duration / 1000}, {
duration: duration,
easing: 'linear',
step: function () {
var txt;

if (!this.Counter) {
return;
}

txt = "Delay 3 sec\nElapsed:";
txt += this.Counter.toFixed(2) + "s";
$(this).text(txt);
},
complete: function() {
this.Counter = 0;
$(this).text("");
}
});
}
}

// counter();
$.each([testMarquee,
drawRectangle,
startEasingTest,
startRelativeTest,
startIndividualElementTest,
counter], function(i, func) {
counter,
delayTest], function(i, func) {
func();
});
</script>
Expand Down
36 changes: 36 additions & 0 deletions test/unit/js/pauseResume.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,39 @@ test("Test relative movent after a value changes on animate chaining", function(
done();
}, this), 2000);
});

test("Delay pause/resume test", function(assert) {
var done = assert.async();
var duration = 400;
var delayDuration = 500;
var pauseAfter = duration + delayDuration / 2;
var pauseDuration = 1000;
var elapsedT1 = 0;
var prevTime = $.now();
var totalDuration = duration + delayDuration + pauseDuration + duration;

// Given
this.$el
.animate({"left": "100px"}, duration)
.delay(delayDuration)
.animate({"left": "150px"}, duration)
.promise().done(function() {
elapsedT1 = $.now() - prevTime;
});

// When
// Pause while delay is inprogress.
setTimeout($.proxy(function() {
this.$el.pause();

setTimeout($.proxy(function() {
this.$el.resume();
}, this), pauseDuration);
}, this), pauseAfter);

//Then
setTimeout($.proxy(function() {
ok(elapsedT1 > totalDuration, "delay was successfully paused and resumed.");
done();
}, this), totalDuration + totalDuration * 0.2);
});

0 comments on commit 8e27b6d

Please sign in to comment.