python-lottie  0.6.11+devc144cca
A framework to work with lottie files and telegram animated stickers (tgs)
properties.py
Go to the documentation of this file.
1 import math
2 from functools import reduce
3 from .base import LottieObject, LottieProp, PseudoList, PseudoBool
4 from . import easing
5 from ..nvector import NVector
6 from .bezier import Bezier
7 from ..utils.color import Color
8 
9 
11  NEWTON_ITERATIONS = 4
12  NEWTON_MIN_SLOPE = 0.001
13  SUBDIVISION_PRECISION = 0.0000001
14  SUBDIVISION_MAX_ITERATIONS = 10
15  SPLINE_TABLE_SIZE = 11
16  SAMPLE_STEP_SIZE = 1.0 / (SPLINE_TABLE_SIZE - 1.0)
17 
18  def __init__(self, h1, h2):
19  self.h1 = h1
20  self.h2 = h2
21  self._sample_values = None
22 
23  @classmethod
24  def from_keyframe(cls, keyframe):
25  return cls(keyframe.out_value, keyframe.in_value)
26 
27  def bezier(self):
28  bez = Bezier()
29  bez.add_point(NVector(0, 0), outp=NVector(self.h1.x, self.h1.y))
30  bez.add_point(NVector(1, 1), inp=NVector(self.h2.x-1, self.h2.y-1))
31  return bez
32 
33  def _a(self, c1, c2):
34  return 1 - 3 * c2 + 3 * c1
35 
36  def _b(self, c1, c2):
37  return 3 * c2 - 6 * c1
38 
39  def _c(self, c1):
40  return 3 * c1
41 
42  def _bezier_component(self, t, c1, c2):
43  return ((self._a(c1, c2) * t + self._b(c1, c2)) * t + self._c(c1)) * t
44 
45  def point_at(self, t):
46  return NVector(
47  self._bezier_component(t, self.h1.x, self.h2.x),
48  self._bezier_component(t, self.h1.y, self.h2.y)
49  )
50 
51  def _slope_component(self, t, c1, c2):
52  return 3 * self._a(c1, c2) * t * t + 2 * self._b(c1, c2) * t + self._c(c1)
53 
54  def slope_at(self, t):
55  return NVector(
56  self._slope_component(t, self.h1.x, self.h2.x),
57  self._slope_component(t, self.h1.y, self.h2.y)
58  )
59 
60  def _binary_subdivide(self, x, interval_start, interval_end):
61  current_x = None
62  t = None
63  i = 0
64  for i in range(self.SUBDIVISION_MAX_ITERATIONS):
65  if current_x is not None and abs(current_x) < self.SUBDIVISION_PRECISION:
66  break
67  t = interval_start + (interval_end - interval_start) / 2.0
68  current_x = self._bezier_component(t, self.h1.x, self.h2.x) - x
69  if current_x > 0.0:
70  interval_end = t
71  else:
72  interval_start = t
73  return t
74 
75  def _newton_raphson(self, x, t_guess):
76  for i in range(self.NEWTON_ITERATIONS):
77  slope = self._slope_component(t_guess, self.h1.x, self.h2.x)
78  if slope == 0:
79  return t_guess
80  current_x = self._bezier_component(t_guess, self.h1.x, self.h2.x) - x
81  t_guess -= current_x / slope
82  return t_guess
83 
84  def _get_sample_values(self):
85  if self._sample_values is None:
86  self._sample_values = [
87  self._bezier_component(i * self.SAMPLE_STEP_SIZE, self.h1.x, self.h2.x)
88  for i in range(self.SPLINE_TABLE_SIZE)
89  ]
90  return self._sample_values
91 
92  def t_for_x(self, x):
93  sample_values = self._get_sample_values()
94  interval_start = 0
95  current_sample = 1
96  last_sample = self.SPLINE_TABLE_SIZE - 1
97  while current_sample != last_sample and sample_values[current_sample] <= x:
98  interval_start += self.SAMPLE_STEP_SIZE
99  current_sample += 1
100  current_sample -= 1
101 
102  dist = (x - sample_values[current_sample]) / (sample_values[current_sample+1] - sample_values[current_sample])
103  t_guess = interval_start + dist * self.SAMPLE_STEP_SIZE
104  initial_slope = self._slope_component(t_guess, self.h1.x, self.h2.x)
105  if initial_slope >= self.NEWTON_MIN_SLOPE:
106  return self._newton_raphson(x, t_guess)
107  if initial_slope == 0:
108  return t_guess
109  return self._binary_subdivide(x, interval_start, interval_start + self.SAMPLE_STEP_SIZE)
110 
111  def y_at_x(self, x):
112  t = self.t_for_x(x)
113  return self._bezier_component(t, self.h1.y, self.h2.y)
114 
115 
116 ## @ingroup Lottie
118  _props = [
119  LottieProp("time", "t", float, False),
120  LottieProp("in_value", "i", easing.KeyframeBezierHandle, False),
121  LottieProp("out_value", "o", easing.KeyframeBezierHandle, False),
122  LottieProp("jump", "h", PseudoBool),
123  ]
124 
125  def __init__(self, time=0, easing_function=None):
126  """!
127  @param time Start time of keyframe segment
128  @param easing_function Callable that performs the easing
129  """
130  ## Start time of keyframe segment.
131  self.time = time
132  ## Bezier curve easing in value.
133  self.in_value = None
134  ## Bezier curve easing out value.
135  self.out_value = None
136  ## Jump to the end value
137  self.jump = None
138 
139  if easing_function:
140  easing_function(self)
141 
142  def bezier(self):
143  if self.jump:
144  bez = Bezier()
145  bez.add_point(NVector(0, 0))
146  bez.add_point(NVector(1, 0))
147  bez.add_point(NVector(1, 1))
148  return bez
149  else:
150  return KeyframeBezier.from_keyframe(self).bezier()
151 
152  def lerp_factor(self, ratio):
153  return KeyframeBezier.from_keyframe(self).y_at_x(ratio)
154 
155  def __str__(self):
156  return "%s %s" % (self.time, self.start)
157 
158 
159 ## @ingroup Lottie
161  """!
162  Keyframe for MultiDimensional values
163 
164  @par Bezier easing
165  @parblock
166  Imagine a quadratic bezier, with starting point at (0, 0) and end point at (1, 1).
167 
168  @p out_value and @p in_value are the other two handles for a quadratic bezier,
169  expressed as absolute values in this 0-1 space.
170 
171  See also https://cubic-bezier.com/
172  @endparblock
173  """
174  _props = [
175  LottieProp("start", "s", NVector, False),
176  LottieProp("end", "e", NVector, False),
177  ]
178 
179  def __init__(self, time=0, start=None, end=None, easing_function=None, in_tan=None, out_tan=None):
180  Keyframe.__init__(self, time, easing_function)
181  ## Start value of keyframe segment.
182  self.start = start
183  ## End value of keyframe segment.
184  self.end = end
185  ## In Spatial Tangent. Only for spatial properties. (for bezier smoothing on position)
186  self.in_tan = in_tan
187  ## Out Spatial Tangent. Only for spatial properties. (for bezier smoothing on position)
188  self.out_tan = out_tan
189 
190  def interpolated_value(self, ratio, next_start=None):
191  end = next_start if self.end is None else self.end
192  if end is None:
193  return self.start
194  if not self.in_value or not self.out_value:
195  return self.start
196  if ratio == 1:
197  return end
198  if ratio == 0:
199  return self.start
200  if self.in_tan and self.out_tan:
201  bezier = Bezier()
202  bezier.add_point(self.start, NVector(0, 0), self.out_tan)
203  bezier.add_point(end, self.in_tan, NVector(0, 0))
204  return bezier.point_at(ratio)
205 
206  lerpv = self.lerp_factor(ratio)
207  return self.start.lerp(end, lerpv)
208 
209  def interpolated_tangent_angle(self, ratio, next_start=None):
210  end = next_start if self.end is None else self.end
211  if end is None or not self.in_tan or not self.out_tan:
212  return 0
213 
214  bezier = Bezier()
215  bezier.add_point(self.start, NVector(0, 0), self.out_tan)
216  bezier.add_point(end, self.in_tan, NVector(0, 0))
217  return bezier.tangent_angle_at(ratio)
218 
219  def __repr__(self):
220  return "<%s.%s %s %s%s>" % (
221  type(self).__module__,
222  type(self).__name__,
223  self.time,
224  self.start,
225  (" -> %s" % self.end) if self.end is not None else ""
226  )
227 
228 
230  keyframe_type = Keyframe
231 
232  def __init__(self, value=None):
233  ## Non-animated value
234  self.value = value
235  ## Property index
236  self.property_index = None
237  ## Whether it's animated
238  self.animated = False
239  ## Keyframe list
240  self.keyframes = None
241  ## Expression
242  self.expression = None
243 
244  def clear_animation(self, value):
245  """!
246  Sets a fixed value, removing animated keyframes
247  """
248  self.value = value
249  self.animated = False
250  self.keyframes = None
251 
252  def add_keyframe(self, time, value, interp=easing.Linear(), *args, **kwargs):
253  """!
254  @param time The time this keyframe appears in
255  @param value The value the property should have at @p time
256  @param interp The easing callable used to update the tangents of the previous keyframe
257  @param args Extra arguments to pass the keyframe constructor
258  @param kwargs Extra arguments to pass the keyframe constructor
259  @note Always call add_keyframe with increasing @p time value
260  """
261  if not self.animated:
262  self.value = None
263  self.keyframes = []
264  self.animated = True
265  else:
266  if self.keyframes[-1].time == time:
267  if value != self.keyframes[-1].start:
268  self.keyframes[-1].start = value
269  return
270  else:
271  self.keyframes[-1].end = value.clone()
272 
273  self.keyframes.append(self.keyframe_type(
274  time,
275  value,
276  None,
277  interp,
278  *args,
279  **kwargs
280  ))
281 
282  def get_value(self, time=0):
283  """!
284  @brief Returns the value of the property at the given frame/time
285  """
286  if not self.animated:
287  return self.value
288 
289  if not self.keyframes:
290  return None
291 
292  return self._get_value_helper(time)[0]
293 
294  def _get_value_helper(self, time):
295  val = self.keyframes[0].start
296  for i in range(len(self.keyframes)):
297  k = self.keyframes[i]
298  if time - k.time <= 0:
299  if k.start is not None:
300  val = k.start
301 
302  kp = self.keyframes[i-1] if i > 0 else None
303  if kp:
304  t = (time - kp.time) / (k.time - kp.time)
305  end = kp.end
306  if end is None:
307  end = val
308  if end is not None:
309  val = kp.interpolated_value(t, end)
310  return val, end, kp, t
311  return val, None, None, None
312  if k.end is not None:
313  val = k.end
314  return val, None, None, None
315 
316  def to_dict(self):
317  d = super().to_dict()
318  if self.animated:
319  if "k" not in d:
320  return d
321  last = d["k"][-1]
322  last.pop("i", None)
323  last.pop("o", None)
324  return d
325 
326  def __repr__(self):
327  if self.keyframes and len(self.keyframes) > 1:
328  val = "%s -> %s" % (self.keyframes[0].start, self.keyframes[-2].end)
329  else:
330  val = self.value
331  return "<%s.%s %s>" % (type(self).__module__, type(self).__name__, val)
332 
333  def __str__(self):
334  if self.animated:
335  return "animated"
336  return str(self.value)
337 
338  @classmethod
339  def merge_keyframes(cls, items, conversion):
340  """
341  @todo Remove similar functionality from SVG/sif parsers
342  """
343  keyframes = []
344  for animatable in items:
345  if animatable.animated:
346  keyframes.extend(animatable.keyframes)
347 
348  # TODO properly interpolate tangents
349  new_kframes = []
350  for keyframe in sorted(keyframes, key=lambda kf: kf.time):
351  if new_kframes and new_kframes[-1].time == keyframe.time:
352  continue
353  kfcopy = keyframe.clone()
354  kfcopy.start = conversion(*(i.get_value(keyframe.time) for i in items))
355  new_kframes.append(kfcopy)
356 
357  for i in range(0, len(new_kframes) - 1):
358  new_kframes[i].end = new_kframes[i+1].start
359 
360  return new_kframes
361 
362  @classmethod
363  def load(cls, lottiedict):
364  obj = super().load(lottiedict)
365  if "a" not in lottiedict:
366  obj.animated = prop_animated(lottiedict)
367  return obj
368 
369 
371  if "a" in l:
372  return l["a"]
373  if "k" not in l:
374  return False
375  if isinstance(l["k"], list) and l["k"] and isinstance(l["k"][0], dict):
376  return True
377  return False
378 
379 
381  return not prop_animated(l)
382 
383 
384 ## @ingroup Lottie
386  """!
387  An animatable property that holds a NVector
388  """
389  keyframe_type = OffsetKeyframe
390  _props = [
391  LottieProp("value", "k", NVector, False, prop_not_animated),
392  LottieProp("property_index", "ix", int, False),
393  LottieProp("animated", "a", PseudoBool, False),
394  LottieProp("keyframes", "k", OffsetKeyframe, True, prop_animated),
395  LottieProp("expression", "x", str, False),
396  ]
397 
398  def get_tangent_angle(self, time=0):
399  """!
400  @brief Returns the value tangent angle of the property at the given frame/time
401  """
402  if not self.keyframes or len(self.keyframes) < 2:
403  return 0
404 
405  val, end, kp, t = self._get_value_helper(time)
406  if kp:
407  return kp.interpolated_tangent_angle(t, end)
408 
409  if self.keyframes[0].time >= time:
410  end = self.keyframes[0].end if self.keyframes[0].end is not None else self.keyframes[1].start
411  return self.keyframes[0].interpolated_tangent_angle(0, end)
412 
413  return 0
414 
415 
416 ## @ingroup Lottie
418  """!
419  Keyframe for Positional values
420  """
421  _props = [
422  LottieProp("in_tan", "ti", NVector, False),
423  LottieProp("out_tan", "to", NVector, False),
424  ]
425 
426 
428  keyframe_type = PositionKeyframe
429  _props = [
430  LottieProp("value", "k", NVector, False, prop_not_animated),
431  LottieProp("property_index", "ix", int, False),
432  LottieProp("animated", "a", PseudoBool, False),
433  LottieProp("keyframes", "k", OffsetKeyframe, True, prop_animated),
434  ]
435 
436  @classmethod
437  def load(cls, lottiedict):
438  obj = super().load(lottiedict)
439  if lottiedict.get("s", False):
440  cls._load_split(lottiedict, obj)
441 
442  return obj
443 
444  @classmethod
445  def _load_split(cls, lottiedict, obj):
446  components = [
447  Value.load(lottiedict.get("x", {})),
448  Value.load(lottiedict.get("y", {})),
449  ]
450  if "z" in lottiedict:
451  components.append(Value.load(lottiedict.get("z", {})))
452 
453  has_anim = any(x for x in components if x.animated)
454  if not has_anim:
455  obj.value = NVector(*(a.value for a in components))
456  obj.animated = False
457  obj.keyframes = None
458  return
459 
460  obj.animated = True
461  obj.value = None
462  obj.keyframes = cls.merge_keyframes(components, NVector)
463 
464 
466  """!
467  An animatable property that holds a Color
468  """
469  keyframe_type = OffsetKeyframe
470  _props = [
471  LottieProp("value", "k", Color, False, prop_not_animated),
472  LottieProp("property_index", "ix", int, False),
473  LottieProp("animated", "a", PseudoBool, False),
474  LottieProp("keyframes", "k", OffsetKeyframe, True, prop_animated),
475  LottieProp("expression", "x", str, False),
476  ]
477 
478 
479 ## @ingroup Lottie
481  """!
482  Represents colors and offsets in a gradient
483 
484  Colors are represented as a flat list interleaving offsets and color components in weird ways
485  There are two possible layouts:
486 
487  Without alpha, the colors are a sequence of offset, r, g, b
488 
489  With alpha, same as above but at the end of the list there is a sequence of offset, alpha
490 
491  Examples:
492 
493  For the gradient [0, red], [0.5, yellow], [1, green]
494  The list would be [0, 1, 0, 0, 0.5, 1, 1, 0, 1, 0, 1, 0]
495 
496  For the gradient [0, red at 80% opacity], [0.5, yellow at 70% opacity], [1, green at 60% opacity]
497  The list would be [0, 1, 0, 0, 0.5, 1, 1, 0, 1, 0, 1, 0, 0, 0.8, 0.5, 0.7, 1, 0.6]
498  """
499  _props = [
500  LottieProp("colors", "k", MultiDimensional),
501  LottieProp("count", "p", int),
502  ]
503 
504  def __init__(self, stops=[]):
505  ## Animatable colors, as a vector containing [offset, r, g, b] values as a flat array
507  ## Number of colors
508  self.count = 0
509  if stops:
510  self.set_stops(stops)
511 
512  @staticmethod
513  def color_to_stops(self, colors):
514  """
515  Converts a list of colors (Color) to tuples (offset, color)
516  """
517  return [
518  (i / (len(colors)-1), color)
519  for i, color in enumerate(colors)
520  ]
521 
522  def set_stops(self, stops, keyframe=None):
523  """!
524  @param stops iterable of (offset, Color) tuples
525  @param keyframe keyframe index (or None if not animated)
526  """
527  flat = self._flatten_stops(stops)
528  if self.colors.animated and keyframe is not None:
529  if keyframe > 1:
530  self.colors.keyframes[keyframe-1].end = flat
531  self.colors.keyframes[keyframe].start = flat
532  else:
533  self.colors.clear_animation(flat)
534  self.count = len(stops)
535 
536  def _flatten_stops(self, stops):
537  flattened_colors = NVector(*reduce(
538  lambda a, b: a + b,
539  (
540  [off] + color.components[:3]
541  for off, color in stops
542  )
543  ))
544 
545  if any(len(c) > 3 for o, c in stops):
546  flattened_colors.components += reduce(
547  lambda a, b: a + b,
548  (
549  [off] + [self._get_alpha(color)]
550  for off, color in stops
551  )
552  )
553  return flattened_colors
554 
555  def _get_alpha(self, color):
556  if len(color) > 3:
557  return color[3]
558  return 1
559 
560  def _add_to_flattened(self, offset, color, flattened):
561  flat = [offset] + list(color[:3])
562  rgb_size = 4 * self.count
563 
564  if len(flattened) == rgb_size:
565  # No alpha
566  flattened.extend(flat)
567  if self.count == 0 and len(color) > 3:
568  flattened.append(offset)
569  flattened.append(color[3])
570  else:
571  flattened[rgb_size:rgb_size] = flat
572  flattened.append(offset)
573  flattened.append(self._get_alpha(color))
574 
575  def add_color(self, offset, color, keyframe=None):
576  if self.colors.animated:
577  if keyframe is None:
578  for kf in self.colors.keyframes:
579  if kf.start:
580  self._add_to_flattened(offset, color, kf.start.components)
581  if kf.end:
582  self._add_to_flattened(offset, color, kf.end.components)
583  else:
584  if keyframe > 1:
585  self._add_to_flattened(offset, color, self.colors.keyframes[keyframe-1].end.components)
586  self._add_to_flattened(offset, color, self.colors.keyframes[keyframe].start.components)
587  else:
588  self._add_to_flattened(offset, color, self.colors.value.components)
589  self.count += 1
590 
591  def add_keyframe(self, time, stops, ease=easing.Linear()):
592  """!
593  @param time Frame time
594  @param stops Iterable of (offset, Color) tuples
595  @param ease Easing function
596  """
597  self.colors.add_keyframe(time, self._flatten_stops(stops), ease)
598 
599  def get_stops(self, keyframe=None):
600  if keyframe is not None:
601  colors = self.colors.keyframes[keyframe].start
602  else:
603  colors = self.colors.value
604  return self._stops_from_flat(colors)
605 
606  def _stops_from_flat(self, colors):
607  if len(colors) == 4 * self.count:
608  for i in range(self.count):
609  off = i * 4
610  yield colors[off], Color(*colors[off+1:off+4])
611  else:
612  for i in range(self.count):
613  off = i * 4
614  aoff = self.count * 4 + i * 2 + 1
615  yield colors[off], Color(colors[off+1], colors[off+2], colors[off+3], colors[aoff])
616 
617  def stops_at(self, time):
618  return self._stops_from_flat(self.colors.get_value(time))
619 
620 
621 ## @ingroup Lottie
623  """!
624  An animatable property that holds a float
625  """
626  keyframe_type = OffsetKeyframe
627  _props = [
628  LottieProp("value", "k", float, False, prop_not_animated),
629  LottieProp("property_index", "ix", int, False),
630  LottieProp("animated", "a", PseudoBool, False),
631  LottieProp("keyframes", "k", keyframe_type, True, prop_animated),
632  LottieProp("expression", "x", str, False),
633  ]
634 
635  def __init__(self, value=0):
636  super().__init__(value)
637 
638  def add_keyframe(self, time, value, ease=easing.Linear()):
639  super().add_keyframe(time, NVector(value), ease)
640 
641  def get_value(self, time=0):
642  v = super().get_value(time)
643  if self.animated and self.keyframes:
644  return v[0]
645  return v
646 
647 
648 ## @ingroup Lottie
650  """!
651  Keyframe holding Bezier objects
652  """
653  _props = [
654  LottieProp("start", "s", Bezier, PseudoList),
655  LottieProp("end", "e", Bezier, PseudoList),
656  ]
657 
658  def __init__(self, time=0, start=None, end=None, easing_function=None):
659  Keyframe.__init__(self, time, easing_function)
660  ## Start value of keyframe segment.
661  self.start = start
662  ## End value of keyframe segment.
663  self.end = end
664 
665  def interpolated_value(self, ratio, next_start=None):
666  end = next_start if self.end is None else self.end
667  if end is None:
668  return self.start
669  if not self.in_value or not self.out_value:
670  return self.start
671  if ratio == 1:
672  return end
673  if ratio == 0 or len(self.start.vertices) != len(end.vertices):
674  return self.start
675 
676  lerpv = self.lerp_factor(ratio)
677  bez = Bezier()
678  bez.closed = self.start.closed
679  for i in range(len(self.start.vertices)):
680  bez.vertices.append(self.start.vertices[i].lerp(end.vertices[i], lerpv))
681  bez.in_tangents.append(self.start.in_tangents[i].lerp(end.in_tangents[i], lerpv))
682  bez.out_tangents.append(self.start.out_tangents[i].lerp(end.out_tangents[i], lerpv))
683  return bez
684 
685 
686 ## @ingroup Lottie
688  """!
689  An animatable property that holds a Bezier
690  """
691  keyframe_type = ShapePropKeyframe
692  _props = [
693  LottieProp("value", "k", Bezier, False, prop_not_animated),
694  LottieProp("expression", "x", str, False),
695  LottieProp("property_index", "ix", float, False),
696  LottieProp("animated", "a", PseudoBool, False),
697  LottieProp("keyframes", "k", keyframe_type, True, prop_animated),
698  ]
699 
700  def __init__(self, bezier=None):
701  super().__init__(bezier or Bezier())
702 
703 
704 #ingroup Lottie
706  """!
707  An animatable property that is split into individually anaimated components
708  """
709  _props = [
710  LottieProp("split", "s", bool, False),
711  LottieProp("x", "x", Value, False),
712  LottieProp("y", "y", Value, False),
713  LottieProp("z", "z", Value, False),
714  ]
715 
716  @property
717  def split(self):
718  return True
719 
720  def __init__(self, x=0, y=0):
721  super().__init__()
722 
723  self.x = Value(x)
724  self.y = Value(y)
725  self.z = None
lottie.objects.properties.GradientColors.__init__
def __init__(self, stops=[])
Definition: properties.py:504
lottie.utils.color.Color
Definition: color.py:368
lottie.objects.properties.KeyframeBezier.NEWTON_ITERATIONS
int NEWTON_ITERATIONS
Definition: properties.py:11
lottie.objects.properties.AnimatableMixin.__init__
def __init__(self, value=None)
Definition: properties.py:232
lottie.objects.properties.KeyframeBezier._bezier_component
def _bezier_component(self, t, c1, c2)
Definition: properties.py:42
lottie.objects.properties.KeyframeBezier.y_at_x
def y_at_x(self, x)
Definition: properties.py:111
lottie.objects.properties.Keyframe.lerp_factor
def lerp_factor(self, ratio)
Definition: properties.py:152
lottie.objects.properties.AnimatableMixin.__repr__
def __repr__(self)
Definition: properties.py:326
lottie.objects.properties.Value
An animatable property that holds a float.
Definition: properties.py:622
lottie.objects.properties.Value.get_value
def get_value(self, time=0)
Returns the value of the property at the given frame/time.
Definition: properties.py:641
lottie.objects.properties.ShapePropKeyframe.end
end
End value of keyframe segment.
Definition: properties.py:663
lottie.objects.properties.GradientColors._flatten_stops
def _flatten_stops(self, stops)
Definition: properties.py:536
lottie.objects.properties.OffsetKeyframe.end
end
End value of keyframe segment.
Definition: properties.py:184
lottie.objects.properties.GradientColors._stops_from_flat
def _stops_from_flat(self, colors)
Definition: properties.py:606
lottie.objects.properties.Keyframe
Definition: properties.py:117
lottie.objects.properties.KeyframeBezier._a
def _a(self, c1, c2)
Definition: properties.py:33
lottie.objects.properties.Value.add_keyframe
def add_keyframe(self, time, value, ease=easing.Linear())
Definition: properties.py:638
lottie.objects.properties.GradientColors.colors
colors
Animatable colors, as a vector containing [offset, r, g, b] values as a flat array.
Definition: properties.py:506
lottie.objects.properties.SplitVector.x
x
Definition: properties.py:723
lottie.objects.properties.ShapePropKeyframe.__init__
def __init__(self, time=0, start=None, end=None, easing_function=None)
Definition: properties.py:658
lottie.objects.properties.KeyframeBezier.NEWTON_MIN_SLOPE
float NEWTON_MIN_SLOPE
Definition: properties.py:12
lottie.objects.bezier.Bezier
Single bezier curve.
Definition: bezier.py:123
lottie.objects.properties.SplitVector.__init__
def __init__(self, x=0, y=0)
Definition: properties.py:720
lottie.objects.properties.AnimatableMixin
Definition: properties.py:229
lottie.objects.properties.ShapePropKeyframe.start
start
Start value of keyframe segment.
Definition: properties.py:661
lottie.objects.properties.OffsetKeyframe.start
start
Start value of keyframe segment.
Definition: properties.py:182
lottie.objects.properties.KeyframeBezier.t_for_x
def t_for_x(self, x)
Definition: properties.py:92
lottie.objects.properties.OffsetKeyframe.in_tan
in_tan
In Spatial Tangent.
Definition: properties.py:186
lottie.objects.properties.PositionValue._load_split
def _load_split(cls, lottiedict, obj)
Definition: properties.py:445
lottie.objects.properties.OffsetKeyframe
Keyframe for MultiDimensional values.
Definition: properties.py:160
lottie.objects.properties.ShapeProperty
An animatable property that holds a Bezier.
Definition: properties.py:687
lottie.objects.properties.PositionValue.load
def load(cls, lottiedict)
Loads from a JSON object.
Definition: properties.py:437
lottie.objects.properties.GradientColors._add_to_flattened
def _add_to_flattened(self, offset, color, flattened)
Definition: properties.py:560
lottie.objects.properties.KeyframeBezier
Definition: properties.py:10
lottie.objects.properties.KeyframeBezier._binary_subdivide
def _binary_subdivide(self, x, interval_start, interval_end)
Definition: properties.py:60
lottie.objects.properties.KeyframeBezier._sample_values
_sample_values
Definition: properties.py:21
lottie.objects.properties.ShapePropKeyframe
Keyframe holding Bezier objects.
Definition: properties.py:649
lottie.objects.properties.KeyframeBezier.SUBDIVISION_MAX_ITERATIONS
int SUBDIVISION_MAX_ITERATIONS
Definition: properties.py:14
lottie.objects.properties.KeyframeBezier.h1
h1
Definition: properties.py:19
lottie.objects.properties.AnimatableMixin.clear_animation
def clear_animation(self, value)
Sets a fixed value, removing animated keyframes.
Definition: properties.py:244
lottie.objects.base.LottieObject
Base class for mapping Python classes into Lottie JSON objects.
Definition: base.py:225
lottie.objects.properties.AnimatableMixin.animated
animated
Whether it's animated.
Definition: properties.py:238
lottie.objects.properties.GradientColors.add_color
def add_color(self, offset, color, keyframe=None)
Definition: properties.py:575
lottie.objects.properties.AnimatableMixin.add_keyframe
def add_keyframe(self, time, value, interp=easing.Linear(), *args, **kwargs)
Definition: properties.py:252
lottie.objects.properties.KeyframeBezier._c
def _c(self, c1)
Definition: properties.py:39
lottie.objects.properties.KeyframeBezier._newton_raphson
def _newton_raphson(self, x, t_guess)
Definition: properties.py:75
lottie.objects.properties.KeyframeBezier.from_keyframe
def from_keyframe(cls, keyframe)
Definition: properties.py:24
lottie.objects.properties.prop_not_animated
def prop_not_animated(l)
Definition: properties.py:380
lottie.objects.easing.KeyframeBezierHandle
Bezier handle for keyframe interpolation.
Definition: easing.py:6
lottie.objects.properties.KeyframeBezier.point_at
def point_at(self, t)
Definition: properties.py:45
lottie.objects.base.LottieProp
Lottie <-> Python property mapper.
Definition: base.py:88
lottie.objects.properties.Keyframe.__str__
def __str__(self)
Definition: properties.py:155
lottie.objects.properties.AnimatableMixin.keyframes
keyframes
Keyframe list.
Definition: properties.py:240
lottie.objects.properties.SplitVector
An animatable property that is split into individually anaimated components.
Definition: properties.py:705
lottie.objects.properties.KeyframeBezier.__init__
def __init__(self, h1, h2)
Definition: properties.py:18
lottie.objects.properties.KeyframeBezier.SAMPLE_STEP_SIZE
float SAMPLE_STEP_SIZE
Definition: properties.py:16
lottie.objects.properties.AnimatableMixin.expression
expression
Expression.
Definition: properties.py:242
lottie.objects.properties.Keyframe.out_value
out_value
Bezier curve easing out value.
Definition: properties.py:135
lottie.objects.properties.MultiDimensional.get_tangent_angle
def get_tangent_angle(self, time=0)
Returns the value tangent angle of the property at the given frame/time.
Definition: properties.py:398
lottie.objects.properties.AnimatableMixin._get_value_helper
def _get_value_helper(self, time)
Definition: properties.py:294
lottie.objects.properties.GradientColors.add_keyframe
def add_keyframe(self, time, stops, ease=easing.Linear())
Definition: properties.py:591
lottie.objects.properties.AnimatableMixin.property_index
property_index
Property index.
Definition: properties.py:236
lottie.objects.properties.GradientColors.color_to_stops
def color_to_stops(self, colors)
Definition: properties.py:513
lottie.objects.properties.OffsetKeyframe.interpolated_tangent_angle
def interpolated_tangent_angle(self, ratio, next_start=None)
Definition: properties.py:209
lottie.objects.properties.ShapePropKeyframe.interpolated_value
def interpolated_value(self, ratio, next_start=None)
Definition: properties.py:665
lottie.objects.properties.KeyframeBezier._get_sample_values
def _get_sample_values(self)
Definition: properties.py:84
lottie.objects.properties.KeyframeBezier._b
def _b(self, c1, c2)
Definition: properties.py:36
lottie.objects.properties.Value.__init__
def __init__(self, value=0)
Definition: properties.py:635
lottie.objects.properties.KeyframeBezier._slope_component
def _slope_component(self, t, c1, c2)
Definition: properties.py:51
lottie.objects.properties.GradientColors.stops_at
def stops_at(self, time)
Definition: properties.py:617
lottie.objects.properties.AnimatableMixin.load
def load(cls, lottiedict)
Definition: properties.py:363
lottie.objects.properties.KeyframeBezier.SPLINE_TABLE_SIZE
int SPLINE_TABLE_SIZE
Definition: properties.py:15
lottie.objects.properties.AnimatableMixin.get_value
def get_value(self, time=0)
Returns the value of the property at the given frame/time.
Definition: properties.py:282
lottie.objects.properties.AnimatableMixin.keyframe_type
keyframe_type
Definition: properties.py:230
lottie.objects.properties.GradientColors.set_stops
def set_stops(self, stops, keyframe=None)
Definition: properties.py:522
lottie.objects.properties.SplitVector.z
z
Definition: properties.py:725
lottie.objects.properties.OffsetKeyframe.__init__
def __init__(self, time=0, start=None, end=None, easing_function=None, in_tan=None, out_tan=None)
Definition: properties.py:179
lottie.objects.properties.GradientColors
Represents colors and offsets in a gradient.
Definition: properties.py:480
lottie.objects.properties.prop_animated
def prop_animated(l)
Definition: properties.py:370
lottie.objects.properties.SplitVector.y
y
Definition: properties.py:724
lottie.objects.properties.GradientColors.get_stops
def get_stops(self, keyframe=None)
Definition: properties.py:599
lottie.objects.properties.Keyframe.bezier
def bezier(self)
Definition: properties.py:142
lottie.objects.properties.GradientColors.count
count
Number of colors.
Definition: properties.py:508
lottie.objects.properties.Keyframe.in_value
in_value
Bezier curve easing in value.
Definition: properties.py:133
lottie.objects.properties.GradientColors._get_alpha
def _get_alpha(self, color)
Definition: properties.py:555
lottie.objects.properties.MultiDimensional
An animatable property that holds a NVector.
Definition: properties.py:385
lottie.objects.properties.KeyframeBezier.slope_at
def slope_at(self, t)
Definition: properties.py:54
lottie.objects.properties.SplitVector.split
def split(self)
Definition: properties.py:717
lottie.objects.properties.AnimatableMixin.__str__
def __str__(self)
Definition: properties.py:333
lottie.objects.properties.AnimatableMixin.value
value
Non-animated value.
Definition: properties.py:234
lottie.objects.properties.PositionKeyframe
Keyframe for Positional values.
Definition: properties.py:417
lottie.objects.properties.PositionValue
Definition: properties.py:427
lottie.objects.properties.OffsetKeyframe.interpolated_value
def interpolated_value(self, ratio, next_start=None)
Definition: properties.py:190
lottie.objects.properties.ShapeProperty.__init__
def __init__(self, bezier=None)
Definition: properties.py:700
lottie.objects.properties.AnimatableMixin.merge_keyframes
def merge_keyframes(cls, items, conversion)
Definition: properties.py:339
lottie.objects.properties.OffsetKeyframe.__repr__
def __repr__(self)
Definition: properties.py:219
lottie.objects.properties.KeyframeBezier.bezier
def bezier(self)
Definition: properties.py:27
lottie.objects.properties.AnimatableMixin.to_dict
def to_dict(self)
Definition: properties.py:316
lottie.objects.properties.KeyframeBezier.SUBDIVISION_PRECISION
float SUBDIVISION_PRECISION
Definition: properties.py:13
lottie.objects.properties.OffsetKeyframe.out_tan
out_tan
Out Spatial Tangent.
Definition: properties.py:188
lottie.objects.properties.Keyframe.time
time
Start time of keyframe segment.
Definition: properties.py:131
lottie.objects.properties.Keyframe.__init__
def __init__(self, time=0, easing_function=None)
Definition: properties.py:125
lottie.objects.properties.ColorValue
An animatable property that holds a Color.
Definition: properties.py:465
lottie.objects.properties.Keyframe.jump
jump
Jump to the end value.
Definition: properties.py:137
lottie.objects.properties.KeyframeBezier.h2
h2
Definition: properties.py:20
lottie.nvector.NVector
Definition: nvector.py:9