Exemplo n.º 1
0
def gen_shapes_fill(lottie, layer):
    """
    Generates the dictionary corresponding to shapes/fill.json

    Args:
        lottie (dict)               : The lottie generated fill layer will be stored in it
        layer  (lxml.etree._Element): Synfig format fill (can be shape/solid anything, we
                                      only need color and opacity part from it) layer

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = "fl"  # Type if fill
    lottie["c"] = {}  # Color
    lottie["o"] = {}  # Opacity of the fill layer
    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "color":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_value_Keyframed(lottie["c"], child[0], index.inc())

                else:
                    if is_animate == 0:
                        val = child[0]
                    else:
                        val = child[0][0][0]
                    red = float(val[0].text)
                    green = float(val[1].text)
                    blue = float(val[2].text)
                    red, green, blue = red ** (1/settings.GAMMA), green **\
                    (1/settings.GAMMA), blue ** (1/ settings.GAMMA)
                    alpha = float(val[3].text)
                    gen_properties_value(lottie["c"],
                                         [red, green, blue, alpha],
                                         index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)

            elif child.attrib["name"] == "amount":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    # Telling the function that this is for opacity
                    child[0].attrib['type'] = 'opacity'
                    gen_value_Keyframed(lottie["o"], child[0], index.inc())

                else:
                    if is_animate == 0:
                        val = float(child[0].attrib["value"]
                                    ) * settings.OPACITY_CONSTANT
                    else:
                        val = float(child[0][0][0].attrib["value"]
                                    ) * settings.OPACITY_CONSTANT
                    gen_properties_value(lottie["o"], val, index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
Exemplo n.º 2
0
def gen_layer_image(lottie, layer, idx):
    """
    Generates the dictionary corresponding to layers/image.json

    Args:
        lottie (dict)               : Lottie generated image stored here
        layer  (lxml.etree._Element): Synfig format image layer
        idx    (int)                : Stores the index(number of) of image layer

    Returns:
        (None)
    """
    index = Count()
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_IMAGE_TYPE
    lottie["nm"] = settings.LAYER_IMAGE_NAME + str(idx)
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled

    settings.lottie_format["assets"].append({})
    st = add_image_asset(settings.lottie_format["assets"][-1], layer)
    asset = settings.lottie_format["assets"][-1]

    # setting class (jpg, png)
    lottie["cl"] = asset["p"].split(".")[-1]

    # setting the reference id
    lottie["refId"] = asset["id"]

    pos1_animate = is_animated(st["tl"][0])
    pos2_animate = is_animated(st["br"][0])
    # If pos1 is not animated
    if pos1_animate in {0, 1}:
        st["tl"] = gen_dummy_waypoint(st["tl"], pos1_animate, "vector")
    # If pos2 is not animated
    if pos2_animate in {0, 1}:
        st["br"] = gen_dummy_waypoint(st["br"], pos2_animate, "vector")

    st["scale"] = gen_image_scale(st["tl"][0], st["br"][0], asset["w"],
                                  asset["h"])
    anchor = [0, 0, 0]

    gen_helpers_transform(lottie["ks"], layer, st["tl"][0], anchor,
                          st["scale"][0])

    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT

    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)
    lottie["markers"] = []  # Markers to be filled yet
Exemplo n.º 3
0
def gen_effects_opacity(lottie, layer, idx):
    """
    Generates the dictionary corresponding to effects/opacity.json

    Args:
        lottie (dict)                : Lottie format effects stored in this
        layer  (lxml.etree._Element) : Synfig format layer
        idx    (int)                 : Index/Count of effect

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = settings.EFFECTS_OPACITY     # Effect type
    lottie["nm"] = "Opacity"                    # Name
    lottie["ix"] = idx                          # Index
    lottie["v"] = {}                            # Value of opacity
    for child in layer:
        if child.attrib["name"] == "amount":
            is_animate = is_animated(child[0])
            if is_animate == 2:
                # Telling the function that this is for opacity
                child[0].attrib['type'] = 'effects_opacity'
                gen_value_Keyframed(lottie["v"], child[0], index.inc())

            else:
                if is_animate == 0:
                    val = float(child[0].attrib["value"])
                else:
                    val = float(child[0][0][0].attrib["value"])
                gen_properties_value(lottie["v"],
                                     val,
                                     index.inc(),
                                     settings.DEFAULT_ANIMATED,
                                     settings.NO_INFO)
Exemplo n.º 4
0
def get_animated_time_list(child, time_list):
    """
    Appends all the frames corresponding to the waypoints in the
    animated(child[0]) list, in time_list

    Args:
        child     (lxml.etree._Element) : Parent Element of animation
        time_list (set)                 : Will store all the frames at which waypoints are present

    Returns:
        (None)
    """
    animated = child[0]
    is_animate = is_animated(animated)
    if is_animate in {0, 1}:
        return
    for waypoint in animated:
        frame = get_frame(waypoint)
        time_list.add(frame)
Exemplo n.º 5
0
def gen_effects_color(lottie, layer, idx):
    """
    Generates the dictionary corresponding to effects/color.json

    Args:
        lottie (dict)                : Lottie format effects stored in this
        layer  (lxml.etree._Element) : Synfig format layer
        idx    (int)                 : Index/Count of effect

    Returns:
        (None)

    """
    index = Count()
    lottie["ty"] = settings.EFFECTS_COLOR  # Effect type
    lottie["nm"] = "Color"  # Name
    lottie["ix"] = idx  # Index
    lottie["v"] = {}  # Value of color
    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "color":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_value_Keyframed(lottie["v"], child[0], index.inc())

                else:
                    if is_animate == 0:
                        val = child[0]
                    else:
                        val = child[0][0][0]
                    red = float(val[0].text)
                    green = float(val[1].text)
                    blue = float(val[2].text)
                    red, green, blue = red ** (1/settings.GAMMA), green **\
                    (1/settings.GAMMA), blue ** (1/ settings.GAMMA)
                    alpha = float(val[3].text)
                    gen_properties_value(lottie["v"],
                                         [red, green, blue, alpha],
                                         index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
Exemplo n.º 6
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
Exemplo n.º 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
Exemplo n.º 8
0
def gen_shapes_rectangle(lottie, layer, idx):
    """
    Generates the dictionary corresponding to shapes/rect.json

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

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = "rc"  # Type: rectangle
    lottie["p"] = {}  # Position of rectangle
    lottie["d"] = settings.DEFAULT_DIRECTION
    lottie["s"] = {}  # Size of rectangle
    lottie["ix"] = idx  # setting the index
    lottie["r"] = {}  # Rounded corners of rectangle
    points = {}

    for child in layer:
        if child.tag == "param":
            if child.attrib["name"] == "point1":
                points["1"] = child  # Store address of child here

            elif child.attrib["name"] == "point2":
                points["2"] = child  # Store address of child here

            elif child.attrib["name"] == "expand":
                expand_animate = is_animated(child[0])
                param_expand = child

            elif child.attrib["name"] == "bevel":
                is_animate = is_animated(child[0])
                if is_animate == 2:
                    gen_value_Keyframed(lottie["r"], child[0], index.inc())
                else:
                    bevel = get_child_value(is_animate, child, "value")
                    bevel *= settings.PIX_PER_UNIT
                    gen_properties_value(lottie["r"], bevel, index.inc(),
                                         settings.DEFAULT_ANIMATED,
                                         settings.NO_INFO)
    p1_animate = is_animated(points["1"][0])
    p2_animate = is_animated(points["2"][0])

    # If expand parameter is not animated
    if expand_animate in {0, 1}:
        param_expand = gen_dummy_waypoint(param_expand, expand_animate, "real")

    # p1 not animated and p2 not animated
    if p1_animate in {0, 1} and p2_animate in {0, 1}:
        points["1"] = gen_dummy_waypoint(points["1"], p1_animate, "vector")
        points["2"] = gen_dummy_waypoint(points["2"], p2_animate, "vector")

    # p1 is animated and p2 is not animated
    elif p1_animate == 2 and p2_animate in {0, 1}:
        points["2"] = gen_dummy_waypoint(points["2"], p2_animate, "vector")

    # p1 is not animated and p2 is animated
    elif p1_animate in {0, 1} and p2_animate == 2:
        points["1"] = gen_dummy_waypoint(points["1"], p1_animate, "vector")

    both_points_animated(points["1"], points["2"], param_expand, lottie, index)