<s> '''<STR_LIT>''' <EOL> __all__ = ( '<STR_LIT>' , ) <EOL> from time import time <EOL> from kivy . event import EventDispatcher <EOL> from kivy . properties import NumericProperty , BooleanProperty <EOL> from kivy . clock import Clock <EOL> class KineticEffect ( EventDispatcher ) : <EOL> '''<STR_LIT>''' <EOL> velocity = NumericProperty ( <NUM_LIT:0> ) <EOL> '''<STR_LIT>''' <EOL> friction = NumericProperty ( <NUM_LIT> ) <EOL> '''<STR_LIT>''' <EOL> value = NumericProperty ( <NUM_LIT:0> ) <EOL> '''<STR_LIT>''' <EOL> is_manual = BooleanProperty ( False ) <EOL> '''<STR_LIT>''' <EOL> max_history = NumericProperty ( <NUM_LIT:5> ) <EOL> '''<STR_LIT>''' <EOL> min_distance = NumericProperty ( <NUM_LIT> ) <EOL> '''<STR_LIT>''' <EOL> min_velocity = NumericProperty ( <NUM_LIT> ) <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , ** kwargs ) : <EOL> self . history = [ ] <EOL> self . trigger_velocity_update = Clock . create_trigger ( <EOL> self . update_velocity , <NUM_LIT:0> ) <EOL> super ( KineticEffect , self ) . __init__ ( ** kwargs ) <EOL> def apply_distance ( self , distance ) : <EOL> if abs ( distance ) < self . min_distance : <EOL> self . velocity = <NUM_LIT:0> <EOL> self . value += distance <EOL> def start ( self , val , t = None ) : <EOL> '''<STR_LIT>''' <EOL> self . is_manual = True <EOL> t = t or time ( ) <EOL> self . velocity = <NUM_LIT:0> <EOL> self . history = [ ( t , val ) ] <EOL> def update ( self , val , t = None ) : <EOL> '''<STR_LIT>''' <EOL> t = t or time ( ) <EOL> distance = val - self . history [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] <EOL> self . apply_distance ( distance ) <EOL> self . history . append ( ( t , val ) ) <EOL> if len ( self . history ) > self . max_history : <EOL> self . history . pop ( <NUM_LIT:0> ) <EOL> def stop ( self , val , t = None ) : <EOL> '''<STR_LIT>''' <EOL> self . is_manual = False <EOL> t = t or time ( ) <EOL> distance = val - self . history [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] <EOL> self . apply_distance ( distance ) <EOL> newest_sample = ( t , val ) <EOL> old_sample = self . history [ <NUM_LIT:0> ] <EOL> for sample in self . history : <EOL> if ( newest_sample [ <NUM_LIT:0> ] - sample [ <NUM_LIT:0> ] ) < <NUM_LIT> / <NUM_LIT> : <EOL> break <EOL> old_sample = sample <EOL> distance = newest_sample [ <NUM_LIT:1> ] - old_sample [ <NUM_LIT:1> ] <EOL> duration = abs ( newest_sample [ <NUM_LIT:0> ] - old_sample [ <NUM_LIT:0> ] ) <EOL> self . velocity = ( distance / max ( duration , <NUM_LIT> ) ) <EOL> self . trigger_velocity_update ( ) <EOL> def cancel ( self ) : <EOL> '''<STR_LIT>''' <EOL> self . is_manual = False <EOL> self . trigger_velocity_update ( ) <EOL> def update_velocity ( self , dt ) : <EOL> '''<STR_LIT>''' <EOL> if abs ( self . velocity ) <= self . min_velocity : <EOL> self . velocity = <NUM_LIT:0> <EOL> return <EOL> self . velocity -= self . velocity * self . friction <EOL> self . apply_distance ( self . velocity * dt ) <EOL> self . trigger_velocity_update ( ) </s>
