summaryrefslogtreecommitdiffstats
path: root/src/fx.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/fx.js')
-rw-r--r--src/fx.js1368
1 files changed, 0 insertions, 1368 deletions
diff --git a/src/fx.js b/src/fx.js
deleted file mode 100644
index dd515df..0000000
--- a/src/fx.js
+++ /dev/null
@@ -1,1368 +0,0 @@
-SVG.easing = {
- '-': function (pos) { return pos },
- '<>': function (pos) { return -Math.cos(pos * Math.PI) / 2 + 0.5 },
- '>': function (pos) { return Math.sin(pos * Math.PI / 2) },
- '<': function (pos) { return -Math.cos(pos * Math.PI / 2) + 1 }
-}
-
-SVG.morph = function (pos) {
- return function (from, to) {
- return new SVG.MorphObj(from, to).at(pos)
- }
-}
-
-let time = window.performance || window.Date
-
-SVG.Timeline = SVG.invent ({
-
- create: function () {
-
- // Store all of the closures to animate
- this._closures = []
-
- this._startTime = time.now()
- this._duration = 0
-
- this._running = true
-
- },
-
- extend: {
-
- animate (duration, ease, delay, epoch) {
-
- }
-
- loop (times, reverse) {
-
- }
-
- duration (time) {
- this._duration = time
- }
-
- delay (by, epoch) {
- if (epoch) {
- this._startTime = time.now()
- }
- this._duration = 0
- this._startTime += by
- }
-
- ease (fn) {
-
- }
-
- play ()
- pause ()
- stop ()
- finish (all=true)
- speed (newSpeed)
- seek (dt)
- persist (dt || forever) // 0 by default
- reverse ()
-
-
-
-
-
-
- // fn is a function that takes a position in range [0, 1]
- schedule (fn) { // fn can not take parameters
-
-
-
-
-
-
-let declarative = rect.animate(300, '>', 200)
- .loop().color('blue')
- .animate(SVG.Spring(300))
-
-onmousemove() {
- declarative.x(mouseX).y(mouseY)
-}
-
- SVG.MorphObj = SVG.invent({
-
- create: function (from, to) {
- // prepare color for morphing
- if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
- // prepare value list for morphing
- if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
- // prepare number for morphing
- if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
-
- // prepare for plain morphing
- this.value = from
- this.destination = to
- },
-
- extend: {
- at: function (pos, real) {
- return real < 1 ? this.value : this.destination
- },
-
- valueOf: function () {
- return this.value
- }
- }
-
- })
-
-
-add('fill-color', val)
-
-add('x', val, 'animations')
-
-add('x', val, 'styles')
-
-add('line-cap', val, 'attrs')
-
-.style(name, val) {
-
-
- styleAttr ('style', name, val)
-}
-
-.animate(spring)
-
-onmousemove(() => {
- el.animate(SVG.Spring(500))
- .move(event.pointX, event.pointY)
- .finish()
-})
-
-
-
-Morphable ()
-
-Controlable ()
-
-new Controller(target, controller)
-
-
-
-
-Number
-Array
-PathArray
-ViewBox
-PointArray
-Color
-
-
-
-
-
-
-
-
-
-
-SVG.Timeline = {
- styleAttr (type, name, val) {
- let morpher = new Morph(val).controller(this.controller)
- queue (
- ()=> {
- morpher = morpher.morph(element[type]('name'))
- },
- morpher.at
- )
- }
-}
-
-.styleAttr (type, name, val) {
-
- let morpher = declarative ? new Controller(target) : new Morph().to(val)
- queue (
- ()=> {
- morpher = morpher.from(element[type](name))
- },
- () => {
- this.element[type](name, morpher.at(pos))
- }
- )
-}
-
-viewbox(box) {
- new Box
- let morpher = new Morph().to(box) // box: {width, heught, x, y}
-}
-
-
-new Morph(from, to)
-
-
-new Morpg(from, to, controller = (from, to, pos) => {from + pos * (to - from)})
-
-
-// Something line
-path = "a, b, c"
-
-SVG.color {
- toArray: [r, g, b]
- fromArray: new Color({r, g, b})
-}
-
-
-
-
-
-
-morph: function (pathArray) {
- pathArray = new SVG.PathArray(pathArray)
-
- if (this.equalCommands(pathArray)) {
- this.destination = pathArray
- } else {
- this.destination = null
- }
-
- return this
-},
-
-[['M', 3, 5], ['L', 5, 6]]
-
-['M', 3, 4, 'L', ...]
-
-
-
-
-function detectSomething (item) {
- if(from instanceof SVG.Morphable) return from.controller(controller)
- // prepare color for morphing
- if (SVG.Color.isColor(to)) return new SVG.Color(from, controller)
- // prepare value list for morphing
- if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
- // prepare number for morphing
- if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
-
- return item
-}
-
-foo->bar
-
-
-all of these things implement
-
-interface Morphable {
- from: (thing)=> {}
- to: (thing)=> {}
- at: (pos)=> {}
- controller: (fn (nowOrFrom, target, pos))=> {}
-}
-
-
-new SVG.MorphObj(el.attr(name))
-
-animate().attr('line-joint', 5)
-
-SVG.MorphObj = SVG.invent({
-
- create: function (from, to) {
- // prepare color for morphing
- if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
- // prepare value list for morphing
- if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
- // prepare number for morphing
- if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
-
- // prepare for plain morphing
- this.value = from
- this.destination = to
- },
-
- extend: {
- at: function (pos, real) {
- return real < 1 ? this.value : this.destination
- },
-
- valueOf: function () {
- return this.value
- }
- }
-
-})
-
-
-// Only works with a single number
-new MorphObj {
-
- constr: (control= (from, to, c)=> {from + pos * (to - from)}) {
- }
-
- _detect: // Gets the user input and returns the right kind of object
-
- from: (from) => {
-
- if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
- // prepare value list for morphing
- if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
- // prepare number for morphing
- if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
-
- // prepare for plain morphing
- this.value = from
- this.destination = to
- }
-
- to: (val) => {
-
- }
- at (pos) {
-
- let type = from.type
- let from = from.toArray()
- let to = to.toArray()
- result = []
- for (i)
- result[i] = this.controller(from[i], to[i], pos) : to[i]
-
- type.fromArray(result)
- }
-}
-
-if(declartive) {
- mropher.init()
- morpher.at(pos/fn)
-}
-
-
-
-controller(currentPos, target)
-
-
-morph interface
-detect type function
-
-
-if (mouse in box)
- move box
- animate(spring)
-
-zoom(level, point) {
- let morpher = SVG.Number(level).controller(this.controller)
- this.queue(
- () => {morpher = morpher.from(element.zoom())},
- (pos) => {element.zoom(morpher.at(pos), point)}
- )
-}
-
-x (x) {
-
-}
-
-this.queue(fn, morpher)
-
-new Morph(x(), xGiven)
-
- x: function (x, relative) {
- if (this.target() instanceof SVG.G) {
- this.transform({x: x}, relative)
- return this
- }
-
- var num = new SVG.Number(x)
- num.relative = relative
- return this.add('x', num)
- },
-
-
- viewbox: function(box) {
- var m = SVG.Box(box)
- }
-
-
- new Runner (function(time) {
-
-
- })
-
-
- var closure = function (time) {
-
- // If it is time to do something, act now.
- var running = start < time && time < end
- if (running && this._running) {
- closure.position = (time - closure.start) / closure.duration
- fn (time)
- }
-
- // If we are not paused or stopped, request another frame
- if (this._running) SVG.Animator.frame(closure, this._startTime)
-
- // Tell the caller whether this animation is finished
- closure.finished = !running
-
- }.bind(this)
-
- closure.stop() // toggles a stop flag
- closure.pause()
- closure.run(t) // If it was paused, it
-
-
- closure.start = this._startTime
- closure.end = this._startTime + this._duration
- closure.positon =
- var forwards = true // Decide if running forward based on looping
-
-
- // TODO: Store a list of closures
-
- SVG.Animator.timeout(closure, this._startTime)
- _continue()
- }
-
- _step (dt) {
-
- }
-
- // Checks if we are running and continues the animation
- _continue () {
- , continue: function () {
- if (this.paused) return
- if (!this.nextFrame)
- this.step()
- return this
- }
-
- }
- },
-
-
- construct: {
- animate: function(o, ease, delay, epoch) {
- return (this.timeline = this.timeline || new SVG.Timeline(o, ease, delay, epoch))
- }
- }
-})
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// SVG.Situation = SVG.invent({
-//
-// create: function (o) {
-// this.init = false
-// this.reversed = false
-// this.reversing = false
-//
-// this.duration = new SVG.Number(o.duration).valueOf()
-// this.delay = new SVG.Number(o.delay).valueOf()
-//
-// this.start = +new Date() + this.delay
-// this.finish = this.start + this.duration
-// this.ease = o.ease
-//
-// // this.loop is incremented from 0 to this.loops
-// // it is also incremented when in an infinite loop (when this.loops is true)
-// this.loop = 0
-// this.loops = false
-//
-// this.animations = {
-// // functionToCall: [list of morphable objects]
-// // e.g. move: [SVG.Number, SVG.Number]
-// }
-//
-// this.attrs = {
-// // holds all attributes which are not represented from a function svg.js provides
-// // e.g. someAttr: SVG.Number
-// }
-//
-// this.styles = {
-// // holds all styles which should be animated
-// // e.g. fill-color: SVG.Color
-// }
-//
-// this.transforms = [
-// // holds all transformations as transformation objects
-// // e.g. [SVG.Rotate, SVG.Translate, SVG.Matrix]
-// ]
-//
-// this.once = {
-// // functions to fire at a specific position
-// // e.g. "0.5": function foo(){}
-// }
-// }
-//
-// })
-//
-// SVG.Timeline = SVG.invent({
-//
-// create: function (element) {
-// this._target = element
-// this.situations = []
-// this.active = false
-// this.situation = null
-// this.paused = false
-// this.lastPos = 0
-// this.pos = 0
-// // The absolute position of an animation is its position in the context of its complete duration (including delay and loops)
-// // When performing a delay, absPos is below 0 and when performing a loop, its value is above 1
-// this.absPos = 0
-// this._speed = 1
-// },
-//
-// extend: {
-//
-// /**
-// * sets or returns the target of this animation
-// * @param o object || number In case of Object it holds all parameters. In case of number its the duration of the animation
-// * @param ease function || string Function which should be used for easing or easing keyword
-// * @param delay Number indicating the delay before the animation starts
-// * @return target || this
-// */
-// animate: function (o, ease, delay) {
-// if (typeof o === 'object') {
-// ease = o.ease
-// delay = o.delay
-// o = o.duration
-// }
-//
-// var situation = new SVG.Situation({
-// duration: o || 1000,
-// delay: delay || 0,
-// ease: SVG.easing[ease || '-'] || ease
-// })
-//
-// this.queue(situation)
-//
-// return this
-// },
-//
-// /**
-// * sets a delay before the next element of the queue is called
-// * @param delay Duration of delay in milliseconds
-// * @return this.target()
-// */
-// delay: function (delay) {
-// // The delay is performed by an empty situation with its duration
-// // attribute set to the duration of the delay
-// var situation = new SVG.Situation({
-// duration: delay,
-// delay: 0,
-// ease: SVG.easing['-']
-// })
-//
-// return this.queue(situation)
-// },
-//
-// /**
-// * sets or returns the target of this animation
-// * @param null || target SVG.Element which should be set as new target
-// * @return target || this
-// */
-// target: function (target) {
-// if (target && target instanceof SVG.Element) {
-// this._target = target
-// return this
-// }
-//
-// return this._target
-// },
-//
-// // returns the absolute position at a given time
-// timeToAbsPos: function (timestamp) {
-// return (timestamp - this.situation.start) / (this.situation.duration / this._speed)
-// },
-//
-// // returns the timestamp from a given absolute positon
-// absPosToTime: function (absPos) {
-// return this.situation.duration / this._speed * absPos + this.situation.start
-// },
-//
-// // starts the animationloop
-// startAnimFrame: function () {
-// this.stopAnimFrame()
-// this.animationFrame = window.requestAnimationFrame(function () { this.step() }.bind(this))
-// },
-//
-// // cancels the animationframe
-// stopAnimFrame: function () {
-// window.cancelAnimationFrame(this.animationFrame)
-// },
-//
-// // kicks off the animation - only does something when the queue is currently not active and at least one situation is set
-// start: function () {
-// // dont start if already started
-// if (!this.active && this.situation) {
-// this.active = true
-// this.startCurrent()
-// }
-//
-// return this
-// },
-//
-// // start the current situation
-// startCurrent: function () {
-// this.situation.start = +new Date() + this.situation.delay / this._speed
-// this.situation.finish = this.situation.start + this.situation.duration / this._speed
-// return this.initAnimations().step()
-// },
-//
-// /**
-// * adds a function / Situation to the animation queue
-// * @param fn function / situation to add
-// * @return this
-// */
-// queue: function (fn) {
-// if (typeof fn === 'function' || fn instanceof SVG.Situation) {
-// this.situations.push(fn)
-// }
-//
-// if (!this.situation) this.situation = this.situations.shift()
-//
-// return this
-// },
-//
-// /**
-// * pulls next element from the queue and execute it
-// * @return this
-// */
-// dequeue: function () {
-// // stop current animation
-// this.stop()
-//
-// // get next animation from queue
-// this.situation = this.situations.shift()
-//
-// if (this.situation) {
-// if (this.situation instanceof SVG.Situation) {
-// this.start()
-// } else {
-// // If it is not a SVG.Situation, then it is a function, we execute it
-// this.situation(this)
-// }
-// }
-//
-// return this
-// },
-//
-// // updates all animations to the current state of the element
-// // this is important when one property could be changed from another property
-// initAnimations: function () {
-// var i, j, source
-// var s = this.situation
-//
-// if (s.init) return this
-//
-// for (i in s.animations) {
-// source = this.target()[i]()
-//
-// if (!Array.isArray(source)) {
-// source = [source]
-// }
-//
-// if (!Array.isArray(s.animations[i])) {
-// s.animations[i] = [s.animations[i]]
-// }
-//
-// // if(s.animations[i].length > source.length) {
-// // source.concat = source.concat(s.animations[i].slice(source.length, s.animations[i].length))
-// // }
-//
-// for (j = source.length; j--;) {
-// // The condition is because some methods return a normal number instead
-// // of a SVG.Number
-// if (s.animations[i][j] instanceof SVG.Number) {
-// source[j] = new SVG.Number(source[j])
-// }
-//
-// s.animations[i][j] = source[j].morph(s.animations[i][j])
-// }
-// }
-//
-// for (i in s.attrs) {
-// s.attrs[i] = new SVG.MorphObj(this.target().attr(i), s.attrs[i])
-// }
-//
-// for (i in s.styles) {
-// s.styles[i] = new SVG.MorphObj(this.target().css(i), s.styles[i])
-// }
-//
-// s.initialTransformation = this.target().matrixify()
-//
-// s.init = true
-// return this
-// },
-//
-// clearQueue: function () {
-// this.situations = []
-// return this
-// },
-//
-// clearCurrent: function () {
-// this.situation = null
-// return this
-// },
-//
-// /** stops the animation immediately
-// * @param jumpToEnd A Boolean indicating whether to complete the current animation immediately.
-// * @param clearQueue A Boolean indicating whether to remove queued animation as well.
-// * @return this
-// */
-// stop: function (jumpToEnd, clearQueue) {
-// var active = this.active
-// this.active = false
-//
-// if (clearQueue) {
-// this.clearQueue()
-// }
-//
-// if (jumpToEnd && this.situation) {
-// // initialize the situation if it was not
-// !active && this.startCurrent()
-// this.atEnd()
-// }
-//
-// this.stopAnimFrame()
-//
-// return this.clearCurrent()
-// },
-//
-// /** resets the element to the state where the current element has started
-// * @return this
-// */
-// reset: function () {
-// if (this.situation) {
-// var temp = this.situation
-// this.stop()
-// this.situation = temp
-// this.atStart()
-// }
-// return this
-// },
-//
-// // Stop the currently-running animation, remove all queued animations, and complete all animations for the element.
-// finish: function () {
-// this.stop(true, false)
-//
-// while (this.dequeue().situation && this.stop(true, false));
-//
-// this.clearQueue().clearCurrent()
-//
-// return this
-// },
-//
-// // set the internal animation pointer at the start position, before any loops, and updates the visualisation
-// atStart: function () {
-// return this.at(0, true)
-// },
-//
-// // set the internal animation pointer at the end position, after all the loops, and updates the visualisation
-// atEnd: function () {
-// if (this.situation.loops === true) {
-// // If in a infinite loop, we end the current iteration
-// this.situation.loops = this.situation.loop + 1
-// }
-//
-// if (typeof this.situation.loops === 'number') {
-// // If performing a finite number of loops, we go after all the loops
-// return this.at(this.situation.loops, true)
-// } else {
-// // If no loops, we just go at the end
-// return this.at(1, true)
-// }
-// },
-//
-// // set the internal animation pointer to the specified position and updates the visualisation
-// // if isAbsPos is true, pos is treated as an absolute position
-// at: function (pos, isAbsPos) {
-// var durDivSpd = this.situation.duration / this._speed
-//
-// this.absPos = pos
-// // If pos is not an absolute position, we convert it into one
-// if (!isAbsPos) {
-// if (this.situation.reversed) this.absPos = 1 - this.absPos
-// this.absPos += this.situation.loop
-// }
-//
-// this.situation.start = +new Date() - this.absPos * durDivSpd
-// this.situation.finish = this.situation.start + durDivSpd
-//
-// return this.step(true)
-// },
-//
-// /**
-// * sets or returns the speed of the animations
-// * @param speed null || Number The new speed of the animations
-// * @return Number || this
-// */
-// speed: function (speed) {
-// if (speed === 0) return this.pause()
-//
-// if (speed) {
-// this._speed = speed
-// // We use an absolute position here so that speed can affect the delay before the animation
-// return this.at(this.absPos, true)
-// } else return this._speed
-// },
-//
-// // Make loopable
-// loop: function (times, reverse) {
-// var c = this.last()
-//
-// // store total loops
-// c.loops = (times != null) ? times : true
-// c.loop = 0
-//
-// if (reverse) c.reversing = true
-// return this
-// },
-//
-// // pauses the animation
-// pause: function () {
-// this.paused = true
-// this.stopAnimFrame()
-//
-// return this
-// },
-//
-// // unpause the animation
-// play: function () {
-// if (!this.paused) return this
-// this.paused = false
-// // We use an absolute position here so that the delay before the animation can be paused
-// return this.at(this.absPos, true)
-// },
-//
-// /**
-// * toggle or set the direction of the animation
-// * true sets direction to backwards while false sets it to forwards
-// * @param reversed Boolean indicating whether to reverse the animation or not (default: toggle the reverse status)
-// * @return this
-// */
-// reverse: function (reversed) {
-// var c = this.last()
-//
-// if (typeof reversed === 'undefined') c.reversed = !c.reversed
-// else c.reversed = reversed
-//
-// return this
-// },
-//
-// /**
-// * returns a float from 0-1 indicating the progress of the current animation
-// * @param eased Boolean indicating whether the returned position should be eased or not
-// * @return number
-// */
-// progress: function (easeIt) {
-// return easeIt ? this.situation.ease(this.pos) : this.pos
-// },
-//
-// /**
-// * adds a callback function which is called when the current animation is finished
-// * @param fn Function which should be executed as callback
-// * @return number
-// */
-// after: function (fn) {
-// var c = this.last()
-// function wrapper (e) {
-// if (e.detail.situation === c) {
-// fn.call(this, c)
-// this.off('finished.fx', wrapper) // prevent memory leak
-// }
-// }
-//
-// this.target().on('finished.fx', wrapper)
-//
-// return this._callStart()
-// },
-//
-// // adds a callback which is called whenever one animation step is performed
-// during: function (fn) {
-// var c = this.last()
-// function wrapper (e) {
-// if (e.detail.situation === c) {
-// fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, c)
-// }
-// }
-//
-// // see above
-// this.target().off('during.fx', wrapper).on('during.fx', wrapper)
-//
-// this.after(function () {
-// this.off('during.fx', wrapper)
-// })
-//
-// return this._callStart()
-// },
-//
-// // calls after ALL animations in the queue are finished
-// afterAll: function (fn) {
-// var wrapper = function wrapper (e) {
-// fn.call(this)
-// this.off('allfinished.fx', wrapper)
-// }
-//
-// // see above
-// this.target().off('allfinished.fx', wrapper).on('allfinished.fx', wrapper)
-//
-// return this._callStart()
-// },
-//
-// // calls on every animation step for all animations
-// duringAll: function (fn) {
-// var wrapper = function (e) {
-// fn.call(this, e.detail.pos, SVG.morph(e.detail.pos), e.detail.eased, e.detail.situation)
-// }
-//
-// this.target().off('during.fx', wrapper).on('during.fx', wrapper)
-//
-// this.afterAll(function () {
-// this.off('during.fx', wrapper)
-// })
-//
-// return this._callStart()
-// },
-//
-// last: function () {
-// return this.situations.length ? this.situations[this.situations.length - 1] : this.situation
-// },
-//
-// // adds one property to the animations
-// add: function (method, args, type) {
-// this.last()[type || 'animations'][method] = args
-// return this._callStart()
-// },
-//
-// /** perform one step of the animation
-// * @param ignoreTime Boolean indicating whether to ignore time and use position directly or recalculate position based on time
-// * @return this
-// */
-// step: function (ignoreTime) {
-// // convert current time to an absolute position
-// if (!ignoreTime) this.absPos = this.timeToAbsPos(+new Date())
-//
-// // This part convert an absolute position to a position
-// if (this.situation.loops !== false) {
-// var absPos, absPosInt, lastLoop
-//
-// // If the absolute position is below 0, we just treat it as if it was 0
-// absPos = Math.max(this.absPos, 0)
-// absPosInt = Math.floor(absPos)
-//
-// if (this.situation.loops === true || absPosInt < this.situation.loops) {
-// this.pos = absPos - absPosInt
-// lastLoop = this.situation.loop
-// this.situation.loop = absPosInt
-// } else {
-// this.absPos = this.situation.loops
-// this.pos = 1
-// // The -1 here is because we don't want to toggle reversed when all the loops have been completed
-// lastLoop = this.situation.loop - 1
-// this.situation.loop = this.situation.loops
-// }
-//
-// if (this.situation.reversing) {
-// // Toggle reversed if an odd number of loops as occured since the last call of step
-// this.situation.reversed = this.situation.reversed !== Boolean((this.situation.loop - lastLoop) % 2)
-// }
-// } else {
-// // If there are no loop, the absolute position must not be above 1
-// this.absPos = Math.min(this.absPos, 1)
-// this.pos = this.absPos
-// }
-//
-// // while the absolute position can be below 0, the position must not be below 0
-// if (this.pos < 0) this.pos = 0
-//
-// if (this.situation.reversed) this.pos = 1 - this.pos
-//
-// // apply easing
-// var eased = this.situation.ease(this.pos)
-//
-// // call once-callbacks
-// for (var i in this.situation.once) {
-// if (i > this.lastPos && i <= eased) {
-// this.situation.once[i].call(this.target(), this.pos, eased)
-// delete this.situation.once[i]
-// }
-// }
-//
-// // fire during callback with position, eased position and current situation as parameter
-// if (this.active) this.target().fire('during', {pos: this.pos, eased: eased, fx: this, situation: this.situation})
-//
-// // the user may call stop or finish in the during callback
-// // so make sure that we still have a valid situation
-// if (!this.situation) {
-// return this
-// }
-//
-// // apply the actual animation to every property
-// this.eachAt()
-//
-// // do final code when situation is finished
-// if ((this.pos === 1 && !this.situation.reversed) || (this.situation.reversed && this.pos === 0)) {
-// // stop animation callback
-// this.stopAnimFrame()
-//
-// // fire finished callback with current situation as parameter
-// this.target().fire('finished', {fx: this, situation: this.situation})
-//
-// if (!this.situations.length) {
-// this.target().fire('allfinished')
-//
-// // Recheck the length since the user may call animate in the afterAll callback
-// if (!this.situations.length) {
-// this.target().off('.fx') // there shouldnt be any binding left, but to make sure...
-// this.active = false
-// }
-// }
-//
-// // start next animation
-// if (this.active) this.dequeue()
-// else this.clearCurrent()
-// } else if (!this.paused && this.active) {
-// // we continue animating when we are not at the end
-// this.startAnimFrame()
-// }
-//
-// // save last eased position for once callback triggering
-// this.lastPos = eased
-// return this
-// },
-//
-// // calculates the step for every property and calls block with it
-// eachAt: function () {
-// var i, at
-// var self = this
-// var target = this.target()
-// var s = this.situation
-//
-// // apply animations which can be called trough a method
-// for (i in s.animations) {
-// at = [].concat(s.animations[i]).map(function (el) {
-// return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
-// })
-//
-// target[i].apply(target, at)
-// }
-//
-// // apply animation which has to be applied with attr()
-// for (i in s.attrs) {
-// at = [i].concat(s.attrs[i]).map(function (el) {
-// return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
-// })
-//
-// target.attr.apply(target, at)
-// }
-//
-// // apply animation which has to be applied with css()
-// for (i in s.styles) {
-// at = [i].concat(s.styles[i]).map(function (el) {
-// return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el
-// })
-//
-// target.css.apply(target, at)
-// }
-//
-// // animate initialTransformation which has to be chained
-// if (s.transforms.length) {
-//
-// // TODO: ANIMATE THE TRANSFORMS
-//
-// // // get initial initialTransformation
-// // at = s.initialTransformation
-// // for(i = 0, len = s.transforms.length; i < len; i++){
-// //
-// // // get next transformation in chain
-// // var a = s.transforms[i]
-// //
-// // // multiply matrix directly
-// // if(a instanceof SVG.Matrix){
-// //
-// // if(a.relative){
-// // at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos)))
-// // }else{
-// // at = at.morph(a).at(s.ease(this.pos))
-// // }
-// // continue
-// // }
-// //
-// // // when transformation is absolute we have to reset the needed transformation first
-// // if(!a.relative)
-// // a.undo(at.decompose())
-// //
-// // // and reapply it after
-// // at = at.multiply(a.at(s.ease(this.pos)))
-// //
-// // }
-// //
-// // // set new matrix on element
-// // target.matrix(at)
-// }
-//
-// return this
-// },
-//
-// // adds an once-callback which is called at a specific position and never again
-// once: function (pos, fn, isEased) {
-// var c = this.last()
-// if (!isEased) pos = c.ease(pos)
-//
-// c.once[pos] = fn
-//
-// return this
-// },
-//
-// _callStart: function () {
-// setTimeout(function () { this.start() }.bind(this), 0)
-// return this
-// }
-//
-// },
-//
-// parent: SVG.Element,
-//
-// // Add method to parent elements
-// construct: {
-// // Get fx module or create a new one, then animate with given duration and ease
-// animate: function (o, ease, delay) {
-// return (this.fx || (this.fx = new SVG.Timeline(this))).animate(o, ease, delay)
-// },
-// delay: function (delay) {
-// return (this.fx || (this.fx = new SVG.Timeline(this))).delay(delay)
-// },
-// stop: function (jumpToEnd, clearQueue) {
-// if (this.fx) {
-// this.fx.stop(jumpToEnd, clearQueue)
-// }
-//
-// return this
-// },
-// finish: function () {
-// if (this.fx) {
-// this.fx.finish()
-// }
-//
-// return this
-// },
-// // Pause current animation
-// pause: function () {
-// if (this.fx) {
-// this.fx.pause()
-// }
-//
-// return this
-// },
-// // Play paused current animation
-// play: function () {
-// if (this.fx) { this.fx.play() }
-//
-// return this
-// },
-// // Set/Get the speed of the animations
-// speed: function (speed) {
-// if (this.fx) {
-// if (speed == null) { return this.fx.speed() } else { this.fx.speed(speed) }
-// }
-//
-// return this
-// }
-// }
-//
-// })
-//
-// // MorphObj is used whenever no morphable object is given
-// SVG.MorphObj = SVG.invent({
-//
-// create: function (from, to) {
-// // prepare color for morphing
-// if (SVG.Color.isColor(to)) return new SVG.Color(from).morph(to)
-// // prepare value list for morphing
-// if (SVG.regex.delimiter.test(from)) return new SVG.Array(from).morph(to)
-// // prepare number for morphing
-// if (SVG.regex.numberAndUnit.test(to)) return new SVG.Number(from).morph(to)
-//
-// // prepare for plain morphing
-// this.value = from
-// this.destination = to
-// },
-//
-// extend: {
-// at: function (pos, real) {
-// return real < 1 ? this.value : this.destination
-// },
-//
-// valueOf: function () {
-// return this.value
-// }
-// }
-//
-// })
-//
-// SVG.extend(SVG.Timeline, {
-// // Add animatable attributes
-// attr: function (a, v, relative) {
-// // apply attributes individually
-// if (typeof a === 'object') {
-// for (var key in a) {
-// this.attr(key, a[key])
-// }
-// } else {
-// this.add(a, v, 'attrs')
-// }
-//
-// return this
-// },
-// // Add animatable styles
-// css: function (s, v) {
-// if (typeof s === 'object') {
-// for (var key in s) {
-// this.css(key, s[key])
-// }
-// } else {
-// this.add(s, v, 'styles')
-// }
-//
-// return this
-// },
-// // Animatable x-axis
-// x: function (x, relative) {
-// if (this.target() instanceof SVG.G) {
-// this.transform({x: x}, relative)
-// return this
-// }
-//
-// var num = new SVG.Number(x)
-// num.relative = relative
-// return this.add('x', num)
-// },
-// // Animatable y-axis
-// y: function (y, relative) {
-// if (this.target() instanceof SVG.G) {
-// this.transform({y: y}, relative)
-// return this
-// }
-//
-// var num = new SVG.Number(y)
-// num.relative = relative
-// return this.add('y', num)
-// },
-// // Animatable center x-axis
-// cx: function (x) {
-// return this.add('cx', new SVG.Number(x))
-// },
-// // Animatable center y-axis
-// cy: function (y) {
-// return this.add('cy', new SVG.Number(y))
-// },
-// // Add animatable move
-// move: function (x, y) {
-// return this.x(x).y(y)
-// },
-// // Add animatable center
-// center: function (x, y) {
-// return this.cx(x).cy(y)
-// },
-// // Add animatable size
-// size: function (width, height) {
-// if (this.target() instanceof SVG.Text) {
-// // animate font size for Text elements
-// this.attr('font-size', width)
-// } else {
-// // animate bbox based size for all other elements
-// var box
-//
-// if (!width || !height) {
-// box = this.target().bbox()
-// }
-//
-// if (!width) {
-// width = box.width / box.height * height
-// }
-//
-// if (!height) {
-// height = box.height / box.width * width
-// }
-//
-// this.add('width', new SVG.Number(width))
-// .add('height', new SVG.Number(height))
-// }
-//
-// return this
-// },
-// // Add animatable width
-// width: function (width) {
-// return this.add('width', new SVG.Number(width))
-// },
-// // Add animatable height
-// height: function (height) {
-// return this.add('height', new SVG.Number(height))
-// },
-// // Add animatable plot
-// plot: function (a, b, c, d) {
-// // Lines can be plotted with 4 arguments
-// if (arguments.length === 4) {
-// return this.plot([a, b, c, d])
-// }
-//
-// return this.add('plot', new (this.target().MorphArray)(a))
-// },
-// // Add leading method
-// leading: function (value) {
-// return this.target().leading
-// ? this.add('leading', new SVG.Number(value))
-// : this
-// },
-// // Add animatable viewbox
-// viewbox: function (x, y, width, height) {
-// if (this.target() instanceof SVG.Container) {
-// this.add('viewbox', new SVG.Box(x, y, width, height))
-// }
-//
-// return this
-// },
-// update: function (o) {
-// if (this.target() instanceof SVG.Stop) {
-// if (typeof o === 'number' || o instanceof SVG.Number) {
-// return this.update({
-// offset: arguments[0],
-// color: arguments[1],
-// opacity: arguments[2]
-// })
-// }
-//
-// if (o.opacity != null) this.attr('stop-opacity', o.opacity)
-// if (o.color != null) this.attr('stop-color', o.color)
-// if (o.offset != null) this.attr('offset', o.offset)
-// }
-//
-// return this
-// }
-// })