python-lottie  0.6.11+devc144cca
A framework to work with lottie files and telegram animated stickers (tgs)
converter.py
Go to the documentation of this file.
1 import math
2 from ... import objects
3 from ...objects import easing
4 from . import api, ast
5 from ... import NVector, PolarVector
6 
7 try:
8  from ...utils import font
9  has_font = True
10 except ImportError:
11  has_font = False
12 
13 
14 def convert(canvas: api.Canvas):
15  return Converter().convert(canvas)
16 
17 
18 class Converter:
19  def __init__(self):
20  pass
21 
22  def _animated(self, sifval):
23  return isinstance(sifval, ast.SifAnimated)
24 
25  def convert(self, canvas: api.Canvas):
26  self.canvas = canvas
28  self._time(canvas.end_time),
29  canvas.fps
30  )
31  self.animation.in_point = self._time(canvas.begin_time)
32  self.animation.width = canvas.width
33  self.animation.height = canvas.height
34  self.view_p1 = NVector(canvas.view_box[0], canvas.view_box[1])
35  self.view_p2 = NVector(canvas.view_box[2], canvas.view_box[3])
36  self.target_size = NVector(canvas.width, canvas.height)
37  self.shape_layer = self.animation.add_layer(objects.ShapeLayer())
38  self.gamma = NVector(canvas.gamma_r, canvas.gamma_g, canvas.gamma_b)
39  self._process_layers(canvas.layers, self.shape_layer)
40  return self.animation
41 
42  def _time(self, t: api.FrameTime):
43  return self.canvas.time_to_frames(t)
44 
45  def _process_layers(self, layers, parent):
46  old_gamma = self.gamma
47 
48  for layer in reversed(layers):
49  if not layer.active:
50  continue
51  elif isinstance(layer, api.GroupLayerBase):
52  parent.add_shape(self._convert_group(layer))
53  elif isinstance(layer, api.RectangleLayer):
54  parent.add_shape(self._convert_fill(layer, self._convert_rect))
55  elif isinstance(layer, api.CircleLayer):
56  parent.add_shape(self._convert_fill(layer, self._convert_circle))
57  elif isinstance(layer, api.StarLayer):
58  parent.add_shape(self._convert_fill(layer, self._convert_star))
59  elif isinstance(layer, api.PolygonLayer):
60  parent.add_shape(self._convert_fill(layer, self._convert_polygon))
61  elif isinstance(layer, api.RegionLayer):
62  parent.add_shape(self._convert_fill(layer, self._convert_bline))
63  elif isinstance(layer, api.AbstractOutline):
64  parent.add_shape(self._convert_outline(layer, self._convert_bline))
65  elif isinstance(layer, api.GradientLayer):
66  parent.add_shape(self._convert_gradient(layer, parent))
67  elif isinstance(layer, api.TransformDown):
68  shape = self._convert_transform_down(layer)
69  parent.add_shape(shape)
70  parent = shape
71  elif isinstance(layer, api.TextLayer):
72  if has_font:
73  parent.add_shape(self._convert_fill(layer, self._convert_text))
74  elif isinstance(layer, api.ColorCorrectLayer):
75  self.gamma = self.gamma * NVector(layer.gamma.value, layer.gamma.value, layer.gamma.value)
76 
77  self.gamma = old_gamma
78 
79  def _convert_group(self, layer: api.GroupLayer):
80  shape = objects.Group()
81  self._set_name(shape, layer)
82  shape.transform.anchor_point = self._adjust_coords(self._convert_vector(layer.origin))
83  self._convert_transform(layer.transformation, shape.transform)
84  self._process_layers(layer.layers, shape)
85  shape.transform.opacity = self._adjust_animated(
86  self._convert_scalar(layer.amount),
87  lambda x: x*100
88  )
89  return shape
90 
91  def _convert_transform(self, sif_transform: api.AbstractTransform, lottie_transform: objects.Transform):
92  if isinstance(sif_transform, api.BoneLinkTransform):
93  base_transform = sif_transform.base_value
94  else:
95  base_transform = sif_transform
96 
97  position = self._adjust_coords(self._convert_vector(base_transform.offset))
98  rotation = self._adjust_angle(self._convert_scalar(base_transform.angle))
99  scale = self._adjust_animated(
100  self._convert_vector(base_transform.scale),
101  lambda x: x * 100
102  )
103 
104  lottie_transform.skew_axis = self._adjust_angle(self._convert_scalar(base_transform.skew_angle))
105 
106  if isinstance(sif_transform, api.BoneLinkTransform):
107  lottie_transform.position = position
108  lottie_transform.rotation = rotation
109  lottie_transform.scale = scale
110  #bone = sif_transform.bone
111  #b_pos = self._adjust_coords(self._convert_vector(bone.origin))
112  #old_anchor = lottie_transform.anchor_point
113 
114  #if sif_transform.translate:
115  #self._mix_animations_into(
116  #[position, b_pos, old_anchor],
117  #lottie_transform.position,
118  #lambda base_p, bone_p, anchor: (anchor-self.target_size/2)/2+self.target_size/2
119  #)
120  #else:
121  #lottie_transform.position = position
122 
123  #lottie_transform.anchor_point = b_pos
124  #lottie_transform.anchor_point.value += NVector(100,0)
125 
126  #if sif_transform.rotate:
127  #b_rot = self._convert_scalar(bone.angle)
128  #self._mix_animations_into([rotation, b_rot], lottie_transform.rotation, lambda a, b: a-b)
129  #else:
130  #lottie_transform.rotation = rotation
131 
132  #if sif_transform.scale_y:
133  #b_scale = self._convert_scalar(bone.scalelx)
134  #self._mix_animations_into(
135  #scale, b_scale, lottie_transform.scale,
136  #lambda a, b: NVector(a.x, a.y * b)
137  #)
138  #else:
139  #lottie_transform.scale = scale
140  else:
141  lottie_transform.position = position
142  lottie_transform.rotation = rotation
143  lottie_transform.scale = scale
144 
145  def _mix_animations_into(self, animations, output, mix):
146  if not any(x.animated for x in animations):
147  output.value = mix(*(x.value for x in animations))
148  else:
149  for vals in self._mix_animations(*animations):
150  time = vals.pop(0)
151  output.add_keyframe(time, mix(*vals))
152 
153  def _convert_fill(self, layer, converter):
154  shape = objects.Group()
155  self._set_name(shape, layer)
156  shape.add_shape(converter(layer))
157  if layer.invert.value:
158  shape.add_shape(objects.Rect(self.target_size/2, self.target_size))
159 
160  fill = objects.Fill()
161  fill.color = self._convert_color(layer.color)
162  fill.opacity = self._adjust_animated(
163  self._convert_scalar(layer.amount),
164  lambda x: x * 100
165  )
166  shape.add_shape(fill)
167  return shape
168 
169  def _convert_linecap(self, lc: api.LineCap):
170  if lc == api.LineCap.Rounded:
171  return objects.LineCap.Round
172  if lc == api.LineCap.Squared:
173  return objects.LineCap.Square
174  return objects.LineCap.Butt
175 
176  def _convert_cusp(self, lc: api.CuspStyle):
177  if lc == api.CuspStyle.Miter:
178  return objects.LineJoin.Miter
179  if lc == api.CuspStyle.Bevel:
180  return objects.LineJoin.Bevel
181  return objects.LineJoin.Round
182 
183  def _convert_outline(self, layer: api.AbstractOutline, converter):
184  shape = objects.Group()
185  self._set_name(shape, layer)
186  shape.add_shape(converter(layer))
187  stroke = objects.Stroke()
188  stroke.color = self._convert_color(layer.color)
189  stroke.line_cap = self._convert_linecap(layer.start_tip)
190  stroke.line_join = self._convert_cusp(layer.cusp_type)
191  stroke.width = self._adjust_scalar(self._convert_scalar(layer.width))
192  shape.add_shape(stroke)
193  return shape
194 
195  def _convert_rect(self, layer: api.RectangleLayer):
196  rect = objects.Rect()
197  p1 = self._adjust_coords(self._convert_vector(layer.point1))
198  p2 = self._adjust_coords(self._convert_vector(layer.point2))
199  if p1.animated or p2.animated:
200  for time, p1v, p2v in self._mix_animations(p1, p2):
201  rect.position.add_keyframe(time, (p1v + p2v) / 2)
202  rect.size.add_keyframe(time, abs(p2v - p1v))
203  pass
204  else:
205  rect.position.value = (p1.value + p2.value) / 2
206  rect.size.value = abs(p2.value - p1.value)
207  rect.rounded = self._adjust_scalar(self._convert_scalar(layer.bevel))
208  return rect
209 
210  def _convert_circle(self, layer: api.CircleLayer):
211  shape = objects.Ellipse()
212  shape.position = self._adjust_coords(self._convert_vector(layer.origin))
213  radius = self._adjust_scalar(self._convert_scalar(layer.radius))
214  shape.size = self._adjust_add_dimension(radius, lambda x: NVector(x, x) * 2)
215  return shape
216 
217  def _convert_star(self, layer: api.StarLayer):
218  shape = objects.Star()
219  shape.position = self._adjust_coords(self._convert_vector(layer.origin))
220  shape.inner_radius = self._adjust_scalar(self._convert_scalar(layer.radius2))
221  shape.outer_radius = self._adjust_scalar(self._convert_scalar(layer.radius1))
222  shape.rotation = self._adjust_animated(
223  self._convert_scalar(layer.angle),
224  lambda x: 90-x
225  )
226  shape.points = self._convert_scalar(layer.points)
227  if layer.regular_polygon.value:
228  shape.star_type = objects.StarType.Polygon
229  return shape
230 
231  def _mix_animations(self, *animatable):
232  times = set()
233  for v in animatable:
234  self._force_animated(v)
235  for kf in v.keyframes:
236  times.add(kf.time)
237 
238  for time in sorted(times):
239  yield [time] + [v.get_value(time) for v in animatable]
240 
241  def _force_animated(self, lottieval):
242  if not lottieval.animated:
243  v = lottieval.value
244  lottieval.add_keyframe(0, v)
245  lottieval.add_keyframe(self.animation.out_point, v)
246 
247  def _convert_easing_part(self, interp: api.Interpolation):
248  if interp == api.Interpolation.Linear:
249  return easing.Linear()
250  return easing.Sigmoid()
251 
252  def _convert_easing(self, start: api.Interpolation, end: api.Interpolation):
253  if api.Interpolation.Constant in (start, end):
254  return easing.Jump()
255  if start == end:
256  return self._convert_easing_part(start)
257  return easing.Split(self._convert_easing_part(start), self._convert_easing_part(end))
258 
259  def _convert_animatable(self, v: ast.SifAstNode, lot: objects.properties.AnimatableMixin):
260  if self._animated(v):
261  if len(v.keyframes) == 1:
262  lot.value = self._convert_ast_value(v.keyframes[0].value)
263  else:
264  for i, kf in enumerate(v.keyframes):
265  if i+1 < len(v.keyframes):
266  start = kf.after
267  end = v.keyframes[i+1].before
268  ease = self._convert_easing(start, end)
269  else:
270  ease = easing.Linear()
271 
272  lot.add_keyframe(self._time(kf.time), self._convert_ast_value(kf.value), ease)
273  else:
274  lot.value = self._convert_ast_value(v)
275  return lot
276 
277  def _convert_ast_value(self, v):
278  if isinstance(v, ast.SifRadialComposite):
279  return self._polar(v.radius.value, v.theta.value, 1)
280  elif isinstance(v, ast.SifValue):
281  return v.value
282  elif isinstance(v, ast.SifVectorComposite):
283  return NVector(v.x.value, v.y.value)
284  else:
285  return v
286 
287  def _converted_vector_values(self, v):
288  if isinstance(v, ast.SifRadialComposite):
289  return [self._convert_scalar(v.radius), self._convert_scalar(v.theta)]
290  return self._convert_vector(v)
291 
292  def _convert_color(self, v: ast.SifAstNode):
293  return self._adjust_animated(
295  self._color_gamma
296  )
297 
298  def _convert_vector(self, v: ast.SifAstNode):
300 
301  def _convert_scalar(self, v: ast.SifAstNode):
302  return self._convert_animatable(v, objects.Value())
303 
304  def _color_gamma(self, color):
305  color = color.clone()
306  for i in range(3):
307  color[i] = color[i] ** (1/self.gamma[i])
308  return color
309 
310  def _adjust_animated(self, lottieval, transform):
311  if lottieval.animated:
312  for kf in lottieval.keyframes:
313  if kf.start is not None:
314  kf.start = transform(kf.start)
315  if kf.end is not None:
316  kf.end = transform(kf.end)
317  else:
318  lottieval.value = transform(lottieval.value)
319  return lottieval
320 
321  def _adjust_scalar(self, lottieval: objects.Value):
322  return self._adjust_animated(lottieval, self._scalar_mult)
323 
324  def _adjust_angle(self, lottieval: objects.Value):
325  return self._adjust_animated(lottieval, lambda x: -x)
326 
327  def _adjust_add_dimension(self, lottieval, transform):
328  to_val = objects.MultiDimensional()
329  to_val.animated = lottieval.animated
330  if lottieval.animated:
331  to_val.keyframes = []
332  for kf in lottieval.keyframes:
333  if kf.start is not None:
334  kf.start = transform(kf.start[0])
335  if kf.end is not None:
336  kf.end = transform(kf.end[0])
337  to_val.keyframes.append(kf)
338  else:
339  to_val.value = transform(lottieval.value)
340  return to_val
341 
342  def _scalar_mult(self, x):
343  return x * 60
344 
345  def _adjust_coords(self, lottieval: objects.MultiDimensional):
346  return self._adjust_animated(lottieval, self._coord)
347 
348  def _coord(self, val: NVector):
349  return NVector(
350  self.target_size.x * (val.x / (self.view_p2.x - self.view_p1.x) + 0.5),
351  self.target_size.y * (val.y / (self.view_p2.y - self.view_p1.y) + 0.5),
352  )
353 
354  def _convert_polygon(self, layer: api.PolygonLayer):
355  lot = objects.Path()
356  animatables = [self._convert_vector(layer.origin)] + [
357  self._convert_vector(p)
358  for p in layer.points
359  ]
360  animated = any(x.animated for x in animatables)
361  if not animated:
362  lot.shape.value = self._polygon([x.value for x in animatables[1:]], animatables[0].value)
363  else:
364  for values in self._mix_animations(*animatables):
365  time = values[0]
366  origin = values[1]
367  points = values[2:]
368  lot.shape.add_keyframe(time, self._polygon(points, origin))
369  return lot
370 
371  def _polygon(self, points, origin):
372  bezier = objects.Bezier()
373  bezier.closed = True
374  for point in points:
375  bezier.add_point(self._coord(point+origin))
376  return bezier
377 
378  def _convert_bline(self, layer: api.AbstractOutline):
379  lot = objects.Path()
380  closed = layer.bline.loop
381  animatables = [
382  self._convert_vector(layer.origin)
383  ]
384  for p in layer.bline.points:
385  animatables += [
386  self._convert_vector(p.point),
387  self._convert_scalar(p.t1.radius) if hasattr(p.t1, "radius") else objects.Value(0),
388  self._convert_scalar(p.t1.theta) if hasattr(p.t1, "radius") else objects.Value(0),
389  self._convert_scalar(p.t2.radius) if hasattr(p.t2, "radius") else objects.Value(0),
390  self._convert_scalar(p.t2.theta) if hasattr(p.t2, "radius") else objects.Value(0)
391  ]
392  animated = any(x.animated for x in animatables)
393  if not animated:
394  lot.shape.value = self._bezier(
395  closed, [x.value for x in animatables[1:]], animatables[0].value, layer.bline.points
396  )
397  else:
398  for values in self._mix_animations(*animatables):
399  time = values[0]
400  origin = values[1]
401  values = values[2:]
402  lot.shape.add_keyframe(time, self._bezier(closed, values, origin, layer.bline.points))
403  return lot
404 
405  def _bezier(self, closed, values, origin, points):
406  chunk_size = 5
407  bezier = objects.Bezier()
408  bezier.closed = closed
409  for i in range(0, len(values), chunk_size):
410  point, r1, a1, r2, a2 = values[i:i+chunk_size]
411  sifvert = point+origin
412  vert = self._coord(sifvert)
413  if not points[i//chunk_size].split_radius.value:
414  r2 = r1
415  if not points[i//chunk_size].split_angle.value:
416  a2 = a1
417  t1 = self._coord(sifvert + self._polar(r1, a1, 1)) - vert
418  t2 = self._coord(sifvert + self._polar(r2, a2, 2)) - vert
419  bezier.add_point(vert, t1, t2)
420  return bezier
421 
422  def _polar(self, radius, angle, dir):
423  offset_angle = 0
424  if dir == 1:
425  offset_angle += 180
426  return PolarVector(radius/3, (angle+offset_angle) * math.pi / 180)
427 
428  def _convert_transform_down(self, tl: api.TransformDown):
429  group = objects.Group()
430  self._set_name(group, tl)
431 
432  if isinstance(tl, api.TranslateLayer):
433  group.transform.anchor_point.value = self.target_size / 2
434  group.transform.position = self._adjust_coords(self._convert_vector(tl.origin))
435  elif isinstance(tl, api.RotateLayer):
436  group.transform.anchor_point = self._adjust_coords(self._convert_vector(tl.origin))
437  group.transform.position = group.transform.anchor_point.clone()
438  group.transform.rotation = self._adjust_angle(self._convert_scalar(tl.amount))
439  elif isinstance(tl, api.ScaleLayer):
440  group.transform.anchor_point = self._adjust_coords(self._convert_vector(tl.center))
441  group.transform.position = group.transform.anchor_point.clone()
442  group.transform.scale = self._adjust_add_dimension(
443  self._convert_scalar(tl.amount),
444  self._zoom_to_scale
445  )
446 
447  return group
448 
449  def _zoom_to_scale(self, value):
450  zoom = math.e ** value * 100
451  return NVector(zoom, zoom)
452 
453  def _set_name(self, lottie, sif):
454  lottie.name = sif.desc if sif.desc is not None else sif.__class__.__name__
455 
456  def _convert_gradient(self, layer: api.GradientLayer, parent):
457  group = objects.Group()
458 
459  parent_shapes = parent.shapes
460  parent.shapes = []
461  if isinstance(parent, objects.Group):
462  parent.shapes.append(parent_shapes[-1])
463 
464  self._gradient_gather_shapes(parent_shapes, group)
465 
466  gradient = objects.GradientFill()
467  self._set_name(gradient, layer)
468  group.add_shape(gradient)
469  gradient.colors = self._convert_gradient_stops(layer.gradient)
470  gradient.opacity = self._adjust_animated(
471  self._convert_scalar(layer.amount),
472  lambda x: x * 100
473  )
474 
475  if isinstance(layer, api.LinearGradient):
476  gradient.start_point = self._adjust_coords(self._convert_vector(layer.p1))
477  gradient.end_point = self._adjust_coords(self._convert_vector(layer.p2))
478  gradient.gradient_type = objects.GradientType.Linear
479  elif isinstance(layer, api.RadialGradient):
480  gradient.gradient_type = objects.GradientType.Radial
481  gradient.start_point = self._adjust_coords(self._convert_vector(layer.center))
482  radius = self._adjust_animated(self._convert_scalar(layer.radius), lambda x: x*45)
483  if not radius.animated and not gradient.start_point.animated:
484  gradient.end_point.value = gradient.start_point.value + NVector(radius.value, radius.value)
485  else:
486  for time, c, r in self._mix_animations(gradient.start_point.clone(), radius):
487  gradient.end_point.add_keyframe(time, c + NVector(r + r))
488 
489  return group
490 
491  def _gradient_gather_shapes(self, shapes, output: objects.Group):
492  for shape in shapes:
493  if isinstance(shape, objects.Shape):
494  output.add_shape(shape)
495  elif isinstance(shape, objects.Group):
496  self._gradient_gather_shapes(shape.shapes, output)
497 
498  def _convert_gradient_stops(self, sif_gradient):
499  stops = objects.GradientColors()
500  if not self._animated(sif_gradient):
501  stops.set_stops(self._flatten_gradient_colors(sif_gradient.value))
502  stops.count = len(sif_gradient.value)
503  else:
504  # TODO easing
505  for kf in sif_gradient.keyframes:
506  stops.add_keyframe(self._time(kf.time), self._flatten_gradient_colors(kf.value))
507  stops.count = len(kf.value)
508 
509  return stops
510 
511  def _flatten_gradient_colors(self, stops):
512  return [
513  (stop.pos, self._color_gamma(stop.color))
514  for stop in stops
515  ]
516 
517  def _convert_text(self, layer: api.TextLayer):
518  shape = font.FontShape(layer.text.value, font.FontStyle(layer.family.value, 110, font.TextJustify.Center))
519  shape.refresh()
520  trans = shape.wrapped.transform
521  trans.anchor_point.value = shape.wrapped.bounding_box().center()
522  trans.anchor_point.value.x /= 2
523  trans.position = self._adjust_coords(self._convert_vector(layer.origin))
524  trans.scale = self._adjust_animated(
525  self._convert_vector(layer.size),
526  lambda v: v * 100
527  )
528  return shape
lottie.objects.shapes.Group
ShapeElement that can contain other shapes.
Definition: shapes.py:430
lottie.parsers.sif.converter.Converter._convert_outline
def _convert_outline(self, api.AbstractOutline layer, converter)
Definition: converter.py:183
lottie.parsers.sif.converter.Converter._convert_easing
def _convert_easing(self, api.Interpolation start, api.Interpolation end)
Definition: converter.py:252
lottie.objects.properties.Value
An animatable property that holds a float.
Definition: properties.py:622
lottie.parsers.sif.sif.nodes.PolygonLayer
Definition: nodes.py:420
lottie.parsers.sif.sif.nodes.TransformDown
Definition: nodes.py:462
lottie.parsers.sif.converter.Converter._force_animated
def _force_animated(self, lottieval)
Definition: converter.py:241
lottie.parsers.sif.converter.Converter._animated
def _animated(self, sifval)
Definition: converter.py:22
lottie.parsers.sif.converter.Converter._convert_group
def _convert_group(self, api.GroupLayer layer)
Definition: converter.py:79
lottie.objects.shapes.Stroke
Solid stroke.
Definition: shapes.py:648
lottie.parsers.sif.converter.Converter._time
def _time(self, api.FrameTime t)
Definition: converter.py:42
lottie.parsers.sif.converter.Converter._convert_polygon
def _convert_polygon(self, api.PolygonLayer layer)
Definition: converter.py:354
lottie.parsers.sif.converter.Converter._convert_fill
def _convert_fill(self, layer, converter)
Definition: converter.py:153
lottie.parsers.sif.sif.nodes.ScaleLayer
Definition: nodes.py:483
lottie.objects.bezier.Bezier
Single bezier curve.
Definition: bezier.py:123
lottie.parsers.sif.converter.Converter._convert_easing_part
def _convert_easing_part(self, api.Interpolation interp)
Definition: converter.py:247
lottie.objects.properties.AnimatableMixin
Definition: properties.py:229
lottie.parsers.sif.converter.Converter.canvas
canvas
Definition: converter.py:26
lottie.parsers.sif.converter.Converter.__init__
def __init__(self)
Definition: converter.py:19
lottie.parsers.sif.converter.Converter._convert_star
def _convert_star(self, api.StarLayer layer)
Definition: converter.py:217
lottie.parsers.sif.converter.Converter.view_p1
view_p1
Definition: converter.py:34
lottie.parsers.sif.sif.nodes.GroupLayerBase
Definition: nodes.py:254
lottie.parsers.sif.converter.Converter._convert_linecap
def _convert_linecap(self, api.LineCap lc)
Definition: converter.py:169
lottie.objects.shapes.Path
Animatable Bezier curve.
Definition: shapes.py:398
lottie.parsers.sif.converter.Converter._convert_vector
def _convert_vector(self, ast.SifAstNode v)
Definition: converter.py:298
lottie.parsers.sif.converter.Converter._convert_rect
def _convert_rect(self, api.RectangleLayer layer)
Definition: converter.py:195
lottie.objects.animation.Animation
Top level object, describing the animation.
Definition: animation.py:62
lottie.parsers.sif.sif.nodes.CircleLayer
Definition: nodes.py:315
lottie.parsers.sif.converter.Converter._adjust_angle
def _adjust_angle(self, objects.Value lottieval)
Definition: converter.py:324
lottie.parsers.sif.sif.nodes.GradientLayer
Definition: nodes.py:492
lottie.parsers.sif.converter.Converter._zoom_to_scale
def _zoom_to_scale(self, value)
Definition: converter.py:449
lottie.parsers.sif.converter.convert
def convert(api.Canvas canvas)
Definition: converter.py:14
lottie.parsers.sif.converter.Converter._adjust_add_dimension
def _adjust_add_dimension(self, lottieval, transform)
Definition: converter.py:327
lottie.parsers.sif.converter.Converter._bezier
def _bezier(self, closed, values, origin, points)
Definition: converter.py:405
lottie.parsers.sif.converter.Converter._color_gamma
def _color_gamma(self, color)
Definition: converter.py:304
lottie.objects.shapes.Rect
A simple rectangle shape.
Definition: shapes.py:149
lottie.parsers.sif.ast_impl.base.SifValue
Definition: base.py:43
lottie.objects.shapes.Fill
Solid fill color.
Definition: shapes.py:506
lottie.parsers.sif.sif.nodes.StarLayer
Definition: nodes.py:349
lottie.parsers.sif.ast_impl.nodes.SifRadialComposite
Definition: nodes.py:171
lottie.nvector.PolarVector
def PolarVector(length, theta)
Definition: nvector.py:147
lottie.parsers.sif.ast_impl.nodes.SifVectorComposite
Definition: nodes.py:196
lottie.parsers.sif.sif.nodes.LinearGradient
Definition: nodes.py:509
lottie.parsers.sif.converter.Converter.convert
def convert(self, api.Canvas canvas)
Definition: converter.py:25
lottie.parsers.sif.converter.Converter._scalar_mult
def _scalar_mult(self, x)
Definition: converter.py:342
lottie.parsers.sif.converter.Converter.animation
animation
Definition: converter.py:27
lottie.parsers.sif.sif.nodes.ColorCorrectLayer
Definition: nodes.py:796
lottie.parsers.sif.converter.Converter._gradient_gather_shapes
def _gradient_gather_shapes(self, shapes, objects.Group output)
Definition: converter.py:491
lottie.parsers.sif.converter.Converter._mix_animations
def _mix_animations(self, *animatable)
Definition: converter.py:231
lottie.parsers.sif.sif.nodes.RegionLayer
Definition: nodes.py:428
lottie.parsers.sif.converter.Converter._polar
def _polar(self, radius, angle, dir)
Definition: converter.py:422
lottie.objects.shapes.GradientFill
Gradient fill.
Definition: shapes.py:563
lottie.parsers.sif.converter.Converter._coord
def _coord(self, NVector val)
Definition: converter.py:348
lottie.parsers.sif.converter.Converter._convert_text
def _convert_text(self, api.TextLayer layer)
Definition: converter.py:517
lottie.parsers.sif.converter.Converter._adjust_coords
def _adjust_coords(self, objects.MultiDimensional lottieval)
Definition: converter.py:345
lottie.parsers.sif.converter.Converter._polygon
def _polygon(self, points, origin)
Definition: converter.py:371
lottie.parsers.sif.ast_impl.base.SifAnimated
Definition: base.py:94
lottie.parsers.sif.sif.nodes.RadialGradient
Definition: nodes.py:500
lottie.parsers.sif.converter.Converter._convert_color
def _convert_color(self, ast.SifAstNode v)
Definition: converter.py:292
lottie.parsers.sif.converter.Converter._convert_ast_value
def _convert_ast_value(self, v)
Definition: converter.py:277
lottie.objects.shapes.Ellipse
Ellipse shape.
Definition: shapes.py:335
lottie.parsers.sif.converter.Converter._convert_transform_down
def _convert_transform_down(self, api.TransformDown tl)
Definition: converter.py:428
lottie.parsers.sif.sif.nodes.BoneLinkTransform
Definition: nodes.py:607
lottie.parsers.sif.converter.Converter._convert_scalar
def _convert_scalar(self, ast.SifAstNode v)
Definition: converter.py:301
lottie.parsers.sif.sif.nodes.RectangleLayer
Definition: nodes.py:299
lottie.parsers.sif.converter.Converter.shape_layer
shape_layer
Definition: converter.py:37
lottie.objects.helpers.Transform
Layer transform.
Definition: helpers.py:7
lottie.parsers.sif.converter.Converter._convert_cusp
def _convert_cusp(self, api.CuspStyle lc)
Definition: converter.py:176
lottie.parsers.sif.converter.Converter._convert_bline
def _convert_bline(self, api.AbstractOutline layer)
Definition: converter.py:378
lottie.objects.properties.GradientColors
Represents colors and offsets in a gradient.
Definition: properties.py:480
lottie.parsers.sif.converter.Converter._process_layers
def _process_layers(self, layers, parent)
Definition: converter.py:45
lottie.parsers.sif.converter.Converter._convert_circle
def _convert_circle(self, api.CircleLayer layer)
Definition: converter.py:210
lottie.parsers.sif.sif.nodes.AbstractOutline
Definition: nodes.py:376
lottie.parsers.sif.converter.Converter._adjust_scalar
def _adjust_scalar(self, objects.Value lottieval)
Definition: converter.py:321
lottie.parsers.sif.converter.Converter
Definition: converter.py:18
lottie.parsers.sif.converter.Converter._convert_gradient
def _convert_gradient(self, api.GradientLayer layer, parent)
Definition: converter.py:456
lottie.parsers.sif.sif.nodes.TranslateLayer
Definition: nodes.py:466
lottie.objects.shapes.Star
Star shape.
Definition: shapes.py:239
lottie.parsers.sif.converter.Converter._convert_transform
def _convert_transform(self, api.AbstractTransform sif_transform, objects.Transform lottie_transform)
Definition: converter.py:91
lottie.objects.properties.MultiDimensional
An animatable property that holds a NVector.
Definition: properties.py:385
lottie.parsers.sif.converter.Converter.target_size
target_size
Definition: converter.py:36
lottie.parsers.sif.converter.Converter._convert_gradient_stops
def _convert_gradient_stops(self, sif_gradient)
Definition: converter.py:498
lottie.parsers.sif.converter.Converter.view_p2
view_p2
Definition: converter.py:35
lottie.parsers.sif.converter.Converter._convert_animatable
def _convert_animatable(self, ast.SifAstNode v, objects.properties.AnimatableMixin lot)
Definition: converter.py:259
lottie.parsers.sif.converter.Converter._set_name
def _set_name(self, lottie, sif)
Definition: converter.py:453
lottie.parsers.sif.sif.nodes.TextLayer
Definition: nodes.py:442
lottie.objects.properties.ColorValue
An animatable property that holds a Color.
Definition: properties.py:465
lottie.parsers.sif.converter.Converter._adjust_animated
def _adjust_animated(self, lottieval, transform)
Definition: converter.py:310
lottie.parsers.sif.converter.Converter._flatten_gradient_colors
def _flatten_gradient_colors(self, stops)
Definition: converter.py:511
lottie.nvector.NVector
Definition: nvector.py:9
lottie.parsers.sif.sif.nodes.RotateLayer
Definition: nodes.py:474
lottie.parsers.sif.ast_impl.base.Interpolation
Definition: base.py:58
lottie.objects.layers.ShapeLayer
Layer containing ShapeElement objects.
Definition: layers.py:193
lottie.parsers.sif.converter.Converter.gamma
gamma
Definition: converter.py:38
lottie.objects.shapes.Shape
Drawable shape.
Definition: shapes.py:128