Coverage for lib/lottie/objects/helpers.py: 76%
84 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
1import math
2from .base import LottieObject, LottieProp, LottieEnum
3from .properties import MultiDimensional, Value, NVector, ShapeProperty, PositionValue
6## @ingroup Lottie
7class Transform(LottieObject):
8 """!
9 Layer transform
10 """
11 _props = [
12 LottieProp("anchor_point", "a", PositionValue, False),
13 LottieProp("position", "p", PositionValue, False),
14 LottieProp("scale", "s", MultiDimensional, False),
15 LottieProp("rotation", "r", Value, False),
16 LottieProp("opacity", "o", Value, False),
17 LottieProp("skew", "sk", Value, False),
18 LottieProp("skew_axis", "sa", Value, False),
19 LottieProp("orientation", "or", MultiDimensional, False),
20 ]
22 def __init__(self):
23 ## Transform Anchor Point
24 self.anchor_point = PositionValue(NVector(0, 0))
25 ## Transform Position
26 self.position = PositionValue(NVector(0, 0))
27 ## Transform Scale
28 self.scale = MultiDimensional(NVector(100, 100))
29 ## Transform Rotation
30 self.rotation = Value(0)
31 ## Transform Opacity
32 self.opacity = Value(100)
34 """
35 # Transform Position X
36 #self.position_x = Value()
37 ## Transform Position Y
38 #self.position_y = Value()
39 ## Transform Position Z
40 #self.position_z = Value()
41 """
43 ## Transform Skew
44 self.skew = Value(0)
45 ## Transform Skew Axis.
46 ## An angle, if 0 skews on the X axis, if 90 skews on the Y axis
47 self.skew_axis = Value(0)
49 self.orientation = None
51 def to_matrix(self, time, auto_orient=False):
52 from ..utils.transform import TransformMatrix
53 mat = TransformMatrix()
55 anchor = self.anchor_point.get_value(time) if self.anchor_point else NVector(0, 0)
56 mat.translate(-anchor.x, -anchor.y)
58 scale = self.scale.get_value(time) if self.scale else NVector(100, 100)
59 mat.scale(scale.x / 100, scale.y / 100)
61 skew = (self.skew.get_value(time) * math.pi / 180) if self.skew else 0
62 if skew != 0: 62 ↛ 63line 62 didn't jump to line 63, because the condition on line 62 was never true
63 axis = (self.skew_axis.get_value(time) * math.pi / 180) if self.skew_axis else 0
64 mat.skew_from_axis(-skew, axis)
66 rot = (self.rotation.get_value(time) * math.pi / 180) if self.rotation else 0
67 if rot: 67 ↛ 68line 67 didn't jump to line 68, because the condition on line 67 was never true
68 mat.rotate(-rot)
70 if auto_orient: 70 ↛ 71line 70 didn't jump to line 71, because the condition on line 70 was never true
71 if self.position and self.position.animated:
72 ao_angle = self.position.get_tangent_angle(time)
73 mat.rotate(-ao_angle)
75 pos = self.position.get_value(time) if self.position else NVector(0, 0)
76 mat.translate(pos.x, pos.y)
78 return mat
81## @ingroup Lottie
82class MaskMode(LottieEnum):
83 """!
84 How masks interact with each other
85 @see https://helpx.adobe.com/after-effects/using/alpha-channels-masks-mattes.html
86 """
87 No = "n"
88 Add = "a"
89 Subtract = "s"
90 Intersect = "i"
91 ## @note Not in lottie web
92 Lighten = "l"
93 ## @note Not in lottie web
94 Darken = "d"
95 ## @note Not in lottie web
96 Difference = "f"
99## @ingroup Lottie
100class VisualObject(LottieObject):
101 _props = [
102 LottieProp("name", "nm", str, False),
103 LottieProp("match_name", "mn", str, False),
104 ]
106 def __init__(self):
107 super().__init__()
108 # Object name
109 self.name = None
110 # Used for expression
111 self.match_name = None
114## @ingroup Lottie
115## @todo Implement SVG/SIF I/O
116class Mask(VisualObject):
117 _props = [
118 LottieProp("inverted", "inv", bool, False),
119 LottieProp("shape", "pt", ShapeProperty, False),
120 LottieProp("opacity", "o", Value, False),
121 LottieProp("mode", "mode", MaskMode, False),
122 LottieProp("dilate", "x", Value, False),
123 ]
125 def __init__(self, bezier=None):
126 super().__init__()
127 ## Inverted Mask flag
128 self.inverted = False
129 ## Mask vertices
130 self.shape = ShapeProperty(bezier)
131 ## Mask opacity.
132 self.opacity = Value(100)
133 ## Mask mode. Not all mask types are supported.
134 self.mode = MaskMode.Intersect
135 self.dilate = Value(0)
137 def __str__(self):
138 return self.name or super().__str__()
141## @ingroup Lottie
142class BlendMode(LottieEnum):
143 Normal = 0
144 Multiply = 1
145 Screen = 2
146 Overlay = 3
147 Darken = 4
148 Lighten = 5
149 ColorDodge = 6
150 ColorBurn = 7
151 HardLight = 8
152 SoftLight = 9
153 Difference = 10
154 Exclusion = 11
155 Hue = 12
156 Saturation = 13
157 Color = 14
158 Luminosity = 15
161#ingroup Lottie
162class Marker(LottieObject):
163 """!
164 Defines named portions of the composition.
165 """
166 _props = [
167 LottieProp("comment", "cm", str, False),
168 LottieProp("time", "tm", float, False),
169 LottieProp("duration", "dr", float, False),
170 ]
172 def __init__(self):
173 super().__init__()
175 self.comment = None
176 self.time = None
177 self.duration = None