"""
This module defines the interface for animating an expression.
.. autoclass:: Animate
:members:
:undoc-members:
:show-inheritance:
"""
from __future__ import division
import time
from scipy import interpolate
[docs]class Animate(object):
[docs] def __init__(self, times, values):
"""
Class to facilitate the tweening of values in time. The animation starts when the object is created. Once ended, the call method will return the last item in values.
:param list times: A list of timestamps in seconds, in increasing order. Timestamp 0 is the moment the Animate object was created.
:param list values: A list of numerical values associated with timestamps. First element should be 0.
"""
self._start_time = time.time()
self._end_time = self._start_time + times[-1]
self._end_value = values[-1]
# if animation time is < or = 0, do not interpolate
if times[-1] <= 0:
return
times_offset = [t + self._start_time for t in times]
self._iplt = interpolate.interp1d(
times_offset,
values,
kind="linear",
bounds_error=False,
fill_value=values[-1])
def __call__(self):
"""
Calculates and returns the current value of the animation.
"""
if self.has_ended():
return self._end_value
# .item() is called so that a values type is returned. Otherwise _iplt
# returns a 0D numpy array.
return self._iplt(time.time()).item()
[docs] def has_ended(self):
"""
Returns true if the animation has ended.
"""
return time.time() > self._end_time
[docs]class AnimatePeriodic(object):
[docs] def __init__(self, times, values):
"""
Class to facilitate the tweening of values in time. The animation starts
when the object is created. This class is a variant of the Animate class
that does not end, but instead repeats its pattern indefinitely.
:param list times: A list of timestamps in seconds, in increasing order. Timestamp 0 is the moment the Animate object was created.
:param list values: A list of numerical values associated with timestamps. First element should be 0.
"""
self._start_time = time.time()
self._period = times[-1]
self._iplt = interpolate.interp1d(
times,
values,
kind="linear",
bounds_error=False,
fill_value=values[-1])
def __call__(self):
"""
Calculates and returns the current value of the animation.
"""
t = time.time() - self._start_time
t = t % self._period
return self._iplt(t).item()