Code archives/Miscellaneous/Animating Fields

This code has been declared by its author to be Public Domain code.

Download source code

Animating Fields by N2009
This code isn't going to be fast, it's mostly just for the sake of prototyping stuff (which is why I wrote it, I needed to do something very quickly and execution speed was not an issue). Its main use is in animating the properties of objects - say you have an object with an Alpha field you want to set to 0 (its starting value being whatever was in there when the animation started) over 5 seconds, you can do that using Animate(theObject, "Alpha", 0, 5000).

For example, here's a quick program I wrote to visualize a timeline. It's not pretty code, but it works.

timeline.bmx


entries.csv


And now I go to sleep, because I have had a very stressful day, my eyes are bright red, and I'm exhausted. I'm really just not cut out for anything...
Strict

Type Animation
	?Threaded
	Global AnimationsLock:TMutex = TMutex.Create()
	?
	Global Animations:TList = New TList
	Global AnimationTimer:TTimer = TTimer.Create(60, Null)
	
	Field o:Object		' Object being animated, used to keep pointer to object in scope during animation
	Field f:TField
	Field duration:Double
	Field stime:Int
	Field start:Double
	Field finish:Double
	Field fn:Double(s:Double,f:Double,t:Double)
'	Field last:Double ' check to see if the value has changed since last time
	
	Method Update(ctime%=-1)
		If ctime=-1 Then ctime = Millisecs()
		Local time! = (ctime-stime)/duration
		If time >= 1! Then
			?Threaded
			AnimationsLock.Lock
			?
			Animations.Remove(Self)
			?Threaded
			AnimationsLock.Unlock
			?
			If Not fn Then f.SetDouble(o, finish)
		Else
			Local nv!
			If fn Then
				nv = fn(start, finish, Min(time,1))
			Else
				nv = start+((finish-start)*Min(time,1))
			EndIf
			f.SetDouble(o, nv)
		EndIf
	End Method
	
	Function UpdateAnimations()
		?Threaded
		AnimationsLock.Lock
		?
		If Not Animations.IsEmpty() Then
			Local ctime% = Millisecs()
			Local anims:TList = Animations.Copy()
			For Local a:Animation = EachIn Animations
				a.Update(ctime)
			Next
		EndIf
		?Threaded
		AnimationsLock.Unlock
		?
	End Function
	
	Function tick_UpdateAnimations:Object(id%, data:Object, ctx:Object)
		Local event:TEvent = TEvent(data)
		If event And event.id = EVENT_TIMERTICK And event.source = AnimationTimer Then
			UpdateAnimations()
			Return Null ' event handled
		EndIf
		
		Return data
	End Function
	
	Function EnableAutoUpdate()
		AddHook(EmitEventHook, Animation.tick_UpdateAnimations, Null, 1000)
	End Function
	
	Function DisableAutoUpdate()
		RemoveHook(EmitEventHook, Animation.tick_UpdateAnimations, Null)
	End Function
End Type

Function Animate(obj:Object, value$, newvalue!, duration!=5000, fn:Double(start:Double, finish:Double, time:Double)=Null)
	Local a:Animation
	
	?Threaded
	AnimationsLock.Lock
	?
	
	If Not Animation.Animations.IsEmpty() Then
		For a = EachIn Animation.Animations
			If a.o = obj And a.f.Name().ToLower() = value.ToLower() Then
				a.start = a.f.GetDouble(obj)
				a.finish = newvalue
				a.duration = duration
				a.stime = Millisecs()
				?Threaded
				AnimationsLock.Unlock
				?
				Return
			EndIf
		Next
	EndIf
	
	a = New Animation
	a.o = obj
	a.f = TTypeID.ForObject(obj).FindField(value)
	a.duration = duration
	a.stime = Millisecs()
	a.start = a.f.GetDouble(obj)
	a.finish = newvalue
	a.fn = fn
	Animation.Animations.AddLast(a)
	
	?Threaded
	AnimationsLock.Unlock
	?
End Function

Comments

None.

Code Archives Forum