def gen_hold_waypoints(deactive_time, layer, anim_type): """ Will only be used to modify opacity waypoints, and set zero values where the layer is deactive Args: deactive_time (set) : Range of time when the layer will be deactive layer (lxml.etree._Element) : Synfig format layer anim_type (str) : Specifies whether it is effects_opacity or opacity (it will effect a factor of 100) Returns: (lxml.etree._Element) : Modified opacity animation is returned """ for chld in layer: if chld.tag == "param" and chld.attrib["name"] == "amount": opacity = chld opacity = gen_dummy_waypoint(opacity, "param", anim_type, "amount") opacity_dict = {} gen_value_Keyframed(opacity_dict, opacity[0], 0) for it in deactive_time: # First add waypoints at both points, make it constant interval # then remove any in-between waypoints first = round(it[0] * settings.lottie_format["fr"]) second = round(it[1] * settings.lottie_format["fr"]) insert_waypoint_at_frame(opacity[0], opacity_dict, first, anim_type) insert_waypoint_at_frame(opacity[0], opacity_dict, second, anim_type) # Making it a constant interval for waypoint in opacity[0]: if approximate_equal(get_frame(waypoint), first): st_waypoint = waypoint break st_waypoint.attrib["after"] = "constant" st_waypoint[0].attrib["value"] = str(0) # removing the in between waypoints for waypoint in opacity[0]: this_frame = get_frame(waypoint) if (not approximate_equal(this_frame, first)) and \ (not approximate_equal(this_frame, second)) and \ (this_frame > first and this_frame < second): waypoint.getparent().remove(waypoint) return opacity
def gen_hold_waypoints(inactive_time, layer, anim_type): """ Will only be used to modify opacity waypoints, and set zero values where the layer is inactive Args: inactive_time (set) : Range of time when the layer will be inactive layer (common.Layer.Layer) : Synfig format layer anim_type (str) : Specifies whether it is effects_opacity or opacity (it will effect a factor of 100) Returns: (common.Param.Param) : Modified opacity animation is returned """ opacity = layer.get_param("amount") opacity.animate(anim_type) opacity_dict = {} opacity_dict["o"] = {} opacity.fill_path(opacity_dict, "o") opacity_dict = opacity_dict["o"] for it in inactive_time: # First add waypoints at both points, make it constant interval # then remove any in-between waypoints first = round(it[0] * settings.lottie_format["fr"]) second = round(it[1] * settings.lottie_format["fr"]) insert_waypoint_at_frame(opacity[0], opacity_dict, first, anim_type) insert_waypoint_at_frame(opacity[0], opacity_dict, second, anim_type) # Making it a constant interval for waypoint in opacity[0]: if approximate_equal(get_frame(waypoint), first): st_waypoint = waypoint break st_waypoint.attrib["after"] = "constant" st_waypoint[0].attrib["value"] = str(0) # removing the in between waypoints for waypoint in opacity[0]: this_frame = get_frame(waypoint) if (not approximate_equal(this_frame, first)) and \ (not approximate_equal(this_frame, second)) and \ (this_frame > first and this_frame < second): waypoint.getparent().remove(waypoint) return opacity
def insert_waypoint_at_frame(animated, orig_path, frame, animated_name): """ This function will only insert a waypoint at 'frame' if no waypoint is present at that 'frame' already Args: animated (lxml.etree._Element): Holds the animation in Synfig xml format orig_path (dict) : Holds the animation in Lottie format frame (int) : The frame at which the waypoint is to be inserted animated_name (str) : The name/type of animation Returns: (None) """ i = 0 while i < len(animated): at_frame = get_frame(animated[i]) if approximate_equal(frame, at_frame): return elif frame < at_frame: break i += 1 pos = get_vector_at_frame(orig_path, frame) pos = to_Synfig_axis(pos, animated_name) if i == len(animated): new_waypoint = copy.deepcopy(animated[i - 1]) else: new_waypoint = copy.deepcopy(animated[i]) if animated_name == "vector": new_waypoint[0][0].text = str(pos[0]) new_waypoint[0][1].text = str(pos[1]) else: new_waypoint[0].attrib["value"] = str(pos) new_waypoint.attrib["time"] = str( frame / settings.lottie_format["fr"]) + "s" if i == 0 or i == len(animated): # No need of tcb value copy as halt interpolation need to be copied here new_waypoint.attrib["before"] = new_waypoint.attrib[ "after"] = "constant" else: copy_tcb_average(new_waypoint, animated[i], animated[i - 1]) new_waypoint.attrib["before"] = animated[i - 1].attrib["after"] new_waypoint.attrib["after"] = animated[i].attrib["before"] # If the interval was constant before, then the whole interval should # remain constant now also if new_waypoint.attrib["before"] == "constant" or new_waypoint.attrib[ "after"] == "constant": new_waypoint.attrib["before"] = new_waypoint.attrib[ "after"] = "constant" animated.insert(i, new_waypoint)
def flip_time(time): """ Time will be in a set(); Example: input: ((2, 3), (4, 5)) output: ((0, 2), (3, 4), (5, frame_last_time)) Args: time (set) : Range of time is stored in this Returns: (set) : Flipped/opposite of `time` is returned """ ret = set() last = settings.lottie_format["op"] / settings.lottie_format["fr"] z = 0 for it in time: if (not approximate_equal(z, it[0])) and (not approximate_equal( it[0], it[1])): ret.add((z, it[0])) z = it[1] if not approximate_equal(z, last): ret.add((z, last)) return ret
def synfig_rectangle(st_val, point1_p, point2_p, expand_p, bevel_p, bevCircle, fr): """ Calculates the points for the rectangle layer as in Synfig: https://github.com/synfig/synfig/blob/678cc3a7b1208fcca18c8b54a29a20576c499927/synfig-core/src/modules/mod_geometry/rectangle.cpp Args: st_val (dict) : Lottie format rectangle will be stored in this point1_p (self.Param.Param) : Lottie format point1 animation point2_p (self.Param.Param) : Lottie format point2 animation expand_p (self.Param.Param) : Lottie format expand parameter animation bevel_p (self.Param.Param) : Lottie format bevel parameter animation bevCircle (lxml.etree._Element) : Animation of bevCircle in Synfig format fr (int) : Frame Number Returns: (None) """ expand = abs(to_Synfig_axis(expand_p.get_value(fr), "real")) bevel = abs(to_Synfig_axis(bevel_p.get_value(fr), "real")) p0 = to_Synfig_axis(point1_p.get_value(fr), "vector") p0 = Vector(p0[0], p0[1]) p1 = to_Synfig_axis(point2_p.get_value(fr), "vector") p1 = Vector(p1[0], p1[1]) if p1[0] < p0[0]: p0[0], p1[0] = p1[0], p0[0] if p1[1] < p0[1]: p0[1], p1[1] = p1[1], p0[1] bev_circle = bevCircle.get_value(fr) w = p1[0] - p0[0] + 2*expand h = p1[1] - p0[1] + 2*expand bev = bevel if bevel > 1: bev = 1 if bev_circle: bevx = min(w*bev/2.0, h*bev/2.0) bevy = min(w*bev/2.0, h*bev/2.0) else: bevx = w*bev/2.0 bevy = h*bev/2.0 # Setup chunk list chunk_list = [] if approximate_equal(bevel, 0.0): chunk_list.append([Vector(p0[0] - expand, p0[1] - expand), Vector(), Vector()]) chunk_list.append([Vector(p1[0] + expand, p0[1] - expand), Vector(), Vector()]) chunk_list.append([Vector(p1[0] + expand, p1[1] + expand), Vector(), Vector()]) chunk_list.append([Vector(p0[0] - expand, p1[1] + expand), Vector(), Vector()]) else: cur = Vector(p1[0] + expand - bevx, p0[1] - expand) chunk_list.append([cur, Vector(), Vector()]) prev = cur cur = Vector(p1[0] + expand, p0[1] - expand + bevy) cp1, cp2 = quadratic_to_cubic(cur, Vector(p1[0] + expand, p0[1] - expand), prev) chunk_list[-1][2] = cp2 - prev chunk_list.append([cur, cur - cp1, Vector()]) prev = cur cur = Vector(p1[0] + expand, p1[1] + expand - bevy) chunk_list.append([cur, Vector(), Vector()]) prev = cur cur = Vector(p1[0] + expand - bevx, p1[1] + expand) cp1, cp2 = quadratic_to_cubic(cur, Vector(p1[0] + expand, p1[1] + expand), prev) chunk_list[-1][2] = cp2 - prev chunk_list.append([cur, cur - cp1, Vector()]) prev = cur cur = Vector(p0[0] - expand + bevx, p1[1] + expand) chunk_list.append([cur, Vector(), Vector()]) prev = cur cur = Vector(p0[0] - expand, p1[1] + expand - bevy) cp1, cp2 = quadratic_to_cubic(cur, Vector(p0[0] - expand, p1[1] + expand), prev) chunk_list[-1][2] = cp2 - prev chunk_list.append([cur, cur - cp1, Vector()]) prev = cur cur = Vector(p0[0] - expand, p0[1] - expand + bevy) chunk_list.append([cur, Vector(), Vector()]) prev = cur cur = Vector(p0[0] - expand + bevx, p0[1] - expand) cp1, cp2 = quadratic_to_cubic(cur, Vector(p0[0] - expand, p0[1] - expand), prev) chunk_list[-1][2] = cp2 - prev chunk_list.append([cur, cur - cp1, Vector()]) prev = cur add(chunk_list, st_val, [0, 0], True)