Пример #1
0
 def gen_path(self, anim_type="real", idx=0):
     """
     Generates the path for this parameter over time depending on the
     animation type of this parameter
     """
     self.path = {}
     if anim_type in {"real", "bool"}:
         gen_value_Keyframed(self.path, self.param[0], idx)
     else:
         gen_properties_multi_dimensional_keyframed(self.path, self.param[0], idx)
Пример #2
0
def gen_image_scale(animated_1, animated_2, width, height):
    """
    In Synfig, no scale parameter is available for image layer, so it will be
    created here for Lottie conversion

    Args:
        animated_1 (lxml.etree._Element): point1 animation in Synfig format
        animated_2 (lxml.etree._Element): point2 animation in Synfig format
        width      (int)                : Width of the original image
        height     (int)                : Height of the original image

    Returns:
        (lxml.etree._Element) : Scale parameter in Synfig format
    """
    st = '<param name="image_scale"><real value="0.0000000000"/></param>'
    root = etree.fromstring(st)
    is_animate = is_animated(root)
    root = gen_dummy_waypoint(root, is_animate, "image_scale")

    anim1_path, anim2_path = {}, {}
    gen_properties_multi_dimensional_keyframed(anim1_path, animated_1, 0)
    gen_properties_multi_dimensional_keyframed(anim2_path, animated_2, 0)

    # Filling the first 2 frames with there original scale values
    fill_image_scale_at_frame(root[0], anim1_path, anim2_path, width, height,
                              0)
    fill_image_scale_at_frame(root[0], anim1_path, anim2_path, width, height,
                              1)

    mx_fr = max(get_frame(animated_1[-1]), get_frame(animated_2[-1]))
    fr = 2
    while fr <= mx_fr:
        new_waypoint = copy.deepcopy(root[0][0])
        time = fr / settings.lottie_format["fr"]
        time = str(time) + "s"
        new_waypoint.attrib["time"] = time
        root[0].append(new_waypoint)
        fill_image_scale_at_frame(root[0], anim1_path, anim2_path, width,
                                  height, fr)
        fr += 1
    return root
Пример #3
0
def append_path(element, parent, element_name, typ="real"):
    """
    Generates a dictionary corresponding to the path followed by that element
    and appends it at the parent which will be needed later

    Args:
        element (lxml.etree._Element) : Synfig format element/parameter
        parent  (lxml.etree._Element) : Parent of the element/parameter
        element_name (str)            : Tag of the dictionary to be stored in parent
        typ (:obj: str, optional)     : Specifies the type of dictionary to be created

    Returns:
        (None)
    """
    # Generating the path and store in the lxml element
    element_dict = {}
    if typ == "real":
        gen_value_Keyframed(element_dict, element, 0)
    else:
        gen_properties_multi_dimensional_keyframed(element_dict, element, 0)
    # Store in lxml element
    element_lxml = etree.Element(element_name)
    element_lxml.text = str(element_dict)
    parent.append(element_lxml)
Пример #4
0
def gen_helpers_transform(lottie,
                          layer,
                          pos=settings.DEFAULT_POSITION,
                          anchor=settings.DEFAULT_ANCHOR,
                          scale=settings.DEFAULT_SCALE,
                          rotation=settings.DEFAULT_ROTATION,
                          opacity=settings.DEFAULT_OPACITY):
    """
    Generates the dictionary corresponding to helpers/transform.json

    Args:
        lottie (dict)                : Lottie format layer
        layer  (lxml.etree._Element) : Synfig format layer
        pos    (:obj: `list | lxml.etree._Element`, optional) : position of layer
        anchor (:obj: `list | lxml.etree._Element`, optional) : anchor point of layer
        scale (:obj: `list | lxml.etree._Element`, optional) : scale of layer
        rotation (:obj: `float | lxml.etree._Element`, optional) : rotation of layer
        opacity (:obj: `float | lxml.etree._Element`, optional) : Opacity of layer

    Returns:
        (None)
    """
    index = Count()
    lottie["o"] = {}  # opacity/Amount
    lottie["r"] = {}  # Rotation of the layer
    lottie["p"] = {}  # Position of the layer
    lottie["a"] = {}  # Anchor point of the layer
    lottie["s"] = {}  # Scale of the layer

    # setting the position
    if isinstance(pos, list):
        gen_properties_value(lottie["p"], pos, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)
    else:
        is_animate = is_animated(pos)
        if is_animate == 2:
            gen_properties_multi_dimensional_keyframed(lottie["p"], pos,
                                                       index.inc())
        else:
            x_val, y_val = 0, 0
            if is_animate == 0:
                x_val = float(pos[0].text) * settings.PIX_PER_UNIT
                y_val = float(pos[1].text) * settings.PIX_PER_UNIT
            else:
                x_val = float(pos[0][0][0].text) * settings.PIX_PER_UNIT
                y_val = float(pos[0][0][1].text) * settings.PIX_PER_UNIT
            gen_properties_value(lottie["p"], change_axis(x_val, y_val, True),
                                 index.inc(), settings.DEFAULT_ANIMATED,
                                 settings.NO_INFO)

    # setting the opacity
    if isinstance(opacity, (float, int)):
        gen_properties_value(lottie["o"], opacity, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)
    else:
        is_animate = is_animated(opacity)
        if is_animate == 2:
            opacity.attrib["type"] = "opacity"
            gen_value_Keyframed(lottie["o"], opacity, index.inc())
        else:
            if is_animate == 0:
                val = float(
                    opacity.attrib["value"]) * settings.OPACITY_CONSTANT
            else:
                val = float(
                    opacity[0][0].attrib["value"]) * settings.OPACITY_CONSTANT
            gen_properties_value(lottie["o"], val, index.inc(),
                                 settings.DEFAULT_ANIMATED, settings.NO_INFO)

    # setting the rotation
    if isinstance(rotation, (float, int)):
        gen_properties_value(lottie["r"], rotation, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)
    else:
        is_animate = is_animated(rotation)
        if is_animate == 2:
            gen_value_Keyframed(lottie["r"], rotation, index.inc())
        else:
            theta = 0  # default rotation
            if is_animate == 0:
                theta = (float(rotation.attrib["value"]))
            else:
                theta = (float(rotation[0][0].attrib["value"]))
            gen_properties_value(lottie["r"], theta, index.inc(),
                                 settings.DEFAULT_ANIMATED, settings.NO_INFO)

    # setting the anchor point
    if isinstance(anchor, list):
        gen_properties_value(lottie["a"], anchor, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)
    else:
        is_animate = is_animated(anchor)
        if is_animate == 2:
            gen_properties_multi_dimensional_keyframed(lottie["a"], anchor,
                                                       index.inc())
        else:
            x_val, y_val = 0, 0
            if is_animate == 0:
                x_val = float(anchor[0].text) * settings.PIX_PER_UNIT
                y_val = float(anchor[1].text) * settings.PIX_PER_UNIT
            else:
                x_val = float(anchor[0][0][0].text) * settings.PIX_PER_UNIT
                y_val = float(anchor[0][0][1].text) * settings.PIX_PER_UNIT
            gen_properties_value(lottie["a"], change_axis(x_val, y_val, True),
                                 index.inc(), settings.DEFAULT_ANIMATED,
                                 settings.NO_INFO)

    # setting the scale
    if isinstance(scale, list):
        gen_properties_value(lottie["s"], scale, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)
    # This means scale parameter is animated
    else:
        is_animate = is_animated(scale)
        if is_animate == 2:
            gen_value_Keyframed(lottie["s"], scale, index.inc())
        else:
            zoom = 0
            if is_animate == 0:
                zoom = float(scale.attrib["value"])
            else:
                zoom = float(scale[0][0].attrib["value"])
            zoom = (math.e**zoom) * 100
            gen_properties_value(lottie["s"], [zoom, zoom], index.inc(),
                                 settings.DEFAULT_ANIMATED, settings.NO_INFO)
Пример #5
0
def both_points_animated(animated_1, animated_2, param_expand, lottie, index):
    """
    This function generates the lottie dictionary for position and size property
    of lottie(point1 and point2 are used from Synfig), when both point1 and
    point2 are animated

    Args:
        animated_1      (lxml.etree._Element): Holds the parameter `point1`'s animation in Synfig xml format
        animated_2      (lxml.etree._Element): Holds the parameter `point2`'s animation in Synfig xml format
        param_expand    (lxml.etree._Element): Holds the parameter `expand`'s animation in Synfig xml format
        lottie          (dict)               : Lottie format rectangle layer will be store in this
        index           (int)                : Stores the index of parameters in rectangle layer

    Returns:
        (None)
    """
    animated_1, animated_2 = animated_1[0], animated_2[0]
    orig_path_1, orig_path_2 = {}, {}
    expand_path = {}
    gen_value_Keyframed(expand_path, param_expand[0], 0)
    gen_properties_multi_dimensional_keyframed(orig_path_1, animated_1, 0)
    gen_properties_multi_dimensional_keyframed(orig_path_2, animated_2, 0)

    #################### SECTION 1 ###########################
    # Insert waypoints in the point1 and point2 parameter at the place where
    # expand parameter is animated
    time_list = set()
    get_animated_time_list(param_expand, time_list)
    for frame in time_list:
        insert_waypoint_at_frame(animated_1, orig_path_1, frame, "vector")
        insert_waypoint_at_frame(animated_2, orig_path_2, frame, "vector")

    #################### END OF SECTION 1 ####################

    ### SECTION TRY ###
    # Every frames value is precomputed in order to achieve maximum similarity
    # to that of Synfig
    st_fr = min(get_frame(animated_1[0]), get_frame(animated_2[0]))
    en_fr = max(get_frame(animated_1[-1]), get_frame(animated_2[-1]))
    fra = st_fr
    while fra <= en_fr:
        insert_waypoint_at_frame(animated_1, orig_path_1, fra, "vector")
        insert_waypoint_at_frame(animated_2, orig_path_2, fra, "vector")
        fra += 1
    ### END SECTION ###

    ######################### SECTION 2 ##########################
    # Insert the waypoints at corresponding positions where point1 is animated
    # and point2 is animated
    for waypoint in animated_1:
        frame = get_frame(waypoint)
        insert_waypoint_at_frame(animated_2, orig_path_2, frame, "vector")

    for waypoint in animated_2:
        frame = get_frame(waypoint)
        insert_waypoint_at_frame(animated_1, orig_path_1, frame, "vector")
    ##################### END OF SECTION 2 #######################

    ##################### SECTION 3 ##############################
    # Add the impact of expand parameter amount towards point1 and point2
    # parameter
    assert len(animated_1) == len(animated_2)
    for waypoint1, waypoint2 in zip(animated_1, animated_2):
        frame = get_frame(waypoint1)
        assert frame == get_frame(waypoint2)
        expand_amount = get_vector_at_frame(expand_path, frame)
        expand_amount = to_Synfig_axis(expand_amount, "real")

        pos1, pos2 = get_vector(waypoint1), get_vector(waypoint2)
        # Comparing the x-coordinates
        if pos1[0] > pos2[0]:
            pos1[0] += expand_amount
            pos2[0] -= expand_amount
        else:
            pos1[0] -= expand_amount
            pos2[0] += expand_amount
        # Comparing the y-coordinates
        if pos1[1] > pos2[1]:
            pos1[1] += expand_amount
            pos2[1] -= expand_amount
        else:
            pos1[1] -= expand_amount
            pos2[1] += expand_amount
        set_vector(waypoint1, pos1)
        set_vector(waypoint2, pos2)
    ##################### END OF SECTION 3 #######################

    #################### SECTION 4 #############################
    # Place waypoints at which the x and y cross each other/cross the extremas
    cross_list = get_cross_list(animated_1, animated_2, orig_path_1,
                                orig_path_2)
    for frame in cross_list:
        insert_waypoint_at_frame(animated_1, orig_path_1, frame, "vector")
        insert_waypoint_at_frame(animated_2, orig_path_2, frame, "vector")
    #################### END SECTION 4 #########################

    ################## SECTION 5 ################################################
    # Store the position of rectangle according to the waypoints in pos_animated
    # Store the size of rectangle according to the waypoints in size_animated
    pos_animated = copy.deepcopy(animated_1)
    size_animated = copy.deepcopy(animated_1)
    size_animated.attrib["type"] = "rectangle_size"

    i, i1 = 0, 0
    while i < len(animated_1) - 1:
        cur_get_after_1, cur_get_after_2 = animated_1[i].attrib[
            "after"], animated_2[i].attrib["after"]
        next_get_before_1, next_get_before_2 = animated_1[
            i + 1].attrib["before"], animated_2[i + 1].attrib["before"]

        dic_1 = {"linear", "auto", "clamped", "halt"}
        dic_2 = {"constant"}
        constant_interval_1 = cur_get_after_1 in dic_2 or next_get_before_1 in dic_2
        constant_interval_2 = cur_get_after_2 in dic_2 or next_get_before_2 in dic_2

        # Case 1 no "constant" interval is present
        if (cur_get_after_1 in dic_1) and (cur_get_after_2 in dic_1) and (
                next_get_before_1 in dic_1) and (next_get_before_2 in dic_1):
            get_average(pos_animated[i1], animated_1[i], animated_2[i])
            copy_tcb_average(pos_animated[i1], animated_1[i], animated_2[i])

            get_difference(size_animated[i1], animated_1[i], animated_2[i])
            copy_tcb(size_animated[i1], pos_animated[i1])
            i, i1 = i + 1, i1 + 1
            get_average(pos_animated[i1], animated_1[i], animated_2[i])
            copy_tcb_average(pos_animated[i1], animated_1[i], animated_2[i])

            get_difference(size_animated[i1], animated_1[i], animated_2[i])
            copy_tcb(size_animated[i1], pos_animated[i1])

        # Case 2 only one "constant" interval: could mean two "constant"'s are present
        elif (constant_interval_1
              and not constant_interval_2) or (not constant_interval_1
                                               and constant_interval_2):
            if constant_interval_1:
                i, i1 = calc_pos_and_size(size_animated, pos_animated,
                                          animated_1, animated_2, orig_path_2,
                                          i, i1)
            elif constant_interval_2:
                i, i1 = calc_pos_and_size(size_animated, pos_animated,
                                          animated_2, animated_1, orig_path_1,
                                          i, i1)

        # Case 3 both are constant
        elif constant_interval_1 and constant_interval_2:
            # No need to copy tcb, as it's pos should be "constant"
            get_average(pos_animated[i1], animated_1[i], animated_2[i])
            get_difference(size_animated[i1], animated_1[i], animated_2[i])

            i, i1 = i + 1, i1 + 1
            get_difference(size_animated[i1], animated_1[i], animated_2[i])
            get_average(pos_animated[i1], animated_1[i], animated_2[i])
    ######################### SECTION 5 END ##############################

    ######################### SECTION 6 ##################################
    # Generate the position and size for lottie format
    gen_properties_multi_dimensional_keyframed(lottie["p"], pos_animated,
                                               index.inc())
    gen_value_Keyframed(lottie["s"], size_animated, index.inc())
Пример #6
0
def gen_shapes_circle(lottie, layer, idx):
    """
    Generates the dictionary corresponding to shapes/ellipse.json where ellipse
    will always be considered as circle

    Args:
        lottie (dict)               : The lottie generated circle layer will be stored in it
        layer  (lxml.etree._Element): Synfig format circle layer
        idx    (int)                : Stores the index of the circle layer

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = "el"  # Type: circle
    lottie["p"] = {}  # Position of circle
    lottie["d"] = settings.DEFAULT_DIRECTION
    lottie["s"] = {}  # Size of circle
    lottie["ix"] = idx  # setting the index

    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] in {"origin", "center"}:
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_properties_multi_dimensional_keyframed(
                        lottie["p"], child[0], index.inc())
                else:
                    x_val, y_val = 0, 0
                    if is_animate == 0:
                        x_val = float(child[0][0].text) * settings.PIX_PER_UNIT
                        y_val = float(child[0][1].text) * settings.PIX_PER_UNIT
                    else:
                        x_val = float(
                            child[0][0][0][0].text) * settings.PIX_PER_UNIT
                        y_val = float(
                            child[0][0][0][1].text) * settings.PIX_PER_UNIT
                    gen_properties_value(lottie["p"],
                                         change_axis(x_val,
                                                     y_val), index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)

            # This will be exported as size of ellipse in lottie format
            elif child.attrib["name"] == "radius":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    child[0].attrib['type'] = "circle_radius"
                    gen_value_Keyframed(lottie["s"], child[0], index.inc())
                else:
                    radius = 0  # default value for radius
                    if is_animate == 0:
                        radius = float(child[0].attrib["value"])
                    else:
                        radius = float(child[0][0][0].attrib["value"])

                    radius_pix = int(settings.PIX_PER_UNIT) * radius
                    diam = radius_pix * 2
                    gen_properties_value(lottie["s"], [diam, diam],
                                         index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
Пример #7
0
def gen_shapes_star(lottie, layer, idx):
    """
    Generates the dictionary corresponding to shapes/star.json

    Args:
        lottie (dict)               : The lottie generated star layer will be stored in it
        layer  (lxml.etree._Element): Synfig format star layer
        idx    (int)                : Stores the index of the star layer

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = "sr"  # Type: star
    lottie["pt"] = {}  # Number of points on the star
    lottie["p"] = {}  # Position of star
    lottie["r"] = {}  # Angle / Star's rotation
    lottie["ir"] = {}  # Inner radius
    lottie["or"] = {}  # Outer radius
    lottie["is"] = {}  # Inner roundness of the star
    lottie["os"] = {}  # Outer roundness of the star
    regular_polygon = {"prop": "false"}
    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "regular_polygon":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    regular_polygon["prop"] = "changing"
                    # Copy the child address to dictionary
                    regular_polygon["animated"] = child[0]
                elif is_animate == 1:
                    regular_polygon["prop"] = child[0][0][0].attrib["value"]
                else:
                    regular_polygon["prop"] = child[0].attrib["value"]
                regular_polygon["animate"] = is_animate

            elif child.attrib["name"] == "points":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    # To uniquely identify the points, attribute type is changed
                    child[0].attrib['type'] = 'points'
                    gen_value_Keyframed(lottie["pt"], child[0], index.inc())

                else:
                    num_points = 3  # default number of points
                    if is_animate == 0:
                        num_points = int(child[0].attrib["value"])
                    else:
                        num_points = int(child[0][0][0].attrib["value"])
                    gen_properties_value(lottie["pt"], num_points, index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
            elif child.attrib["name"] == "angle":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_value_Keyframed(lottie["r"], child[0], index.inc())
                else:
                    theta = 0  # default angle for the star
                    if is_animate == 0:
                        theta = get_angle(float(child[0].attrib["value"]))
                    else:
                        theta = get_angle(float(
                            child[0][0][0].attrib["value"]))
                    gen_properties_value(lottie["r"], theta, index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
            elif child.attrib["name"] == "radius1":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_value_Keyframed(lottie["or"], child[0], index.inc())
                else:
                    r_outer = 0  # default value for outer radius
                    if is_animate == 0:
                        r_outer = float(child[0].attrib["value"])
                    else:
                        r_outer = float(child[0][0][0].attrib["value"])

                    gen_properties_value(lottie["or"],
                                         int(settings.PIX_PER_UNIT * r_outer),
                                         index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
            elif child.attrib["name"] == "radius2":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_value_Keyframed(lottie["ir"], child[0], index.inc())
                else:
                    r_inner = 0  # default value for inner radius
                    if is_animate == 0:
                        r_inner = float(child[0].attrib["value"])
                    else:
                        r_inner = float(child[0][0][0].attrib["value"])
                    gen_properties_value(lottie["ir"],
                                         int(settings.PIX_PER_UNIT * r_inner),
                                         index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
            elif child.attrib["name"] == "origin":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_properties_multi_dimensional_keyframed(
                        lottie["p"], child[0], index.inc())
                else:
                    x_val, y_val = 0, 0
                    if is_animate == 0:
                        x_val = float(child[0][0].text) * settings.PIX_PER_UNIT
                        y_val = float(child[0][1].text) * settings.PIX_PER_UNIT
                    else:
                        x_val = float(
                            child[0][0][0][0].text) * settings.PIX_PER_UNIT
                        y_val = float(
                            child[0][0][0][1].text) * settings.PIX_PER_UNIT
                    gen_properties_value(lottie["p"],
                                         change_axis(x_val,
                                                     y_val), index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)

    # If not animated, then go to if, else
    if regular_polygon["animate"] in {0, 1}:
        if regular_polygon["prop"] == "false":
            lottie["sy"] = 1  # Star Type

            # inner property is only needed if type is star
            gen_properties_value(lottie["is"], 0, index.inc(),
                                 settings.DEFAULT_ANIMATED, settings.NO_INFO)
        else:
            lottie["sy"] = 2  # Polygon Type

            # for polygon type, "ir" and "is" must not be present
            del lottie["ir"]

    # If animated, it will always be of type star
    else:
        polygon_correction(lottie, regular_polygon["animated"])

        lottie["sy"] = 1
        gen_properties_value(lottie["is"], 0, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    gen_properties_value(lottie["os"], 0, index.inc(),
                         settings.DEFAULT_ANIMATED, settings.NO_INFO)
    lottie["ix"] = idx
Пример #8
0
def gen_dynamic_list_polygon(lottie, dynamic_list):
    """
    Generates the bline corresponding to polygon layer

    Args:
        lottie (dict) : Lottie format polygon layer will be stored here
        dynamic_list (lxml.etree._Element) : Synfig format points of polygon

    Returns:
        (None)
    """
    ################## SECTION 1 ################
    # Inserting the waypoints if not animated, finding the first and last frame
    # Calculating the path after this
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1
    count = 0

    for entry in dynamic_list:
        pos = entry
        update_frame_window(pos[0], window)

        new_pos = gen_dummy_waypoint(pos, "entry", "vector")
        pos.getparent().remove(pos)
        dynamic_list.insert(count, new_pos)

        append_path(new_pos[0], dynamic_list[count], "pos_path", "vector")

        count += 1

    layer = dynamic_list.getparent().getparent()
    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "origin":
                origin = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin_parent = origin.getparent()
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(origin_parent, origin, "param", "origin")

    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################ END OF SECTION 1 ##############

    ################ SECTION 2 #####################
    # Generating values for all the frames in the window
    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, False)

        for entry in dynamic_list:
            # Only two childs, one should be animated, other one is path
            for child in entry:
                if child.tag == "pos_path":
                    dictionary = ast.literal_eval(child.text)
                    pos_cur = get_vector_at_frame(dictionary, fr)
                    pos_next = get_vector_at_frame(dictionary, fr + 1)

            tangent1_cur, tangent2_cur = Vector(0, 0), Vector(0, 0)
            tangent1_next, tangent2_next = Vector(0, 0), Vector(0, 0)

            # Adding origin to each vertex
            origin_cur = get_vector_at_frame(origin_dict, fr)
            origin_next = get_vector_at_frame(origin_dict, fr + 1)
            for i in range(len(pos_cur)):
                pos_cur[i] += origin_cur[i]
            for i in range(len(pos_next)):
                pos_next[i] += origin_next[i]

            # Store values in dictionary
            st_val["i"].append(tangent1_cur.get_list())
            st_val["o"].append(tangent2_cur.get_list())
            st_val["v"].append(pos_cur)
            en_val["i"].append(tangent1_next.get_list())
            en_val["o"].append(tangent2_next.get_list())
            en_val["v"].append(pos_next)
        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
Пример #9
0
def gen_bline_outline(lottie, bline_point):
    """
    Generates the bline corresponding to outline layer by adding some vertices
    to bline and converting it to region layer

    Some parts are common with gen_bline_shapePropKeyframe(), which will be
    placed in a common function latter

    Args:
        lottie (dict) : Lottie format outline layer will be stored in this
        bline_point (lxml.etree._Element) : Synfig format bline points

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    for entry in bline_point:
        composite = entry[0]
        for child in composite:
            if child.tag == "point":
                pos = child
            elif child.tag == "width":
                width = child
            elif child.tag == "t1":
                t1 = child
            elif child.tag == "t2":
                t2 = child
            elif child.tag == "split_radius":
                split_r = child
            elif child.tag == "split_angle":
                split_a = child

        # Necassary to update this before inserting new waypoints, as new
        # waypoints might include there on time: 0 seconds
        update_frame_window(pos[0], window)

        # Empty the pos and fill in the new animated pos
        pos = gen_dummy_waypoint(pos, "point", "vector")
        update_child_at_parent(composite, pos, "point")

        # Empty the width and fill in the new animated width
        update_frame_window(width[0], window)
        width = gen_dummy_waypoint(width, "width", "real")
        update_child_at_parent(composite, width, "width")

        update_frame_window(split_r[0], window)
        split_r = gen_dummy_waypoint(split_r, "split_radius", "bool")
        update_child_at_parent(composite, split_r, "split_radius")

        update_frame_window(split_a[0], window)
        split_a = gen_dummy_waypoint(split_a, "split_angle", "bool")
        update_child_at_parent(composite, split_a, "split_angle")

        append_path(pos[0], composite, "point_path", "vector")
        append_path(width[0], composite, "width_path")

        animate_radial_composite(t1[0], window)
        animate_radial_composite(t2[0], window)

    layer = bline_point.getparent().getparent()
    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "width":
                outer_width = chld
            elif chld.attrib["name"] == "sharp_cusps":
                sharp_cusps = chld
            elif chld.attrib["name"] == "expand":
                expand = chld
            elif chld.attrib["name"] == "round_tip[0]":
                r_tip0 = chld
            elif chld.attrib["name"] == "round_tip[1]":
                r_tip1 = chld
            elif chld.attrib["name"] == "homogeneous_width":
                homo_width = chld
            elif chld.attrib["name"] == "origin":
                origin = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin_parent = origin.getparent()
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(origin_parent, origin, "param", "origin")
    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    update_frame_window(outer_width[0], window)
    outer_width = gen_dummy_waypoint(outer_width, "param", "real", "width")
    # Update the layer with this animated outline width
    update_child_at_parent(layer, outer_width, "param", "width")

    # Generate outline width for Lottie format
    # No need to store this dictionary in lxml element, as it will be used in this function and will not be rewritten
    outer_width_dict = {}
    gen_value_Keyframed(outer_width_dict, outer_width[0], 0)

    # Animating the sharp_cusps
    update_frame_window(sharp_cusps[0], window)
    sharp_cusps = gen_dummy_waypoint(sharp_cusps, "param", "bool",
                                     "sharp_cusps")

    # Update the layer with this animated outline sharp cusps
    update_child_at_parent(layer, sharp_cusps, "param", "sharp_cusps")

    update_frame_window(expand[0], window)
    expand = gen_dummy_waypoint(expand, "param", "real", "expand")
    update_child_at_parent(layer, expand, "param", "expand")
    expand_dict = {}
    gen_value_Keyframed(expand_dict, expand[0], 0)

    update_frame_window(r_tip0[0], window)
    r_tip0 = gen_dummy_waypoint(r_tip0, "param", "bool", "round_tip[0]")
    update_child_at_parent(layer, r_tip0, "param", "round_tip[0]")

    update_frame_window(r_tip1[0], window)
    r_tip1 = gen_dummy_waypoint(r_tip1, "param", "bool", "round_tip[1]")
    update_child_at_parent(layer, r_tip1, "param", "round_tip[1]")

    update_frame_window(homo_width[0], window)
    homo_width = gen_dummy_waypoint(homo_width, "param", "bool",
                                    "homogeneous_width")
    update_child_at_parent(layer, homo_width, "param", "homogeneous_width")

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(
            lottie, -1, fr,
            False)  # This loop needs to be considered somewhere down

        synfig_outline(bline_point, st_val, origin_dict, outer_width_dict,
                       sharp_cusps, expand_dict, r_tip0, r_tip1, homo_width,
                       fr)
        synfig_outline(bline_point, en_val, origin_dict, outer_width_dict,
                       sharp_cusps, expand_dict, r_tip0, r_tip1, homo_width,
                       fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
Пример #10
0
def gen_bline_region(lottie, bline_point):
    """
    Generates the dictionary corresponding to properties/shapePropKeyframe.json,
    given a bline/spline

    Args:
        lottie     (dict) : Lottie generated keyframes will be stored here for shape/path
        bline_path (lxml.etree._Element) : shape/path store in Synfig format

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    loop = False
    if "loop" in bline_point.keys():
        val = bline_point.attrib["loop"]
        if val == "false":
            loop = False
        else:
            loop = True

    for entry in bline_point:
        composite = entry[0]
        for child in composite:
            if child.tag == "point":
                pos = child
            elif child.tag == "t1":
                t1 = child
            elif child.tag == "t2":
                t2 = child
            elif child.tag == "split_radius":
                split_r = child
            elif child.tag == "split_angle":
                split_a = child

        # Necassary to update this before inserting new waypoints, as new
        # waypoints might include there on time: 0 seconds
        update_frame_window(pos[0], window)

        # Empty the pos and fill in the new animated pos
        pos = gen_dummy_waypoint(pos, "point", "vector")
        update_child_at_parent(composite, pos, "point")

        update_frame_window(split_r[0], window)
        split_r = gen_dummy_waypoint(split_r, "split_radius", "bool")
        update_child_at_parent(composite, split_r, "split_radius")

        update_frame_window(split_a[0], window)
        split_a = gen_dummy_waypoint(split_a, "split_angle", "bool")
        update_child_at_parent(composite, split_a, "split_angle")

        append_path(pos[0], composite, "point_path", "vector")

        animate_radial_composite(t1[0], window)
        animate_radial_composite(t2[0], window)

    layer = bline_point.getparent().getparent()
    for chld in layer:
        if chld.tag == "param" and chld.attrib["name"] == "origin":
            origin = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin_parent = origin.getparent()
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(origin_parent, origin, "param", "origin")

    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window
    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, loop)

        for entry in bline_point:
            composite = entry[0]
            for child in composite:
                if child.tag == "point_path":
                    dictionary = ast.literal_eval(child.text)
                    pos_cur = get_vector_at_frame(dictionary, fr)
                    pos_next = get_vector_at_frame(dictionary, fr + 1)
                elif child.tag == "t1":
                    t1 = child[0]
                elif child.tag == "t2":
                    t2 = child[0]
                elif child.tag == "split_radius":
                    split_r = child
                elif child.tag == "split_angle":
                    split_a = child

            tangent1_cur, tangent2_cur = get_tangent_at_frame(
                t1, t2, split_r, split_a, fr)
            tangent1_next, tangent2_next = get_tangent_at_frame(
                t1, t2, split_r, split_a, fr)

            tangent1_cur, tangent2_cur = convert_tangent_to_lottie(
                tangent1_cur, tangent2_cur)
            tangent1_next, tangent2_next = convert_tangent_to_lottie(
                tangent1_next, tangent2_next)

            # Adding origin to each vertex
            origin_cur = get_vector_at_frame(origin_dict, fr)
            origin_next = get_vector_at_frame(origin_dict, fr + 1)
            for i in range(len(pos_cur)):
                pos_cur[i] += origin_cur[i]
            for i in range(len(pos_next)):
                pos_next[i] += origin_next[i]

            # Store values in dictionary
            st_val["i"].append(tangent1_cur.get_list())
            st_val["o"].append(tangent2_cur.get_list())
            st_val["v"].append(pos_cur)
            en_val["i"].append(tangent1_next.get_list())
            en_val["o"].append(tangent2_next.get_list())
            en_val["v"].append(pos_next)
        fr += 1
    # Setting final time
    lottie.append({})
    lottie[-1]["t"] = fr
Пример #11
0
def gen_shapes_star(lottie, layer, idx):
    """
    Generates the dictionary corresponding to shapes/star.json

    Args:
        lottie (dict)               : The lottie generated star layer will be stored in it
        layer  (common.Layer.Layer)  : Synfig format star layer
        idx    (int)                : Stores the index of the star layer

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = "sr"  # Type: star
    lottie["pt"] = {}  # Number of points on the star
    lottie["p"] = {}  # Position of star
    lottie["r"] = {}  # Angle / Star's rotation
    lottie["ir"] = {}  # Inner radius
    lottie["or"] = {}  # Outer radius
    lottie["is"] = {}  # Inner roundness of the star
    lottie["os"] = {}  # Outer roundness of the star
    regular_polygon = {"prop": "false"}

    # Regular polygon
    rp = layer.get_param("regular_polygon").get()
    is_animate = is_animated(rp[0])
    if is_animate == settings.ANIMATED:
        regular_polygon["prop"] = "changing"
        regular_polygon["animated"] = rp[0]
    elif is_animate == settings.SINGLE_WAYPOINT:
        regular_polygon["prop"] = rp[0][0][0].attrib["value"]
    else:
        regular_polygon["prop"] = rp[0].attrib["value"]
    regular_polygon["animate"] = is_animate

    # Points
    points = layer.get_param("points").get()
    is_animate = is_animated(points[0])
    if is_animate == settings.ANIMATED:
        # To uniquely identify the points, attribute type is changed
        points[0].attrib['type'] = 'points'
        gen_value_Keyframed(lottie["pt"], points[0], index.inc())
    else:
        num_points = 3  # default number of points
        if is_animate == settings.NOT_ANIMATED:
            num_points = int(points[0].attrib["value"])
        else:
            num_points = int(points[0][0][0].attrib["value"])
        gen_properties_value(lottie["pt"], num_points, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    # Angle
    angle = layer.get_param("angle").get()
    is_animate = is_animated(angle[0])
    if is_animate == settings.ANIMATED:
        gen_value_Keyframed(lottie["r"], angle[0], index.inc())
    else:
        theta = 0  # default angle for the star
        if is_animate == settings.NOT_ANIMATED:
            theta = get_angle(float(angle[0].attrib["value"]))
        else:
            theta = get_angle(float(angle[0][0][0].attrib["value"]))
        gen_properties_value(lottie["r"], theta, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    # Radius1
    radius1 = layer.get_param("radius1").get()
    is_animate = is_animated(radius1[0])
    if is_animate == settings.ANIMATED:
        gen_value_Keyframed(lottie["or"], radius1[0], index.inc())
    else:
        r_outer = 0  # default value for outer radius
        if is_animate == settings.NOT_ANIMATED:
            r_outer = float(radius1[0].attrib["value"])
        else:
            r_outer = float(radius1[0][0][0].attrib["value"])
        gen_properties_value(lottie["or"],
                             int(settings.PIX_PER_UNIT * r_outer), index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    # Radius2
    radius2 = layer.get_param("radius2").get()
    is_animate = is_animated(radius2[0])
    if is_animate == settings.ANIMATED:
        gen_value_Keyframed(lottie["ir"], radius2[0], index.inc())
    else:
        r_inner = 0  # default value for inner radius
        if is_animate == settings.NOT_ANIMATED:
            r_inner = float(radius2[0].attrib["value"])
        else:
            r_inner = float(radius2[0][0][0].attrib["value"])
        gen_properties_value(lottie["ir"],
                             int(settings.PIX_PER_UNIT * r_inner), index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    # Origin
    origin = layer.get_param("origin").get()
    is_animate = is_animated(origin[0])
    if is_animate == settings.ANIMATED:
        gen_properties_multi_dimensional_keyframed(lottie["p"], origin[0],
                                                   index.inc())
    else:
        x_val, y_val = 0, 0
        if is_animate == settings.NOT_ANIMATED:
            x_val = float(origin[0][0].text) * settings.PIX_PER_UNIT
            y_val = float(origin[0][1].text) * settings.PIX_PER_UNIT
        else:
            x_val = float(origin[0][0][0][0].text) * settings.PIX_PER_UNIT
            y_val = float(origin[0][0][0][1].text) * settings.PIX_PER_UNIT
        gen_properties_value(lottie["p"], change_axis(x_val,
                                                      y_val), index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    # If not animated, then go to if, else
    if regular_polygon["animate"] in {0, 1}:
        if regular_polygon["prop"] == "false":
            lottie["sy"] = 1  # Star Type

            # inner property is only needed if type is star
            gen_properties_value(lottie["is"], 0, index.inc(),
                                 settings.DEFAULT_ANIMATED, settings.NO_INFO)
        else:
            lottie["sy"] = 2  # Polygon Type

            # for polygon type, "ir" and "is" must not be present
            del lottie["ir"]

    # If animated, it will always be of type star
    else:
        lottie["sy"] = 1
        gen_properties_value(lottie["is"], 0, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

    gen_properties_value(lottie["os"], 0, index.inc(),
                         settings.DEFAULT_ANIMATED, settings.NO_INFO)
    lottie["ix"] = idx
Пример #12
0
def gen_list_circle(lottie, layer):
    """
    Generates a shape layer corresponding to circle layer by manipulating the
    origin and radius of the circle

    Args:
        lottie (dict) : Lottie format circle layer will be stored in this
        layer (lxml.etree._Element) : Synfig format circle layer

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "origin":
                origin = chld
            elif chld.attrib["name"] == "radius":
                radius = chld

    # Animating the origin
    update_frame_window(origin[0], window)
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(layer, origin, "param", "origin")
    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    update_frame_window(radius[0], window)
    radius = gen_dummy_waypoint(radius, "param", "real", "radius")
    update_child_at_parent(layer, radius, "param", "width")

    # Generate radius for Lottie format
    radius_dict = {}
    gen_value_Keyframed(radius_dict, radius[0], 0)

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(
            lottie, -1, fr,
            False)  # This loop needs to be considered somewhere down

        synfig_circle(st_val, origin_dict, radius_dict, fr)
        synfig_circle(en_val, origin_dict, radius_dict, fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
Пример #13
0
def gen_list_rectangle(lottie, layer):
    """
    Generates a shape layer corresponding to rectangle layer by manipulating the
    parameters of the rectangle

    Args:
        lottie (dict) : Lottie format rectangle layer will be stored in this
        layer (lxml.etree._Element) : Synfig format rectangle layer

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1
    bevel_found = False
    expand_found = False

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "point1":
                point1 = chld
            elif chld.attrib["name"] == "point2":
                point2 = chld
            elif chld.attrib["name"] == "expand":
                expand_found = True
                expand = chld
            elif chld.attrib["name"] == "bevel":
                bevel_found = True
                bevel = chld
            elif chld.attrib["name"] == "bevCircle":
                bevCircle = chld

    if not expand_found:  # Means filled rectangle layer
        st = "<param name='expand'><real value='0.0'/></param>"
        expand = etree.fromstring(st)

    if not bevel_found:  # For rectangle layer in stable version 1.2.2
        st = "<param name='bevel'><real value='0.0'/></param>"
        bevel = etree.fromstring(st)
        st = "<param name='bevCircle'><bool value='false'/></param>"
        bevCircle = etree.fromstring(st)

    # Animating point1
    update_frame_window(point1[0], window)
    point1 = gen_dummy_waypoint(point1, "param", "vector", "point1")
    update_child_at_parent(layer, point1, "param", "point1")
    # Generate path for the point1 component
    p1_dict = {}
    #point1[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(p1_dict, point1[0], 0)

    # Animating point2
    update_frame_window(point2[0], window)
    point2 = gen_dummy_waypoint(point2, "param", "vector", "point2")
    update_child_at_parent(layer, point2, "param", "point2")
    # Generate path for the point2 component
    p2_dict = {}
    gen_properties_multi_dimensional_keyframed(p2_dict, point2[0], 0)

    # Animating expand
    update_frame_window(expand[0], window)
    expand = gen_dummy_waypoint(expand, "param", "real", "expand")
    update_child_at_parent(layer, expand, "param", "expand")
    # Generate expand param for Lottie format
    expand_dict = {}
    gen_value_Keyframed(expand_dict, expand[0], 0)

    # Animating bevel
    update_frame_window(bevel[0], window)
    bevel = gen_dummy_waypoint(bevel, "param", "real", "bevel")
    update_child_at_parent(layer, bevel, "param", "bevel")
    # Generate bevel param for Lottie format
    bevel_dict = {}
    gen_value_Keyframed(bevel_dict, bevel[0], 0)

    # Animating bevCircle
    update_frame_window(bevCircle[0], window)
    bevCircle = gen_dummy_waypoint(bevCircle, "param", "bool", "bevCircle")
    update_child_at_parent(layer, bevCircle, "param", "bevCircle")

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, False)

        synfig_rectangle(st_val, p1_dict, p2_dict, expand_dict, bevel_dict,
                         bevCircle, fr)
        synfig_rectangle(en_val, p1_dict, p2_dict, expand_dict, bevel_dict,
                         bevCircle, fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr
Пример #14
0
def gen_helpers_transform(lottie, layer, pos=[0, 0], anchor=[0, 0, 0], scale=[100, 100, 100]):
    """
    Generates the dictionary corresponding to helpers/transform.json

    Args:
        lottie (dict)                : Lottie format layer
        layer  (lxml.etree._Element) : Synfig format layer
        pos    (:obj: `list | lxml.etree._Element`, optional) : position of layer
        anchor (:obj: `list`) : anchor point of layer
        scale (:obj: `list | lxml.etree._Element`, optional) : scale of layer

    Returns:
        (None)
    """
    index = Count()
    lottie["o"] = {}    # opacity/Amount
    lottie["r"] = {}    # Rotation of the layer
    lottie["p"] = {}    # Position of the layer
    lottie["a"] = {}    # Anchor point of the layer
    lottie["s"] = {}    # Scale of the layer

    # setting the default location
    if isinstance(pos, list):
        gen_properties_value(lottie["p"],
                             pos,
                             index.inc(),
                             settings.DEFAULT_ANIMATED,
                             settings.NO_INFO)
    else:
        gen_properties_multi_dimensional_keyframed(lottie["p"],
                                                   pos,
                                                   index.inc())

    # setting the default opacity i.e. 100
    gen_properties_value(lottie["o"],
                         settings.DEFAULT_OPACITY,
                         index.inc(),
                         settings.DEFAULT_ANIMATED,
                         settings.NO_INFO)

    # setting the rotation
    gen_properties_value(lottie["r"],
                         settings.DEFAULT_ROTATION,
                         index.inc(),
                         settings.DEFAULT_ANIMATED,
                         settings.NO_INFO)

    # setting the anchor point
    gen_properties_value(lottie["a"],
                         anchor,
                         index.inc(),
                         settings.DEFAULT_ANIMATED,
                         settings.NO_INFO)

    # setting the scale
    if isinstance(scale, list):
        gen_properties_value(lottie["s"],
                             scale,
                             index.inc(),
                             settings.DEFAULT_ANIMATED,
                             settings.NO_INFO)
    # This means scale parameter is animated
    else:
        gen_value_Keyframed(lottie["s"], scale, index.inc())
Пример #15
0
def gen_list_star(lottie, layer):
    """
    Generates a shape layer corresponding to star layer by manipulating the
    parameters of the star

    Args:
        lottie (dict) : Lottie format rectangle layer will be stored in this
        layer (lxml.etree._Element) : Synfig format rectangle layer

    Returns:
        (None)
    """
    ################### SECTION 1 #########################
    # Inserting waypoints if not animated and finding the first and last frame
    # AFter that, there path will be calculated in lottie format which can
    # latter be used in get_vector_at_frame() function
    window = {}
    window["first"] = sys.maxsize
    window["last"] = -1

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "origin":
                origin = chld
            elif chld.attrib["name"] == "radius1":
                radius1 = chld
            elif chld.attrib["name"] == "radius2":
                radius2 = chld
            elif chld.attrib["name"] == "angle":
                angle = chld
            elif chld.attrib["name"] == "points":
                points = chld
            elif chld.attrib["name"] == "regular_polygon":
                regular_polygon = chld

    # Animating origin
    update_frame_window(origin[0], window)
    origin = gen_dummy_waypoint(origin, "param", "vector", "origin")
    update_child_at_parent(layer, origin, "param", "origin")
    # Generate path for the origin component
    origin_dict = {}
    origin[0].attrib["transform_axis"] = "true"
    gen_properties_multi_dimensional_keyframed(origin_dict, origin[0], 0)

    # Animating radius1
    update_frame_window(radius1[0], window)
    radius1 = gen_dummy_waypoint(radius1, "param", "real", "radius1")
    update_child_at_parent(layer, radius1, "param", "radius1")
    # Generate expand param for Lottie format
    radius1_dict = {}
    gen_value_Keyframed(radius1_dict, radius1[0], 0)

    # Animating radius2
    update_frame_window(radius2[0], window)
    radius2 = gen_dummy_waypoint(radius2, "param", "real", "radius2")
    update_child_at_parent(layer, radius2, "param", "radius2")
    # Generate expand param for Lottie format
    radius2_dict = {}
    gen_value_Keyframed(radius2_dict, radius2[0], 0)

    # Animating angle
    update_frame_window(angle[0], window)
    angle = gen_dummy_waypoint(angle, "param", "star_angle_new", "angle")
    update_child_at_parent(layer, angle, "param", "angle")
    # Generate expand param for Lottie format
    angle_dict = {}
    gen_value_Keyframed(angle_dict, angle[0], 0)

    # Animating points
    update_frame_window(points[0], window)
    points = gen_dummy_waypoint(points, "param", "real", "points")
    update_child_at_parent(layer, points, "param", "points")
    # Generate expand param for Lottie format
    points_dict = {}
    gen_value_Keyframed(points_dict, points[0], 0)

    mx_points = get_max_points(points)

    # Animating regular_polygon
    update_frame_window(regular_polygon[0], window)
    regular_polygon = gen_dummy_waypoint(regular_polygon, "param", "bool",
                                         "regular_polygon")
    update_child_at_parent(layer, regular_polygon, "param", "regular_polygon")

    # Minimizing the window size
    if window["first"] == sys.maxsize and window["last"] == -1:
        window["first"] = window["last"] = 0
    ################# END OF SECTION 1 ###################

    ################ SECTION 2 ###########################
    # Generating values for all the frames in the window

    fr = window["first"]
    while fr <= window["last"]:
        st_val, en_val = insert_dict_at(lottie, -1, fr, False)
        synfig_star(st_val, mx_points, origin_dict, radius1_dict, radius2_dict,
                    angle_dict, points_dict, regular_polygon, fr)
        synfig_star(en_val, mx_points, origin_dict, radius1_dict, radius2_dict,
                    angle_dict, points_dict, regular_polygon, fr + 1)

        fr += 1
    # Setting the final time
    lottie.append({})
    lottie[-1]["t"] = fr