# -*- coding: utf-8 -*- module Lotu class InterpolationSystem < System def initialize(user, opts={}) super user.extend(UserMethods) @interpolations = [] @tagged_for_deletion = [] end def interpolate(object, property, opts) interpolation = { :object => object, :property_getter => property, :property_setter => "#{property}=", :accum_time => 0, :calc => 0, :init => Float(opts[:init]), :end => Float(opts[:end]), :duration => opts[:duration] || 1, :start_in => opts[:start_in] || 0, :on_result => opts[:on_result], :loop => opts[:loop], :bounce => opts[:bounce], :bouncing_back => false } @interpolations << interpolation end # TODO: incluir código para :loop_for => n def update @interpolations.each do |t| t[:accum_time] += dt if t[:accum_time] > t[:start_in] step = (t[:end] - t[:init])/t[:duration] * dt t[:calc] += step tag_for_deletion(t) if step == 0 if(t[:init] + t[:calc] > t[:end] && step > 0) || (t[:init] + t[:calc] < t[:end] && step < 0) if t[:loop] || (t[:bounce] && !t[:bouncing_back]) t[:calc] = 0 else t[:calc] = t[:end] - t[:init] tag_for_deletion(t) end if t[:bounce] t[:bouncing_back] = !t[:bouncing_back] t[:init], t[:end] = t[:end], t[:init] end end value = t[:init] + t[:calc] value = value.send(t[:on_result]) if t[:on_result] t[:object].send(t[:property_setter], value) end end @tagged_for_deletion.each do |to_delete| @interpolations.delete(to_delete) end.clear end def tag_for_deletion(interpolation) @tagged_for_deletion << interpolation end def to_s ["@interpolations.length #{@interpolations.length}", "@tagged_for_deletion.length #{@tagged_for_deletion.length}"] end module UserMethods def interpolate(object, property, opts) @systems[InterpolationSystem].interpolate(object, property, opts) end # Image helpers def interpolate_angle(opts) interpolate(self, :angle, opts) end def interpolate_width(opts) interpolate(self, :width, opts) end def interpolate_height(opts) interpolate(self, :height, opts) end # Color helpers def interpolate_alpha(opts) interpolate(@color, :alpha, opts.merge!(:on_result => :to_i)) end def interpolate_red(opts) interpolate(@color, :red, opts.merge!(:on_result => :to_i)) end def interpolate_green(opts) interpolate(@color, :green, opts.merge!(:on_result => :to_i)) end def interpolate_blue(opts) interpolate(@color, :blue, opts.merge!(:on_result => :to_i)) end def interpolate_hue(opts) interpolate(@color, :hue, opts) end def interpolate_saturation(opts) interpolate(@color, :saturation, opts) end def interpolate_value(opts) interpolate(@color, :value, opts) end end end end