Coverage for lib/lottie/utils/tensor.py: 0%
62 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
1from .. import objects
4class TensorSerializer:
5 def process(self, animation: objects.Animation, flatten: bool = True):
6 data = []
7 for layer in animation.layers:
8 self.process_layer(layer, data)
10 if flatten:
11 return self.flatten(data)
13 return data
15 def process_layer(self, layer, data):
16 if not isinstance(layer, objects.ShapeLayer):
17 return
19 self.process_shape_group(layer, data)
21 def process_shape(self, shape: objects.Path, data: dict):
22 bez = shape.shape.get_value()
23 if bez and len(bez.vertices) > 1:
24 data["curves"].append(bez)
26 def process_styler(self, styler):
27 return {
28 "opacity": (styler.opacity.get_value() or 100) / 100,
29 "color":
30 styler.gradient.get_stops()[0][0]
31 if isinstance(styler, objects.Gradient)
32 else styler.color.get_value()
33 }
35 def process_shape_group(self, group, data):
36 shape_data = {
37 "curves": [],
38 "fill": None,
39 "stroke": None
40 }
42 for shape in group.shapes:
43 if shape.hidden:
44 continue
46 if isinstance(shape, objects.Group):
47 child_data = self.process_shape_group(shape, data)
48 shape_data["curves"] += child_data["curves"]
49 elif isinstance(shape, objects.Path):
50 self.process_shape(shape, shape_data)
51 elif isinstance(shape, objects.Shape):
52 self.process_shape(shape.to_bezier(), shape_data)
53 elif isinstance(shape, (objects.Fill, objects.GradientFill)):
54 shape_data["fill"] = self.process_styler(shape)
55 elif isinstance(shape, objects.BaseStroke):
56 shape_data["stroke"] = self.process_styler(shape)
57 shape_data["stroke"]["width"] = shape.width.get_value()
59 if shape_data["curves"] and (shape_data["fill"] or shape_data["stroke"]):
60 data.append(shape_data)
62 return shape_data
64 def flatten_color(self, data):
65 if not data:
66 return None
67 return list(data["color"])[0:3] + [data["opacity"]]
69 def flatten(self, data):
70 flattened = []
71 for item in data:
72 base = {
73 "fill": self.flatten_color(item["fill"]),
74 "stroke": self.flatten_color(item["stroke"]),
75 "stroke_width": item["stroke"]["width"] if item["stroke"] else 0,
76 }
77 base["color"] = base["fill"] or base["stroke"]
79 for curve in item["curves"]:
80 points = []
81 for i in range(len(curve.vertices)):
82 v = curve.vertices[i]
83 points.append(list(v))
84 points.append(list(curve.out_tangents[i] + v))
85 next_i = (i+1) % len(curve.vertices)
86 points.append(list(curve.in_tangents[next_i] + curve.vertices[next_i]))
88 if curve.closed:
89 points.push(list(curve.vertices[0]))
90 else:
91 points.pop()
92 points.pop()
94 flattened.append({
95 **base,
96 "points": points,
97 "closed": int(curve.closed)
98 })
100 return flattened