From e8c2147c13429b85c150d25207cb6ca94000e056 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Wed, 5 Feb 2014 01:50:21 +0400 Subject: [PATCH] rewritten animateElementTo(..)... Signed-off-by: Alex A. Naanou --- css/magazine.css | 2 + lib/jli.js | 146 +++++++++++++++++++++++++++++++++++++++++++++++ magazine.js | 2 +- 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/css/magazine.css b/css/magazine.css index c554ac7..076c2b0 100755 --- a/css/magazine.css +++ b/css/magazine.css @@ -20,6 +20,7 @@ body { /*********************************************************** pages ***/ +.skip, .page { /* XXX make this browser-sized... */ position: relative; @@ -47,6 +48,7 @@ body { */ } +.skip .content, .page .content { display: inline-block; text-align: left; diff --git a/lib/jli.js b/lib/jli.js index 46c1fbc..52fb7a2 100755 --- a/lib/jli.js +++ b/lib/jli.js @@ -401,6 +401,148 @@ function setElementTransform(elem, offset, scale, duration){ } +// Run a function controllably in an animation frame +// +// NOTE: we do not need to make this run several callbacks as the +// browser already does this and will do the loop faster... +function animationFrameRunner(func){ + var next + var _nop = function(){ return this } + + if(this === window){ + self = new animationFrameRunner + } else { + self = this + } + + self.func = func + + var _tick = function(){ + func(Date.now()) + getAnimationFrame(next) + } + + // main user interface... + var start = function(){ + next = _tick + this.start = _nop + this.stop = stop + + // start things up... + // NOTE: we are not calling _tick here directly to avoid stray, + // off-frame call to func... + getAnimationFrame(next) + + return this + } + var stop = function(){ + next = _nop + this.start = start + this.stop = _nop + return this + } + + // setup the ticker in stopped state... + stop.call(self) + + return self +} + + +// NOTE: this is exclusive, e.g. all other animations set with this will +// be stopped on call... +function animateElementTo(elem, to, duration, easing, speed, use_transitions){ + use_transitions = use_transitions != null ? + use_transitions + : USE_TRANSITIONS_FOR_ANIMATION + to = typeof(to) == typeof(1) ? { + left: to, + top: 0, + } : to + speed = typeof(speed) == typeof(2) ? { + x: speed, + y: 0, + } : speed + duration = duration == null ? getElementTransitionDuration(elem) : duration + + // stop other animations... + var runner = elem.data('animating') + if(runner != null){ + runner.stop() + } + + // setup context... + var start = Date.now() + var then = start + duration + var from = getElementShift(elem) + var cur = { + top: from.top, + left: from.left + } + var dist = { + top: to.top - from.top, + left: to.left - from.left, + } + + // accepts either 'top' or 'left' the rest is passed as closures... + var _shift = function(direction, t){ + var v = direction == 'top' ? 'y' : 'x' + if(Math.abs(dist[direction]) >= 1){ + d = ((t - start) * speed[v]) + if(Math.abs(dist[direction]) > Math.abs(d)){ + dist[direction] -= d + cur[direction] = Math.round(cur[direction] + d) + // normalize... + cur[direction] = Math.abs(dist[direction]) <= 1 ? to[direction] : cur[direction] + // calc speed for next step... + speed[v] = dist[direction] / (duration - (t - start)) + } else { + cur[direction] = to[direction] + } + } + } + + var runner = animationFrameRunner(function(){ + var t = Date.now() + + // end of the animation... + if(t >= then){ + setElementTransform(elem, to) + runner.stop() + return + } + + // calculate target position for current step... + // XXX do propper easing... + if(speed != null){ + _shift('top', t) + _shift('left', t) + + // liner speed... + } else { + var r = (t - start) / duration + cur.top = Math.round(from.top + (dist.top * r)) + cur.left = Math.round(from.left + (dist.left * r)) + } + + // do the actual move... + setElementTransform(elem, cur) + }) + + elem.data('animating', runner) + return runner.start() +} + + +function stopAnimation(elem){ + var runner = elem.data('runner') + if(runner != null){ + runner.stop() + } +} + + +/* XXX legacy code... // XXX make this a drop-in replacement for setElementTransform... // XXX cleanup, still flacky... function animateElementTo(elem, to, duration, easing, speed, use_transitions){ @@ -450,6 +592,7 @@ function animateElementTo(elem, to, duration, easing, speed, use_transitions){ elem.next_frame = null function animate(){ + // prevent running animations till next call of animateElementTo(..) if(elem.next_frame === false){ return } @@ -519,11 +662,14 @@ function animateElementTo(elem, to, duration, easing, speed, use_transitions){ function stopAnimation(elem){ + // legacy... if(elem.next_frame){ cancelAnimationFrame(elem.next_frame) elem.next_frame = false + return } } +*/ // XXX account for other transitions... diff --git a/magazine.js b/magazine.js index a51b836..a2d49a2 100755 --- a/magazine.js +++ b/magazine.js @@ -107,7 +107,7 @@ var toggleThemes = createCSSClassToggler('.viewer', [ ]) // toggle box-shadows, this is here mostly for performance reasons... -var toggleShadows = createCSSClassToggler('.viewer', 'shadowless') +var toggleShadows = createCSSClassToggler('.viewer', ['none', 'shadowless'])