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

1import math 

2from .base import LottieObject, LottieProp, LottieEnum 

3from .properties import MultiDimensional, Value, NVector, ShapeProperty, PositionValue 

4 

5 

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 ] 

21 

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) 

33 

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 """ 

42 

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) 

48 

49 self.orientation = None 

50 

51 def to_matrix(self, time, auto_orient=False): 

52 from ..utils.transform import TransformMatrix 

53 mat = TransformMatrix() 

54 

55 anchor = self.anchor_point.get_value(time) if self.anchor_point else NVector(0, 0) 

56 mat.translate(-anchor.x, -anchor.y) 

57 

58 scale = self.scale.get_value(time) if self.scale else NVector(100, 100) 

59 mat.scale(scale.x / 100, scale.y / 100) 

60 

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) 

65 

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) 

69 

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) 

74 

75 pos = self.position.get_value(time) if self.position else NVector(0, 0) 

76 mat.translate(pos.x, pos.y) 

77 

78 return mat 

79 

80 

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" 

97 

98 

99## @ingroup Lottie 

100class VisualObject(LottieObject): 

101 _props = [ 

102 LottieProp("name", "nm", str, False), 

103 LottieProp("match_name", "mn", str, False), 

104 ] 

105 

106 def __init__(self): 

107 super().__init__() 

108 # Object name 

109 self.name = None 

110 # Used for expression 

111 self.match_name = None 

112 

113 

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 ] 

124 

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) 

136 

137 def __str__(self): 

138 return self.name or super().__str__() 

139 

140 

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 

159 

160 

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 ] 

171 

172 def __init__(self): 

173 super().__init__() 

174 

175 self.comment = None 

176 self.time = None 

177 self.duration = None