mirror of
https://github.com/svgdotjs/svg.js.git
synced 2024-07-31 20:21:32 +02:00
Added some timeline and Morphing functions
This commit is contained in:
parent
7a4979d0cf
commit
64b3144c89
@ -41,13 +41,14 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
|
||||
<script src="svg.bench.js"></script>
|
||||
<!--<script src="tests/10000-each.js"></script> -->
|
||||
<script src="tests/10000-rects.js"></script>
|
||||
<!-- <script src="tests/10000-rects.js"></script>
|
||||
<script src="tests/10000-circles.js"></script>
|
||||
<script src="tests/10000-paths.js"></script>
|
||||
<script src="tests/10000-boxes.js"></script>
|
||||
<script src="tests/10000-pointArray-bbox.js"></script>
|
||||
<script src="tests/10000-pointArray-bbox.js"></script> -->
|
||||
<script src="tests/10000-accesses.js"></script>
|
||||
<script>
|
||||
SVG.bench.run()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
35
bench/tests/10000-accesses.js
Normal file
35
bench/tests/10000-accesses.js
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
SVG.bench.describe('Access a dom attribues vs dom properties vs object properties', function(bench) {
|
||||
bench.test('using an object', function() {
|
||||
var sum = 0
|
||||
var obj = {x: "30"}
|
||||
for (var i = 0; i < 1000000; i++) {
|
||||
sum += obj.x * i
|
||||
}
|
||||
console.log(sum)
|
||||
})
|
||||
|
||||
bench.test('figure out what the overhead is', function () {
|
||||
var obj = bench.draw.rect(100, 100).move(0, 0)
|
||||
})
|
||||
|
||||
bench.test('using dom attriutes', function () {
|
||||
var sum = 0
|
||||
var obj = bench.draw.rect(100, 100).move(0, 0)
|
||||
var node = obj.node
|
||||
for (var i = 0; i < 1000000; i++) {
|
||||
sum += node.getAttribute('x') * i
|
||||
}
|
||||
console.log(sum, node.getAttribute('x'))
|
||||
})
|
||||
|
||||
bench.test('using dom properties', function () {
|
||||
var sum = 0
|
||||
var obj = bench.draw.rect(100, 100).move(0, 0)
|
||||
var node = obj.node
|
||||
for (var i = 0; i < 1000000; i++) {
|
||||
sum += node.x.baseVal * i
|
||||
}
|
||||
console.log(sum, node.x)
|
||||
})
|
||||
})
|
@ -1,6 +1,13 @@
|
||||
|
||||
SVG.defaults = {
|
||||
|
||||
// Default animation values
|
||||
timeline: {
|
||||
duration: 600,
|
||||
ease: '>',
|
||||
delay: 0,
|
||||
},
|
||||
|
||||
// Default attribute values
|
||||
attrs: {
|
||||
|
||||
|
25
src/fx.js
25
src/fx.js
@ -142,12 +142,30 @@ Controlable ()
|
||||
new Controller(target, controller)
|
||||
|
||||
|
||||
|
||||
|
||||
Number
|
||||
Array
|
||||
PathArray
|
||||
ViewBox
|
||||
PointArray
|
||||
Color
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
SVG.Timeline = {
|
||||
styleAttr (type, name, val) {
|
||||
let morpher = new Morph(this.controller).to(val)
|
||||
let morpher = new Morph(val).controller(this.controller)
|
||||
queue (
|
||||
()=> {
|
||||
morpher = morpher.from(element[type]('name'))
|
||||
morpher = morpher.morph(element[type]('name'))
|
||||
},
|
||||
morpher.at
|
||||
)
|
||||
@ -159,7 +177,7 @@ SVG.Timeline = {
|
||||
let morpher = declarative ? new Controller(target) : new Morph().to(val)
|
||||
queue (
|
||||
()=> {
|
||||
morpher = morpher.from(element[type]('name'))
|
||||
morpher = morpher.from(element[type](name))
|
||||
},
|
||||
() => {
|
||||
this.element[type](name, morpher.at(pos))
|
||||
@ -339,7 +357,6 @@ this.queue(fn, morpher)
|
||||
|
||||
new Morph(x(), xGiven)
|
||||
|
||||
|
||||
x: function (x, relative) {
|
||||
if (this.target() instanceof SVG.G) {
|
||||
this.transform({x: x}, relative)
|
||||
|
@ -10,7 +10,11 @@ SVG.Matrix = SVG.invent({
|
||||
source = source instanceof SVG.Element ? source.matrixify()
|
||||
: typeof source === 'string' ? arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat))
|
||||
: Array.isArray(source) ? arrayToMatrix(source)
|
||||
: typeof source === 'object' ? source
|
||||
: (typeof source === 'object' && (
|
||||
source.a != null || source.b != null || source.c != null
|
||||
|| source.d != null || source.e != null || source.f != null
|
||||
)) ? source
|
||||
: (typeof source === 'object') ? new SVG.Matrix().transform(source)
|
||||
: arguments.length === 6 ? arrayToMatrix([].slice.call(arguments))
|
||||
: base
|
||||
|
||||
|
394
src/morph.js
Normal file
394
src/morph.js
Normal file
@ -0,0 +1,394 @@
|
||||
SVG.Morphable = SVG.invent{
|
||||
create: function (controller) {
|
||||
this.controller = controller || function (from, to, pos) {
|
||||
return pos < 1 ? from : to
|
||||
}
|
||||
},
|
||||
|
||||
extend: {
|
||||
|
||||
from: function (val) {
|
||||
this._from = this._set(val)
|
||||
return this
|
||||
}
|
||||
|
||||
to: function (val, modifier) {
|
||||
this._to = this._set(val)
|
||||
this.modifier = modifier
|
||||
return this
|
||||
}
|
||||
|
||||
type: function (type) {
|
||||
this._type = type
|
||||
return this
|
||||
}
|
||||
|
||||
_set: function (value) {
|
||||
|
||||
if(!this._type) {
|
||||
if (SVG.Color.isColor(val)) {
|
||||
this._type = SVG.Color
|
||||
|
||||
} else if (SVG.regex.delimiter.test(val)) {
|
||||
|
||||
this._type = SVG.regex.pathLetters.test(val)
|
||||
? SVG.PathArray
|
||||
: SVG.Array
|
||||
|
||||
} else if (SVG.regex.numberAndUnit.test(val)) {
|
||||
this._type = SVG.Number
|
||||
|
||||
} else if (value in SVG.MorphableTypes) {
|
||||
this._type = value.constructor
|
||||
|
||||
// } else if (typeof value == 'object') {
|
||||
// this._type = SVG.Morphable.TransformBag
|
||||
} else {
|
||||
this._type = SVG.Morphable.NonMorphable
|
||||
}
|
||||
}
|
||||
|
||||
return (new this._type(value)).toArray()
|
||||
}
|
||||
|
||||
controller: function (controller) {
|
||||
this._controller = controller
|
||||
}
|
||||
|
||||
at: function (pos) {
|
||||
|
||||
var _this = this
|
||||
|
||||
// for(var i = 0, len = this._from.length; i < len; ++i) {
|
||||
// arr.push(this.controller(this._from[i], this._to[i]))
|
||||
// }
|
||||
|
||||
return this.type.fromArray(this.modifier(this._from.map(function (i, index) {
|
||||
return _this.controller(i, _this._to[i], pos)
|
||||
})))
|
||||
},
|
||||
|
||||
valueOf: function () {
|
||||
return this._value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SVG.Morphable.NonMorphable = SVG.invent({
|
||||
create: function (val) {
|
||||
this.value = val
|
||||
},
|
||||
|
||||
extend: {
|
||||
valueOf: function () {
|
||||
return this.value
|
||||
},
|
||||
|
||||
toArray: function () {
|
||||
return [this.value]
|
||||
},
|
||||
|
||||
fromArray: function (arr) {
|
||||
return new SVG.Morphable.NonMorphable(arr[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
SVG.Morphable.TransformBag = SVG.invent({
|
||||
create: function (val) {
|
||||
this.value = new Matrix(val).decompose()
|
||||
},
|
||||
|
||||
extend: {
|
||||
valueOf: function () {
|
||||
return this.value
|
||||
},
|
||||
|
||||
toArray: function (){
|
||||
var v = this.value
|
||||
|
||||
return [
|
||||
v.scaleX,
|
||||
v.scaleY,
|
||||
v.shear,
|
||||
v.rotate,
|
||||
v.translateX,
|
||||
v.translateY
|
||||
]
|
||||
}
|
||||
|
||||
fromArray: function (arr) {
|
||||
return new SVG.Morphable.TransformBag({
|
||||
scaleX: arr[0],
|
||||
scaleY: arr[1],
|
||||
shear: arr[2],
|
||||
rotate: arr[3],
|
||||
translateX: arr[4],
|
||||
translateY: arr[5]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
SVG.MorphableTypes = [SVG.Number, SVG.Color, SVG.Box, SVG.Matrix, SVG.Morphable.NonMorphable, SVG.Morphable.TransformBag]
|
||||
SVG.extend(SVG.MorphableTypes, {
|
||||
to: (item, args) => {
|
||||
let a = new SVG.Morphable().type(this.constructor).to(item, args)
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
// - Objects are just variable bags
|
||||
// - morph rerutrns a morphable. No state on normal objects (like SVG.Color)
|
||||
// - Objects can be represented as Array (with toArray())
|
||||
// - Objects have an unmorph/fromarray function which converts it back to a normal object
|
||||
|
||||
// var b = new Color('#fff')
|
||||
// b.morph('#000') === new Morph(b).to('#000')
|
||||
|
||||
// sweet = Color('#fff')
|
||||
// dark = Color('#fef')
|
||||
// sweet.to(dark, 'hsl')
|
||||
|
||||
// angle = Number(30)
|
||||
// lastAngle = Number(300)
|
||||
// angle.to(lastAngle, cyclic)
|
||||
|
||||
// mat1 = Matrix().transform({rotation: 30, scale: 0})
|
||||
// mat2 = Matrix(30, 40, 50, 60, 10, 20)
|
||||
// mat1.to(mat2)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
** absolute transformations
|
||||
**/
|
||||
|
||||
// M v -----|-----(D M v = I v)------|-----> T v
|
||||
//
|
||||
// 1. define the final state (T) and decompose it (once) t = [tx, ty, the, lam, sy, sx]
|
||||
// 2. on every frame: pull the current state of all previous transforms (M - m can change)
|
||||
// and then write this as m = [tx0, ty0, the0, lam0, sy0, sx0]
|
||||
// 3. Find the interpolated matrix I(pos) = m + pos * (t - m)
|
||||
// - Note I(0) = M
|
||||
// - Note I(1) = T
|
||||
// 4. Now you get the delta matrix as a result: D = I * inv(M)
|
||||
|
||||
|
||||
|
||||
|
||||
el.animate().trasform({rotate: 720, scale: 2}, true)
|
||||
|
||||
el.animate().scale(2).rotate(720)
|
||||
|
||||
el.animate().transform({origin: traslate, })
|
||||
|
||||
absolute -> start at current - {affine params}
|
||||
relative -> start at 0 always - {random stuff}
|
||||
|
||||
|
||||
|> object.toArray()
|
||||
|> (_) => _.map(() => {})
|
||||
|> modifier
|
||||
|> fromArray
|
||||
|
||||
function transform(transforms, relative, affine) {
|
||||
affine = transforms.affine || affine
|
||||
relative = transforms.relative || relative
|
||||
|
||||
// 1. define the final state (T) and decompose it (once) t = [tx, ty, the, lam, sy, sx]
|
||||
var morpher = new SVG.Morphable.TransformBag().to(transforms)
|
||||
|
||||
// make sure you have an identity matrix defined as default for relative transforms
|
||||
var morpher.from()
|
||||
var el = this.target()
|
||||
|
||||
var initFn = relative ? function() {} : function() {
|
||||
// 2. on every frame: pull the current state of all previous transforms (M - m can change)
|
||||
morpher.from(el.transform())
|
||||
}
|
||||
|
||||
this.queue(initFn, function (pos) {
|
||||
// 3. Find the interpolated matrix I(pos) = m + pos * (t - m)
|
||||
// - Note I(0) = M
|
||||
// - Note I(1) = T
|
||||
var matrix = morpher.at(pos)
|
||||
|
||||
if(!relative) {
|
||||
// 4. Now you get the delta matrix as a result: D = I * inv(M)
|
||||
matrix = matrix.multiply(el.transform().inverse())
|
||||
}
|
||||
|
||||
el.pushTransform(matrix)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
SVG.Morphable.TransformList = Object
|
||||
|
||||
if(affine) {
|
||||
var morpher = new Matrix().to(transforms)
|
||||
}
|
||||
|
||||
if(input is typeof plain object) {
|
||||
// deal with a ttransformList
|
||||
this.type = SVG.Morphable.TransformList
|
||||
}
|
||||
|
||||
var morpher = new Morphable(modifier).to(transforms)
|
||||
|
||||
this.queue(() => {
|
||||
morpher.from(this.transform())
|
||||
}, (pos) => {
|
||||
var matrix = morpher.at(pos)
|
||||
el.transform(matrix)
|
||||
})
|
||||
|
||||
el.transform({rotate: 720, sclae: 2, })
|
||||
|
||||
el.scale(2)
|
||||
.rotate(720)
|
||||
|
||||
from -> 300
|
||||
to -> [295, 305]
|
||||
|
||||
from -> 358
|
||||
to -> 1
|
||||
|
||||
|
||||
|
||||
from -> 300
|
||||
to -> 30
|
||||
|
||||
function transform(transforms, affine) {
|
||||
|
||||
if(relative) {
|
||||
|
||||
var morpher = new Morphable().to(transforms, affine)
|
||||
this.queue(() => {}, (pos) => {
|
||||
var matrix = morpher.at(pos)
|
||||
el.transform(matrix)
|
||||
})
|
||||
|
||||
} else {
|
||||
|
||||
this.queue(() => {
|
||||
morpher
|
||||
}, (pos) => {
|
||||
var matrix = morpher.at(pos)
|
||||
el.transform(matrix)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// el.animate().rotate(480)
|
||||
function rotate(val) { // Relative
|
||||
var morpher = new Morphable().from(0).to(val)
|
||||
this.queue(() => {}, (pos)=> {
|
||||
var rotation = morpher.at(pos)
|
||||
el.rotate(rotation)
|
||||
})
|
||||
}
|
||||
// morph = new Morphable(0).to(50, [0, 360]) -> in timeline
|
||||
//
|
||||
//
|
||||
//
|
||||
// on each frame
|
||||
// el.rotate(morph.at(pos))
|
||||
|
||||
|
||||
Morph.modifiers = {
|
||||
|
||||
hsb:
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
new Color(#fff).to('#000', 'hsb')
|
||||
|
||||
at returns a matrix anyway
|
||||
|
||||
new Number()
|
||||
|
||||
|
||||
el.animate().fill('#000', 'hsb')
|
||||
function fill(val, colorspace) {
|
||||
var morpher = new Morphable().to(val, colorspace || 'rgb')
|
||||
|
||||
this.queue((val) => {
|
||||
morpher.from(val)
|
||||
}, (pos)=> {
|
||||
var color = morpher.at(pos)
|
||||
el.fill(color)
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
// Number.toArray() -> [3]
|
||||
// Color.toArray() -> [red, green, blue]
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
new Color(30, 50, 40).toArray()
|
||||
|
||||
|
||||
|
||||
|
||||
new PathArray([['M', 0, 3], ['L', 4, 5]]).morph(5, 3, 2, 8, 5)
|
||||
|
||||
controller = (s, e, p)=> {return s + (e-s) * p}
|
||||
|
||||
[['M', 0, 3], ['L', 4, 5], ['A', 120, 120, 1, 0]]
|
||||
|
||||
|
||||
['1', '2', '3'] => parseFloat()
|
||||
|
||||
|
||||
rect.anim()
|
||||
.color('blue')
|
||||
.anim()
|
||||
.color(new Color('red'))
|
||||
|
||||
|
||||
|
||||
a = new SVG.Color('#3f2').to('#5f4').at(0.3)
|
||||
|
||||
|
||||
new Morphable('#3f2').to('#5f4').at(0.4)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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)}
|
||||
)
|
||||
return this
|
||||
}
|
||||
*/
|
@ -100,5 +100,11 @@ SVG.Number = SVG.invent({
|
||||
.plus(this)
|
||||
}
|
||||
|
||||
|
||||
|
||||
new SVG.Color('#2a4e5a').morph('#3b4f2a').at(0.4)
|
||||
|
||||
new Morph().from('#2a4e5a').to('#3b4f2a').at(0.3)
|
||||
|
||||
}
|
||||
})
|
||||
|
172
src/timeline.js
172
src/timeline.js
@ -11,9 +11,9 @@ SVG.easing = {
|
||||
function Runner (timeline) {
|
||||
|
||||
// We store a reference to the function to run and the timeline to use
|
||||
this.functions = []
|
||||
this.timeline = timeline
|
||||
this.transforms = []
|
||||
this.functions = []
|
||||
this.done = false
|
||||
|
||||
// We copy the current values from the timeline because they can change
|
||||
@ -29,11 +29,10 @@ Runner.prototype = {
|
||||
this.functions.push(fn)
|
||||
},
|
||||
|
||||
run: function (time) {
|
||||
|
||||
var line = this.timeline
|
||||
step: function (time) {
|
||||
|
||||
// If it is time to do something, act now.
|
||||
var end = this._start + this._duration
|
||||
var running = this._start < time && time < end
|
||||
if (running && this._running) {
|
||||
var position = (time - this._startTime) / this._duration
|
||||
@ -50,7 +49,7 @@ Runner.prototype = {
|
||||
closure.finished = !running
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
snap: function () {
|
||||
|
||||
},
|
||||
|
||||
@ -60,44 +59,128 @@ Runner.prototype = {
|
||||
}
|
||||
|
||||
|
||||
let time = window.performance || window.Date
|
||||
|
||||
|
||||
SVG.Timeline = SVG.invent({
|
||||
|
||||
create: function (o, easy, delay, epoch) {
|
||||
// Construct a new timeline on the given element
|
||||
create: function (element) {
|
||||
|
||||
this.baseTransform = []
|
||||
this.runners = []
|
||||
this.controller = null
|
||||
// Store a reference to the element to call its parent methods
|
||||
this._element = element
|
||||
|
||||
if(o instanceof 'function') {
|
||||
this.controller = o
|
||||
// Store the timing variables
|
||||
this._startTime = time.now()
|
||||
this._duration = SVG.defaults.duration
|
||||
this._ease = SVG.defaults.ease
|
||||
|
||||
} else if (typeof o === 'object') {
|
||||
ease = o.ease
|
||||
delay = o.delay
|
||||
o = o.duration
|
||||
}
|
||||
// Play control variables control how the animation proceeds
|
||||
this._controller = o instanceof 'function' ? o : null
|
||||
this._backwards = false
|
||||
this._reverse = false
|
||||
this._loops = 0
|
||||
|
||||
this.ease = ease
|
||||
this.delay = delay
|
||||
this.duration = o
|
||||
// Keep track of the running animations and their starting parameters
|
||||
this._baseTransform = null
|
||||
this._running = true
|
||||
this._runners = []
|
||||
},
|
||||
|
||||
extend: {
|
||||
|
||||
animate (duration, ease, delay, epoch)
|
||||
loop (times, reverse)
|
||||
duration (time)
|
||||
delay (by, epoch)
|
||||
ease (fn)
|
||||
animate (duration, delay, now) {
|
||||
|
||||
play ()
|
||||
pause ()
|
||||
stop ()
|
||||
finish (all=true)
|
||||
speed (newSpeed)
|
||||
seek (dt)
|
||||
persist (dt || forever) // 0 by default
|
||||
reverse ()
|
||||
// Clear the controller and the looping parameters
|
||||
this._controller = null
|
||||
this._backwards = false
|
||||
this._swing = false
|
||||
this._loops = 0
|
||||
|
||||
// If we have a controller, we will use the declarative animation mode
|
||||
if(duration instanceof 'function') {
|
||||
|
||||
this._controller = duration
|
||||
|
||||
// If we have an object we are declaring imperative animations
|
||||
} else if (typeof duration === 'object') {
|
||||
|
||||
ease = duration.ease
|
||||
delay = duration.delay
|
||||
now = duration.now
|
||||
duration = duration.duration
|
||||
}
|
||||
|
||||
// We start the next animation after the old one is complete
|
||||
this._startTime = now ? time.now() : (this._startTime + this._duration)
|
||||
this._duration = duration || SVG.defaults.duration
|
||||
|
||||
// Make a new runner to take care of the
|
||||
|
||||
return this
|
||||
},
|
||||
|
||||
duration (time) {
|
||||
return this.animate(time, 0, false)
|
||||
},
|
||||
|
||||
delay (by, now) {
|
||||
return this.animate(0, by, now)
|
||||
},
|
||||
|
||||
ease (fn) {
|
||||
this._ease = SVG.easing[fn || SVG.defaults.ease] || fn
|
||||
return this
|
||||
},
|
||||
|
||||
loop (times, swing) {
|
||||
this._loops = times
|
||||
this._swing = swing
|
||||
},
|
||||
|
||||
play () {
|
||||
this._running = true
|
||||
this._continue()
|
||||
},
|
||||
|
||||
pause () {
|
||||
this._running = false
|
||||
},
|
||||
|
||||
stop () {
|
||||
this.pause()
|
||||
|
||||
// Cancel all of the requested animation frames
|
||||
|
||||
},
|
||||
|
||||
finish (all=true) {
|
||||
|
||||
},
|
||||
|
||||
speed (newSpeed) {
|
||||
|
||||
},
|
||||
|
||||
seek (dt) {
|
||||
|
||||
},
|
||||
|
||||
persist (dt || forever) {
|
||||
// 0 by default
|
||||
},
|
||||
|
||||
reverse () {
|
||||
|
||||
},
|
||||
|
||||
queue (initialise, during) {
|
||||
|
||||
// Make a new runner
|
||||
var runner = new Runner(this)
|
||||
this._runners.push()
|
||||
|
||||
},
|
||||
|
||||
_step (dt) {
|
||||
|
||||
@ -105,23 +188,26 @@ SVG.Timeline = SVG.invent({
|
||||
|
||||
// Checks if we are running and continues the animation
|
||||
_continue () {
|
||||
, continue: function () {
|
||||
if (this.paused) return
|
||||
if (!this.nextFrame)
|
||||
this.step()
|
||||
return this
|
||||
}
|
||||
if (this._paused) return
|
||||
|
||||
// Go through each of the runners and step them
|
||||
},
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
// Only elements are animatable
|
||||
parent: SVG.Element,
|
||||
|
||||
// These methods will be added to all SVG.Element objects
|
||||
construct: {
|
||||
animate: function(o, ease, delay, epoch) {
|
||||
return (this.timeline = this.timeline || new SVG.Timeline(o, ease, delay, epoch))
|
||||
animate: function(o, delay, now) {
|
||||
|
||||
// Get the current timeline or construct a new one
|
||||
this.timeline = (this.timeline || new SVG.Timeline(this))
|
||||
.animate(o, delay, now)
|
||||
return this.timeline
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Extend the attribute methods separately to avoid cluttering the main
|
||||
@ -150,7 +236,7 @@ SVG.extend(SVG.Timeline, {
|
||||
|
||||
this.queue(
|
||||
function () {
|
||||
morpher = morpher.from(element[type]('name'))
|
||||
morpher = morpher.from(element[type](name))
|
||||
},
|
||||
function () {
|
||||
this.element[type](name, morpher.at(pos))
|
||||
|
Loading…
Reference in New Issue
Block a user