UNPKG

neft

Version:

Universal Platform

147 lines (119 loc) 4.05 kB
'use strict' utils = require 'src/utils' assert = require 'src/assert' eventLoop = require 'src/eventLoop' module.exports = (impl) -> {Types, Renderer} = impl {now} = Date {round} = Math pending = [] nowTime = now() vsync = -> nowTime = now() eventLoop.lock() i = 0; n = pending.length while i < n anim = pending[i] if anim._running and not anim._paused updateAnimation anim, Renderer.PropertyAnimation.ON_PENDING i++ else # remove element in not ordered list # this array may change due loop pending[i] = pending[n - 1] pending.pop() anim._impl.pending = false n-- eventLoop.release() if pending.length > 0 requestAnimationFrame vsync return updateAnimation = (anim, stateFlags) -> data = anim._impl progress = (nowTime - data.startTime) / anim._duration if progress < 0 progress = 0 else if progress > 1 progress = 1 data.progress = progress running = progress isnt 1 or (anim._running and anim._loop and anim._when) fromVal = if data.reversed then data.to else data.from toVal = if data.reversed then data.from else data.to if progress is 1 val = toVal else val = data.easing( anim._duration * progress, fromVal, (toVal - fromVal), anim._duration ) target = anim._target property = anim._property if progress is 1 stateFlags |= Renderer.PropertyAnimation.ON_STOP if val is val and target and property # isNaN hack if (anim._updateProperty & stateFlags) > 0 or not data.propertySetter anim._updatePending = true target[property] = val anim._updatePending = false else impl[data.propertySetter].call target, val if progress is 1 if running data.startTime += anim._loopDelay + anim._duration else data.startTime = 0 anim.running = false return addAnimationIntoPending = (anim) -> data = anim._impl unless data.pending if pending.length is 0 requestAnimationFrame vsync pending.push anim data.pending = true return DATA = type: 'number' pending: false startTime: 0 pauseTime: 0 from: 0 to: 0 DATA: DATA createData: impl.utils.createDataCloner 'PropertyAnimation', DATA create: (data) -> impl.Types.PropertyAnimation.create.call @, data startAnimation: do (_super = impl.startAnimation) -> -> _super.call @ if @_impl.type is 'number' data = @_impl data.from = @_from data.to = @_to addAnimationIntoPending @ data.startTime = now() updateAnimation @, Renderer.PropertyAnimation.ON_START data.startTime += @_startDelay return stopAnimation: do (_super = impl.stopAnimation) -> -> _super.call @ data = @_impl if data.type is 'number' and data.startTime isnt 0 updateAnimation @, Renderer.PropertyAnimation.ON_STOP data.startTime = 0 return resumeAnimation: do (_super = impl.resumeAnimation) -> -> _super.call @ if @_impl.type is 'number' data = @_impl addAnimationIntoPending @ data.startTime += Date.now() - data.pauseTime data.pauseTime = 0 return pauseAnimation: do (_super = impl.pauseAnimation) -> -> _super.call @ data = @_impl if data.type is 'number' data.pauseTime = Date.now() return