82 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Odin
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Odin
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import "core:math"
 | 
						|
import "core:math/ease"
 | 
						|
import "core:math/linalg"
 | 
						|
import "core:slice"
 | 
						|
 | 
						|
 | 
						|
Tween :: struct {
 | 
						|
	ptr: ^f32,
 | 
						|
	from: f32,
 | 
						|
	to: f32,
 | 
						|
	time: f32,
 | 
						|
	duration: f32,
 | 
						|
	ease_type: ease.Ease,
 | 
						|
	active: bool,
 | 
						|
	finished: proc(data: rawptr),
 | 
						|
	data: rawptr
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
TWEEN_SIZE :: 128
 | 
						|
tweens_buf: [TWEEN_SIZE]^Tween
 | 
						|
tweens : [dynamic]^Tween
 | 
						|
 | 
						|
tween_init :: proc() {
 | 
						|
	tweens = slice.into_dynamic(tweens_buf[:])
 | 
						|
}
 | 
						|
 | 
						|
tween_clean :: proc() {
 | 
						|
	for tween, i in tweens {
 | 
						|
		free(tween)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
tween_to :: proc(
 | 
						|
		value: ^f32, to: f32, duration: f32,
 | 
						|
		ease: ease.Ease = ease.Ease.Quartic_In_Out,
 | 
						|
		data: rawptr = nil,
 | 
						|
		callback: proc(data: rawptr) = nil
 | 
						|
		) -> ^Tween {
 | 
						|
 | 
						|
	tween := new(Tween) 
 | 
						|
	tween.ptr = value
 | 
						|
	tween.from = value^
 | 
						|
	tween.to = to
 | 
						|
	tween.duration = duration
 | 
						|
	tween.ease_type = ease
 | 
						|
	tween.active = true
 | 
						|
	tween.data = data
 | 
						|
	tween.finished = callback
 | 
						|
 | 
						|
	append(&tweens, tween)
 | 
						|
	return tween
 | 
						|
}
 | 
						|
 | 
						|
tween_cancel :: proc(t: ^Tween) {
 | 
						|
	t.active = false
 | 
						|
}
 | 
						|
 | 
						|
tweens_process :: proc(delta: f32) {
 | 
						|
	#reverse for tween, i in tweens {
 | 
						|
 | 
						|
		tween.time += delta
 | 
						|
		p := clamp(tween.time / tween.duration, 0, 1)
 | 
						|
 | 
						|
		val := ease.ease(tween.ease_type, p)
 | 
						|
		tween.ptr^ = math.lerp(tween.from, tween.to, val)
 | 
						|
 | 
						|
		if tween.time >= tween.duration {
 | 
						|
			tween.active = false
 | 
						|
			if tween.finished != nil {
 | 
						|
				tween.finished(tween.data)
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if !tween.active {
 | 
						|
			free(tween)
 | 
						|
			unordered_remove(&tweens, i)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |