python-lottie  0.6.11+deva0e77a1
A framework to work with lottie files and telegram animated stickers (tgs)
shapes.py
Go to the documentation of this file.
1 import math
2 from .base import LottieObject, LottieProp, LottieEnum, NVector
3 from .properties import Value, MultiDimensional, GradientColors, ShapeProperty, Bezier, ColorValue, PositionValue
4 from ..utils.color import Color
5 from .helpers import Transform, VisualObject, BlendMode
6 
7 
8 class BoundingBox:
9  """!
10  Shape bounding box
11  """
12  def __init__(self, x1=None, y1=None, x2=None, y2=None):
13  self.x1x1 = x1
14  self.y1y1 = y1
15  self.x2x2 = x2
16  self.y2y2 = y2
17 
18  def include(self, x, y):
19  """!
20  Expands the box to include the point at x, y
21  """
22  if x is not None:
23  if self.x1x1 is None or self.x1x1 > x:
24  self.x1x1 = x
25  if self.x2x2 is None or self.x2x2 < x:
26  self.x2x2 = x
27  if y is not None:
28  if self.y1y1 is None or self.y1y1 > y:
29  self.y1y1 = y
30  if self.y2y2 is None or self.y2y2 < y:
31  self.y2y2 = y
32 
33  def expand(self, other):
34  """!
35  Expands the bounding box to include another bounding box
36  """
37  self.includeinclude(other.x1, other.y1)
38  self.includeinclude(other.x2, other.y2)
39 
40  def center(self):
41  """!
42  Center point of the bounding box
43  """
44  return NVector((self.x1x1 + self.x2x2) / 2, (self.y1y1 + self.y2y2) / 2)
45 
46  def isnull(self):
47  """!
48  Whether the box is default-initialized
49  """
50  return self.x1x1 is None or self.y2y2 is None
51 
52  def __repr__(self):
53  return "<BoundingBox [%s, %s] - [%s, %s]>" % (self.x1x1, self.y1y1, self.x2x2, self.y2y2)
54 
55  @property
56  def width(self):
57  if self.isnullisnull():
58  return 0
59  return self.x2x2 - self.x1x1
60 
61  @property
62  def height(self):
63  if self.isnullisnull():
64  return 0
65  return self.y2y2 - self.y1y1
66 
67  def size(self):
68  return NVector(self.widthwidth, self.heightheight)
69 
70 
71 ## @ingroup Lottie
73  """!
74  Base class for all elements of ShapeLayer and Group
75  """
76  _props = [
77  LottieProp("hidden", "hd", bool, False),
78  LottieProp("type", "ty", str, False),
79  LottieProp("property_index", "cix", int, False),
80  LottieProp("blend_mode", "bm", BlendMode, False),
81  ]
82  ## %Shape type.
83  type = None
84  _shape_classses = None
85 
86  def __init__(self):
87  super().__init__()
88  ## Property index
89  self.property_indexproperty_index = None
90  ## Hide element
91  self.hiddenhidden = None
92  ## Blend mode
93  self.blend_modeblend_mode = None
94 
95  def bounding_box(self, time=0):
96  """!
97  Bounding box of the shape element at the given time
98  """
99  return BoundingBox()
100 
101  @classmethod
102  def _load_get_class(cls, lottiedict):
103  if not ShapeElement._shape_classses:
104  ShapeElement._shape_classses = {}
105  ShapeElement._load_sub(ShapeElement._shape_classses)
106  return ShapeElement._shape_classses[lottiedict["ty"]]
107 
108  @classmethod
109  def _load_sub(cls, dict):
110  for sc in cls.__subclasses__():
111  if sc.type and sc.type not in dict:
112  dict[sc.type] = sc
113  sc._load_sub(dict)
114 
115  def __str__(self):
116  return self.namename or super().__str__()
117 
118 
119 #ingroup Lottie
121  Undefined = 0
122  ## Usually clockwise
123  Normal = 1
124  ## Usually counter clockwise
125  Reversed = 3
126 
127 
128 ## @ingroup Lottie
130  """!
131  Drawable shape
132  """
133  _props = [
134  LottieProp("direction", "d", ShapeDirection, False),
135  ]
136 
137  def __init__(self):
138  ShapeElement.__init__(self)
139  ## After Effect's Direction. Direction how the shape is drawn. Used for trim path for example.
140  self.directiondirection = ShapeDirection.Normal
141 
142  def to_bezier(self):
143  """!
144  Returns a Path corresponding to this Shape
145  """
146  raise NotImplementedError()
147 
148 
149 ## @ingroup Lottie
150 class Rect(Shape):
151  """!
152  A simple rectangle shape
153  """
154  _props = [
155  LottieProp("position", "p", PositionValue, False),
156  LottieProp("size", "s", MultiDimensional, False),
157  LottieProp("rounded", "r", Value, False),
158  ]
159  ## %Shape type.
160  type = "rc"
161 
162  def __init__(self, pos=None, size=None, rounded=0):
163  Shape.__init__(self)
164  ## Rect's position
165  self.positionposition = PositionValue(pos or NVector(0, 0))
166  ## Rect's size
167  self.sizesize = MultiDimensional(size or NVector(0, 0))
168  ## Rect's rounded corners
169  self.roundedrounded = Value(rounded)
170 
171  def bounding_box(self, time=0):
172  pos = self.positionposition.get_value(time)
173  sz = self.sizesize.get_value(time)
174 
175  return BoundingBox(
176  pos[0] - sz[0]/2,
177  pos[1] - sz[1]/2,
178  pos[0] + sz[0]/2,
179  pos[1] + sz[1]/2,
180  )
181 
182  def to_bezier(self):
183  """!
184  Returns a Shape corresponding to this rect
185  """
186  shape = Path()
187  kft = set()
188  if self.positionposition.animated:
189  kft |= set(kf.time for kf in self.positionposition.keyframes)
190  if self.sizesize.animated:
191  kft |= set(kf.time for kf in self.sizesize.keyframes)
192  if self.roundedrounded.animated:
193  kft |= set(kf.time for kf in self.roundedrounded.keyframes)
194  if not kft:
195  shape.shape.value = self._bezier_t_bezier_t(0)
196  else:
197  for time in sorted(kft):
198  shape.shape.add_keyframe(time, self._bezier_t_bezier_t(time))
199  return shape
200 
201  def _bezier_t(self, time):
202  bezier = Bezier()
203  bb = self.bounding_boxbounding_boxbounding_box(time)
204  rounded = self.roundedrounded.get_value(time)
205  tl = NVector(bb.x1, bb.y1)
206  tr = NVector(bb.x2, bb.y1)
207  br = NVector(bb.x2, bb.y2)
208  bl = NVector(bb.x1, bb.y2)
209 
210  if not self.roundedrounded.animated and rounded == 0:
211  bezier.add_point(tl)
212  bezier.add_point(tr)
213  bezier.add_point(br)
214  bezier.add_point(bl)
215  else:
216  hh = NVector(rounded/2, 0)
217  vh = NVector(0, rounded/2)
218  hd = NVector(rounded, 0)
219  vd = NVector(0, rounded)
220  bezier.add_point(tl+vd, outp=-vh)
221  bezier.add_point(tl+hd, -hh)
222  bezier.add_point(tr-hd, outp=hh)
223  bezier.add_point(tr+vd, -vh)
224  bezier.add_point(br-vd, outp=vh)
225  bezier.add_point(br-hd, hh)
226  bezier.add_point(bl+hd, outp=-hh)
227  bezier.add_point(bl-vd, vh)
228 
229  bezier.close()
230  return bezier
231 
232 
233 ## @ingroup Lottie
235  Star = 1
236  Polygon = 2
237 
238 
239 ## @ingroup Lottie
240 class Star(Shape):
241  """!
242  Star shape
243  """
244  _props = [
245  LottieProp("position", "p", PositionValue, False),
246  LottieProp("inner_radius", "ir", Value, False),
247  LottieProp("inner_roundness", "is", Value, False),
248  LottieProp("outer_radius", "or", Value, False),
249  LottieProp("outer_roundness", "os", Value, False),
250  LottieProp("rotation", "r", Value, False),
251  LottieProp("points", "pt", Value, False),
252  LottieProp("star_type", "sy", StarType, False),
253  ]
254  ## %Shape type.
255  type = "sr"
256 
257  def __init__(self):
258  Shape.__init__(self)
259  ## Star's position
260  self.positionposition = PositionValue(NVector(0, 0))
261  ## Star's inner radius. (Star only)
262  self.inner_radiusinner_radius = Value()
263  ## Star's inner roundness. (Star only)
264  self.inner_roundnessinner_roundness = Value()
265  ## Star's outer radius.
266  self.outer_radiusouter_radius = Value()
267  ## Star's outer roundness.
268  self.outer_roundnessouter_roundness = Value()
269  ## Star's rotation.
270  self.rotationrotation = Value()
271  ## Star's number of points.
272  self.pointspoints = Value(5)
273  ## Star's type. Polygon or Star.
274  self.star_typestar_type = StarType.Star
275 
276  def bounding_box(self, time=0):
277  pos = self.positionposition.get_value(time)
278  r = self.outer_radiusouter_radius.get_value(time)
279 
280  return BoundingBox(
281  pos[0] - r,
282  pos[1] - r,
283  pos[0] + r,
284  pos[1] + r,
285  )
286 
287  def to_bezier(self):
288  """!
289  Returns a Shape corresponding to this star
290  """
291  shape = Path()
292  kft = set()
293  if self.positionposition.animated:
294  kft |= set(kf.time for kf in self.positionposition.keyframes)
295  if self.inner_radiusinner_radius.animated:
296  kft |= set(kf.time for kf in self.inner_radiusinner_radius.keyframes)
297  if self.inner_roundnessinner_roundness.animated:
298  kft |= set(kf.time for kf in self.inner_roundnessinner_roundness.keyframes)
299  if self.pointspoints.animated:
300  kft |= set(kf.time for kf in self.pointspoints.keyframes)
301  if self.rotationrotation.animated:
302  kft |= set(kf.time for kf in self.rotationrotation.keyframes)
303  # TODO inner_roundness / outer_roundness
304  if not kft:
305  shape.shape.value = self._bezier_t_bezier_t(0)
306  else:
307  for time in sorted(kft):
308  shape.shape.add_keyframe(time, self._bezier_t_bezier_t(time))
309  return shape
310 
311  def _bezier_t(self, time):
312  bezier = Bezier()
313  pos = self.positionposition.get_value(time)
314  r1 = self.inner_radiusinner_radius.get_value(time)
315  r2 = self.outer_radiusouter_radius.get_value(time)
316  rot = -(self.rotationrotation.get_value(time)) * math.pi / 180 + math.pi
317  p = self.pointspoints.get_value(time)
318  halfd = -math.pi / p
319 
320  for i in range(int(p)):
321  main_angle = rot + i * halfd * 2
322  dx = r2 * math.sin(main_angle)
323  dy = r2 * math.cos(main_angle)
324  bezier.add_point(NVector(pos.x + dx, pos.y + dy))
325 
326  if self.star_typestar_type == StarType.Star:
327  dx = r1 * math.sin(main_angle+halfd)
328  dy = r1 * math.cos(main_angle+halfd)
329  bezier.add_point(NVector(pos.x + dx, pos.y + dy))
330 
331  bezier.close()
332  return bezier
333 
334 
335 ## @ingroup Lottie
336 class Ellipse(Shape):
337  """!
338  Ellipse shape
339  """
340  _props = [
341  LottieProp("position", "p", MultiDimensional, False),
342  LottieProp("size", "s", MultiDimensional, False),
343  ]
344  ## %Shape type.
345  type = "el"
346 
347  def __init__(self, position=None, size=None):
348  Shape.__init__(self)
349  ## Ellipse's position
350  self.positionposition = MultiDimensional(position or NVector(0, 0))
351  ## Ellipse's size
352  self.sizesize = MultiDimensional(size or NVector(0, 0))
353 
354  def bounding_box(self, time=0):
355  pos = self.positionposition.get_value(time)
356  sz = self.sizesize.get_value(time)
357 
358  return BoundingBox(
359  pos[0] - sz[0]/2,
360  pos[1] - sz[1]/2,
361  pos[0] + sz[0]/2,
362  pos[1] + sz[1]/2,
363  )
364 
365  def to_bezier(self):
366  """!
367  Returns a Shape corresponding to this ellipse
368  """
369  shape = Path()
370  kft = set()
371  if self.positionposition.animated:
372  kft |= set(kf.time for kf in self.positionposition.keyframes)
373  if self.sizesize.animated:
374  kft |= set(kf.time for kf in self.sizesize.keyframes)
375  if not kft:
376  shape.shape.value = self._bezier_t_bezier_t(0)
377  else:
378  for time in sorted(kft):
379  shape.shape.add_keyframe(time, self._bezier_t_bezier_t(time))
380  return shape
381 
382  def _bezier_t(self, time):
383  from ..utils.ellipse import Ellipse as EllipseConverter
384 
385  bezier = Bezier()
386  position = self.positionposition.get_value(time)
387  radii = self.sizesize.get_value(time) / 2
388 
389  el = EllipseConverter(position, radii, 0)
390  points = el.to_bezier(0, math.pi*2)
391  for point in points[1:]:
392  bezier.add_point(point.vertex, point.in_tangent, point.out_tangent)
393 
394  bezier.close()
395  return bezier
396 
397 
398 ## @ingroup Lottie
399 class Path(Shape):
400  """!
401  Animatable Bezier curve
402  """
403  _props = [
404  LottieProp("shape", "ks", ShapeProperty, False),
405  LottieProp("index", "ind", int, False),
406  ]
407  ## %Shape type.
408  type = "sh"
409 
410  def __init__(self, bezier=None):
411  Shape.__init__(self)
412  ## Shape's vertices
413  self.shapeshape = ShapeProperty(bezier or Bezier())
414  ## @todo Index?
415  self.indexindex = None
416 
417  def bounding_box(self, time=0):
418  pos = self.shapeshape.get_value(time)
419 
420  bb = BoundingBox()
421  for v, i, o in zip(pos.vertices, pos.in_tangents, pos.out_tangents):
422  bb.include(*v)
423  bb.include(*(v+i))
424  bb.include(*(v+o))
425 
426  return bb
427 
428  def to_bezier(self):
429  return self.clonecloneclone()
430 
431 
432 ## @ingroup Lottie
434  """!
435  ShapeElement that can contain other shapes
436  @note Shapes inside the same group will create "holes" in other shapes
437  """
438  _props = [
439  LottieProp("number_of_properties", "np", float, False),
440  LottieProp("shapes", "it", ShapeElement, True),
441  ]
442  ## %Shape type.
443  type = "gr"
444 
445  def __init__(self):
446  ShapeElement.__init__(self)
447  ## Group number of properties. Used for expressions.
448  self.number_of_propertiesnumber_of_properties = None
449  ## Group list of items
450  self.shapesshapes = [TransformShape()]
451 
452  @property
453  def transform(self):
454  return self.shapesshapes[-1]
455 
456  def bounding_box(self, time=0):
457  bb = BoundingBox()
458  for v in self.shapesshapes:
459  bb.expand(v.bounding_box(time))
460 
461  if not bb.isnull():
462  mat = self.transformtransform.to_matrix(time)
463  points = [
464  mat.apply(NVector(bb.x1, bb.y1)),
465  mat.apply(NVector(bb.x1, bb.y2)),
466  mat.apply(NVector(bb.x2, bb.y2)),
467  mat.apply(NVector(bb.x2, bb.y1)),
468  ]
469  x1 = min(p.x for p in points)
470  x2 = max(p.x for p in points)
471  y1 = min(p.y for p in points)
472  y2 = max(p.y for p in points)
473  return BoundingBox(x1, y1, x2, y2)
474  return bb
475 
476  def add_shape(self, shape):
477  self.shapesshapes.insert(-1, shape)
478  return shape
479 
480  def insert_shape(self, index, shape):
481  self.shapesshapes.insert(index, shape)
482  return shape
483 
484  @classmethod
485  def load(cls, lottiedict):
486  object = ShapeElement.load(lottiedict)
487 
488  shapes = []
489  transform = None
490  for obj in object.shapes:
491  if isinstance(obj, TransformShape):
492  if not transform:
493  transform = obj
494  else:
495  shapes.append(obj)
496 
497  object.shapes = shapes
498  object.shapes.append(transform)
499  return object
500 
501 
502 ## @ingroup Lottie
504  NonZero = 1
505  EvenOdd = 2
506 
507 
508 ## @ingroup Lottie
510  """!
511  Solid fill color
512  """
513  _props = [
514  LottieProp("opacity", "o", Value, False),
515  LottieProp("color", "c", ColorValue, False),
516  LottieProp("fill_rule", "r", FillRule, False),
517  ]
518  ## %Shape type.
519  type = "fl"
520 
521  def __init__(self, color=None):
522  ShapeElement.__init__(self)
523  ## Fill Opacity
524  self.opacityopacity = Value(100)
525  ## Fill Color
526  self.colorcolor = ColorValue(color or Color(1, 1, 1))
527  ## Fill rule
528  self.fill_rulefill_rule = None
529 
530 
531 ## @ingroup Lottie
533  Linear = 1
534  Radial = 2
535 
536 
537 ## @ingroup Lottie
539  _props = [
540  LottieProp("start_point", "s", MultiDimensional, False),
541  LottieProp("end_point", "e", MultiDimensional, False),
542  LottieProp("gradient_type", "t", GradientType, False),
543  LottieProp("highlight_length", "h", Value, False),
544  LottieProp("highlight_angle", "a", Value, False),
545  LottieProp("colors", "g", GradientColors, False),
546  ]
547 
548  def __init__(self, colors=[]):
549  ## Fill Opacity
550  self.opacityopacity = Value(100)
551  ## Gradient Start Point
552  self.start_pointstart_point = MultiDimensional(NVector(0, 0))
553  ## Gradient End Point
554  self.end_pointend_point = MultiDimensional(NVector(0, 0))
555  ## Gradient Type
556  self.gradient_typegradient_type = GradientType.Linear
557  ## Gradient Highlight Length. Only if type is Radial
558  self.highlight_lengthhighlight_length = Value()
559  ## Highlight Angle. Only if type is Radial
560  self.highlight_anglehighlight_angle = Value()
561  ## Gradient Colors
562  self.colorscolors = GradientColors(colors)
563 
564 
565 ## @ingroup Lottie
567  """!
568  Gradient fill
569  """
570  _props = [
571  LottieProp("opacity", "o", Value, False),
572  LottieProp("fill_rule", "r", FillRule, False),
573  ]
574  ## %Shape type.
575  type = "gf"
576 
577  def __init__(self, colors=[]):
578  ShapeElement.__init__(self)
579  Gradient.__init__(self, colors)
580  ## Fill Opacity
581  self.opacityopacityopacity = Value(100)
582  ## Fill rule
583  self.fill_rulefill_rule = None
584 
585 
586 ## @ingroup Lottie
588  Miter = 1
589  Round = 2
590  Bevel = 3
591 
592 
593 ## @ingroup Lottie
595  Butt = 1
596  Round = 2
597  Square = 3
598 
599 
600 ## @ingroup Lottie
602  Dash = "d"
603  Gap = "g"
604  Offset = "o"
605 
606 
607 ## @ingroup Lottie
609  _props = [
610  LottieProp("type", "n", StrokeDashType, False),
611  LottieProp("length", "v", Value, False),
612  ]
613 
614  def __init__(self, length=0, type=StrokeDashType.Dash):
615  super().__init__()
616  self.namenamename = type.name.lower()
617  self.typetype = type
618  self.lengthlength = Value(length)
619 
620  def __str__(self):
621  return self.namenamename or super().__str__()
622 
623 
624 ## @ingroup Lottie
626  _props = [
627  LottieProp("line_cap", "lc", LineCap, False),
628  LottieProp("line_join", "lj", LineJoin, False),
629  LottieProp("miter_limit", "ml", float, False),
630  LottieProp("opacity", "o", Value, False),
631  LottieProp("width", "w", Value, False),
632  LottieProp("dashes", "d", StrokeDash, True),
633  ]
634 
635  def __init__(self, width=1):
636  ## Stroke Line Cap
637  self.line_capline_cap = LineCap.Round
638  ## Stroke Line Join
639  self.line_joinline_join = LineJoin.Round
640  ## Stroke Miter Limit. Only if Line Join is set to Miter.
641  self.miter_limitmiter_limit = 0
642  ## Stroke Opacity
643  self.opacityopacity = Value(100)
644  ## Stroke Width
645  self.widthwidth = Value(width)
646  ## Dashes
647  self.dashesdashes = None
648 
649 
650 ## @ingroup Lottie
652  """!
653  Solid stroke
654  """
655  _props = [
656  LottieProp("color", "c", MultiDimensional, False),
657  ]
658  ## %Shape type.
659  type = "st"
660 
661  def __init__(self, color=None, width=1):
662  ShapeElement.__init__(self)
663  BaseStroke.__init__(self, width)
664  ## Stroke Color
665  self.colorcolor = ColorValue(color or Color(0, 0, 0))
666 
667 
668 ## @ingroup Lottie
670  """!
671  Gradient stroke
672  """
673  ## %Shape type.
674  type = "gs"
675 
676  def __init__(self, stroke_width=1):
677  ShapeElement.__init__(self)
678  BaseStroke.__init__(self, stroke_width)
679  Gradient.__init__(self)
680 
681  def bounding_box(self, time=0):
682  return BoundingBox()
683 
684 
685 ## @ingroup Lottie
687  """!
688  Group transform
689  """
690  ## %Shape type.
691  type = "tr"
692 
693  def __init__(self):
694  ShapeElement.__init__(self)
695  Transform.__init__(self)
697 
698 
699 ## @ingroup Lottie
701  Above = 1
702  Below = 2
703 
704 
705 ## @ingroup Lottie
707  _props = [
708  LottieProp("start_opacity", "so", Value, False),
709  LottieProp("end_opacity", "eo", Value, False),
710  ]
711 
712  def __init__(self):
713  Transform.__init__(self)
714  self.start_opacitystart_opacity = Value(100)
715  self.end_opacityend_opacity = Value(100)
716 
717 
718 ## @ingroup Lottie
720  pass
721 
722 
723 ## @ingroup Lottie
724 class TrimMultipleShapes(LottieEnum):
725  Individually = 1
726  Simultaneously = 2
727 
728 
729 ## @ingroup Lottie
730 ## @todo Implement SIF Export
731 class Trim(Modifier):
732  """
733  Trims shapes into a segment
734  """
735  _props = [
736  LottieProp("start", "s", Value, False),
737  LottieProp("end", "e", Value, False),
738  LottieProp("offset", "o", Value, False),
739  LottieProp("multiple", "m", TrimMultipleShapes, False),
740  ]
741  ## %Shape type.
742  type = "tm"
743 
744  def __init__(self):
745  ShapeElement.__init__(self)
746  ## Start of the segment, as a percentage
747  self.startstart = Value(0)
748  ## End of the segment, as a percentage
749  self.endend = Value(100)
750  ## start/end offset, as an angle (0, 360)
751  self.offsetoffset = Value(0)
752  ## @todo?
753  self.multiplemultiple = None
754 
755 
756 ## @ingroup Lottie
758  """
759  Duplicates previous shapes in a group
760  """
761  _props = [
762  LottieProp("copies", "c", Value, False),
763  LottieProp("offset", "o", Value, False),
764  LottieProp("composite", "m", Composite, False),
765  LottieProp("transform", "tr", RepeaterTransform, False),
766  ]
767  ## %Shape type.
768  type = "rp"
769 
770  def __init__(self, copies=1):
771  Modifier.__init__(self)
772  ## Number of Copies
773  self.copiescopies = Value(copies)
774  ## Offset of Copies
775  self.offsetoffset = Value()
776  ## Composite of copies
777  self.compositecomposite = Composite.Above
778  ## Transform values for each repeater copy
779  self.transformtransform = RepeaterTransform()
780 
781 
782 ## @ingroup Lottie
783 ## @todo Implement SIF Export
785  """
786  Rounds corners of other shapes
787  """
788  _props = [
789  LottieProp("radius", "r", Value, False),
790  ]
791  ## %Shape type.
792  type = "rd"
793 
794  def __init__(self, radius=0):
795  Modifier.__init__(self)
796  ## Rounded Corner Radius
797  self.radiusradius = Value(radius)
798 
799 
800 ## @ingroup Lottie
801 ## @ingroup LottieCheck
802 ## @note marked as unsupported by lottie
804  _props = [
805  LottieProp("merge_mode", "mm", float, False),
806  ]
807  ## %Shape type.
808  type = "mm"
809 
810  def __init__(self):
811  ShapeElement.__init__(self)
812  ## Merge Mode
813  self.merge_modemerge_mode = 1
814 
815 
816 ## @ingroup Lottie
817 ## @note marked as unsupported by lottie
819  _props = [
820  LottieProp("angle", "a", Value, False),
821  LottieProp("center", "c", MultiDimensional, False),
822  ]
823  ## %Shape type.
824  type = "tw"
825 
826  def __init__(self):
827  ShapeElement.__init__(self)
828  self.angleangle = Value(0)
829  self.centercenter = MultiDimensional(NVector(0, 0))
830 
831 
832 ## @ingroup Lottie
834  """
835  Interpolates the shape with its center point and bezier tangents with the opposite direction
836  """
837  _props = [
838  LottieProp("amount", "a", Value, False),
839  ]
840  ## %Shape type.
841  type = "pb"
842 
843  def __init__(self):
844  ShapeElement.__init__(self)
845  self.amountamount = Value(0)
846 
847 
848 #ingroup Lottie
849 ## @note marked as unsupported by lottie
851  """!
852  Changes the edges of affected shapes into a series of peaks and valleys of uniform size
853  """
854  _props = [
855  LottieProp("shape_type", "ty", str, False),
856  LottieProp("roundness", "r", Value, False),
857  LottieProp("size", "s", Value, False),
858  LottieProp("points", "pt", Value, False),
859  ]
860  ## %Shape type.
861  type = "zz"
862 
863  def __init__(self):
864  super().__init__()
865 
866  ## Radius to maked it a smoother curve
867  self.roundnessroundness = Value(0)
868  ## Distance between peaks and troughs
869  self.sizesize = Value(0)
870  ## Number of ridges
871  self.pointspoints = Value(1)
872 
873 
874 #ingroup Lottie
875 ## @note marked as unsupported by lottie
877  """!
878  Interpolates the shape with its center point and bezier tangents with the opposite direction
879  """
880  _props = [
881  LottieProp("shape_type", "ty", str, False),
882  LottieProp("amount", "a", Value, False),
883  LottieProp("line_join", "lj", LineJoin, False),
884  LottieProp("miter_limit", "ml", Value, False),
885  ]
886  ## %Shape type.
887  type = "op"
888 
889  def __init__(self):
890  super().__init__()
891 
892  self.amountamount = Value(0)
893  self.line_joinline_join = LineJoin.Round
894  self.miter_limitmiter_limit = Value(0)
def clone(self)
Returns a copy of the object.
Definition: base.py:26
Base class for enum-like types in the Lottie JSON structure.
Definition: base.py:42
Base class for mapping Python classes into Lottie JSON objects.
Definition: base.py:225
def clone(self)
Returns a copy of the object.
Definition: base.py:299
Lottie <-> Python property mapper.
Definition: base.py:88
Single bezier curve.
Definition: bezier.py:123
anchor_point
Transform Anchor Point.
Definition: helpers.py:24
An animatable property that holds a Color.
Definition: properties.py:551
Represents colors and offsets in a gradient.
Definition: properties.py:566
An animatable property that holds a NVector.
Definition: properties.py:471
An animatable property that holds a Bezier.
Definition: properties.py:773
An animatable property that holds a float.
Definition: properties.py:708
line_cap
Stroke Line Cap.
Definition: shapes.py:637
line_join
Stroke Line Join.
Definition: shapes.py:639
miter_limit
Stroke Miter Limit.
Definition: shapes.py:641
def __init__(self, width=1)
Definition: shapes.py:635
Shape bounding box.
Definition: shapes.py:8
def isnull(self)
Whether the box is default-initialized.
Definition: shapes.py:46
def center(self)
Center point of the bounding box.
Definition: shapes.py:40
def expand(self, other)
Expands the bounding box to include another bounding box.
Definition: shapes.py:33
def include(self, x, y)
Expands the box to include the point at x, y.
Definition: shapes.py:18
def __init__(self, x1=None, y1=None, x2=None, y2=None)
Definition: shapes.py:12
def __init__(self, position=None, size=None)
Definition: shapes.py:347
def to_bezier(self)
Returns a Shape corresponding to this ellipse.
Definition: shapes.py:365
def bounding_box(self, time=0)
Bounding box of the shape element at the given time.
Definition: shapes.py:354
def _bezier_t(self, time)
Definition: shapes.py:382
position
Ellipse's position.
Definition: shapes.py:350
Solid fill color.
Definition: shapes.py:509
def __init__(self, color=None)
Definition: shapes.py:521
opacity
Fill Opacity.
Definition: shapes.py:524
def __init__(self, colors=[])
Definition: shapes.py:577
def __init__(self, stroke_width=1)
Definition: shapes.py:676
def bounding_box(self, time=0)
Bounding box of the shape element at the given time.
Definition: shapes.py:681
highlight_angle
Highlight Angle.
Definition: shapes.py:560
highlight_length
Gradient Highlight Length.
Definition: shapes.py:558
gradient_type
Gradient Type.
Definition: shapes.py:556
start_point
Gradient Start Point.
Definition: shapes.py:552
end_point
Gradient End Point.
Definition: shapes.py:554
def __init__(self, colors=[])
Definition: shapes.py:548
colors
Gradient Colors.
Definition: shapes.py:562
ShapeElement that can contain other shapes.
Definition: shapes.py:433
number_of_properties
Group number of properties.
Definition: shapes.py:448
def bounding_box(self, time=0)
Bounding box of the shape element at the given time.
Definition: shapes.py:456
def add_shape(self, shape)
Definition: shapes.py:476
def insert_shape(self, index, shape)
Definition: shapes.py:480
def load(cls, lottiedict)
Loads from a JSON object.
Definition: shapes.py:485
shapes
Group list of items.
Definition: shapes.py:450
Interpolates the shape with its center point and bezier tangents with the opposite direction.
Definition: shapes.py:876
Animatable Bezier curve.
Definition: shapes.py:399
def __init__(self, bezier=None)
Definition: shapes.py:410
def to_bezier(self)
Returns a Path corresponding to this Shape.
Definition: shapes.py:428
shape
Shape's vertices.
Definition: shapes.py:413
def bounding_box(self, time=0)
Bounding box of the shape element at the given time.
Definition: shapes.py:417
A simple rectangle shape.
Definition: shapes.py:150
position
Rect's position.
Definition: shapes.py:165
def _bezier_t(self, time)
Definition: shapes.py:201
rounded
Rect's rounded corners.
Definition: shapes.py:169
def to_bezier(self)
Returns a Shape corresponding to this rect.
Definition: shapes.py:182
def __init__(self, pos=None, size=None, rounded=0)
Definition: shapes.py:162
def bounding_box(self, time=0)
Bounding box of the shape element at the given time.
Definition: shapes.py:171
transform
Transform values for each repeater copy.
Definition: shapes.py:779
def __init__(self, copies=1)
Definition: shapes.py:770
offset
Offset of Copies.
Definition: shapes.py:775
composite
Composite of copies.
Definition: shapes.py:777
copies
Number of Copies.
Definition: shapes.py:773
def __init__(self, radius=0)
Definition: shapes.py:794
radius
Rounded Corner Radius.
Definition: shapes.py:797
Base class for all elements of ShapeLayer and Group.
Definition: shapes.py:72
property_index
Property index.
Definition: shapes.py:89
def bounding_box(self, time=0)
Bounding box of the shape element at the given time.
Definition: shapes.py:95
Drawable shape.
Definition: shapes.py:129
direction
After Effect's Direction.
Definition: shapes.py:140
def to_bezier(self)
Returns a Path corresponding to this Shape.
Definition: shapes.py:142
def bounding_box(self, time=0)
Bounding box of the shape element at the given time.
Definition: shapes.py:276
outer_roundness
Star's outer roundness.
Definition: shapes.py:268
inner_radius
Star's inner radius.
Definition: shapes.py:262
def _bezier_t(self, time)
Definition: shapes.py:311
def to_bezier(self)
Returns a Shape corresponding to this star.
Definition: shapes.py:287
points
Star's number of points.
Definition: shapes.py:272
rotation
Star's rotation.
Definition: shapes.py:270
inner_roundness
Star's inner roundness.
Definition: shapes.py:264
star_type
Star's type.
Definition: shapes.py:274
outer_radius
Star's outer radius.
Definition: shapes.py:266
position
Star's position.
Definition: shapes.py:260
def __init__(self, length=0, type=StrokeDashType.Dash)
Definition: shapes.py:614
def __init__(self, color=None, width=1)
Definition: shapes.py:661
start
Start of the segment, as a percentage.
Definition: shapes.py:747
offset
start/end offset, as an angle (0, 360)
Definition: shapes.py:751
end
End of the segment, as a percentage.
Definition: shapes.py:749
Changes the edges of affected shapes into a series of peaks and valleys of uniform size.
Definition: shapes.py:850
size
Distance between peaks and troughs.
Definition: shapes.py:869
roundness
Radius to maked it a smoother curve.
Definition: shapes.py:867
points
Number of ridges.
Definition: shapes.py:871