Exemple #1
0
def gen_mask(lottie, invert, bline_point, idx):
    """
    Generates a mask. This was specifically needed to support the invert
    parameter

    Args:
        lottie      (dict) : The final mask will be stored in this dict
        invert      (bool) : Tells if the invert parameter is set or not
        bline_point (lxml.etree._Element) : Synfig format shape
        idx         (int)  : Specifies the index of this mask

    Returns:
        (None)
    """
    lottie["inv"] = invert
    lottie["mode"] = settings.MASK_ADDITIVE
    lottie["pt"] = {}
    lottie["o"] = {}  # Opacity
    lottie["x"] = {}  # Expression
    lottie["nm"] = "Mask " + str(idx)
    index = Count()

    gen_properties_shapeKeyframed(lottie["pt"], bline_point, index.inc())
    gen_properties_value(lottie["o"], settings.DEFAULT_OPACITY, index.inc(),
                         settings.DEFAULT_ANIMATED, settings.NO_INFO)
    gen_properties_value(lottie["x"], 0, index.inc(),
                         settings.DEFAULT_ANIMATED, settings.NO_INFO)

    convert_non_loop(lottie["pt"])
Exemple #2
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)
Exemple #3
0
def fill_blur_dict(lottie, layer, idx, direction):
    """
	This function will be called for each blur layer separately for the two directions

	Args:
		lottie    (dict)               : Lottie Dictionary for blur layers
		layers    (common.Layer.Layer) : Synfig format layer
		idx       (int)                : Stores the index(number of) of blur layer
		direction (string)             : Indicates the direction of blurring

	Returns:
		(None)
	"""
    index = Count()
    lottie["ty"] = settings.BLUR_TYPE
    lottie["nm"] = layer.get_description()
    lottie["mn"] = lottie["nm"]
    lottie["np"] = 5
    lottie["en"] = 1
    lottie["ix"] = idx
    lottie["ef"] = []
    size = layer.get_param("size").get()
    temp_blurriness = {}
    blurriness(temp_blurriness, size, index.inc(), direction)
    temp_directions = {}
    generate_dimensions_dict(temp_directions, index.inc(), direction)
    temp_pixels = {}
    generate_dimensions_dict(temp_pixels, index.inc(), "edge_pixels")

    lottie["ef"].append(temp_blurriness)
    lottie["ef"].append(temp_directions)
    lottie["ef"].append(temp_pixels)
Exemple #4
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)
Exemple #5
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  (common.Layer.Layer)  : 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

    # Color
    color = layer.get_param("color").get()
    is_animate = is_animated(color[0])
    if is_animate == settings.ANIMATED:
        gen_value_Keyframed(lottie["c"], color[0], index.inc())

    else:
        if is_animate == settings.NOT_ANIMATED:
            val = color[0]
        else:
            val = color[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[0]), green**(
            1 / settings.GAMMA[1]), blue**(1 / settings.GAMMA[2])
        alpha = float(val[3].text)
        gen_properties_value(lottie["c"], [red, green, blue, alpha],
                             index.inc(), settings.DEFAULT_ANIMATED,
                             settings.NO_INFO)

    # Color Opacity
    opacity = layer.get_param("amount").get()
    is_animate = is_animated(opacity[0])
    if is_animate == settings.ANIMATED:
        # Telling the function that this is for opacity
        opacity[0].attrib['type'] = 'opacity'
        gen_value_Keyframed(lottie["o"], opacity[0], index.inc())

    else:
        if is_animate == settings.NOT_ANIMATED:
            val = float(opacity[0].attrib["value"]) * settings.OPACITY_CONSTANT
        else:
            val = float(
                opacity[0][0][0].attrib["value"]) * settings.OPACITY_CONSTANT
        gen_properties_value(lottie["o"], val, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)
Exemple #6
0
def gen_layer_shape(lottie, layer, idx):
    """
    Generates the dictionary corresponding to layers/shape.json

    Args:
        lottie (dict)       : Lottie generate shape stored here
        layer  (common.Layer.Layer) : Synfig format shape layer
        idx    (int)        : Stores the index(number of) of shape layer

    Returns:
        (None)
    """

    if layer.get_type() in {"linear_gradient"}:
        # Create dummy point1 and point2 for linear gradient to generate rectangle for it in lottie format
        # Will have to use add_offset() function inside after this generation
        gen_dummy_rectangle(layer)

    layer.add_offset()

    index = Count()
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_SHAPE_TYPE
    lottie["nm"] = layer.get_description()
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled

    gen_helpers_transform(lottie["ks"])

    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT
    lottie["shapes"] = []  # Shapes to be filled yet
    lottie["shapes"].append({})
    if layer.get_type() == "star":
        gen_shapes_star(lottie["shapes"][0], layer, index.inc())
    elif layer.get_type() in {"circle", "simple_circle"}:
        gen_shapes_circle(lottie["shapes"][0], layer, index.inc())
    elif layer.get_type() in {"filled_rectangle", "rectangle"}:
        gen_shapes_rectangle(lottie["shapes"][0], layer.get_layer(),
                             index.inc())
    elif layer.get_type() in {"linear_gradient"}:
        gen_shapes_shape(lottie["shapes"][0], layer, index.inc())

    lottie["shapes"].append({})  # For the fill or color
    if layer.get_type() in {"linear_gradient"}:
        gen_linear_gradient(lottie["shapes"][1], layer, index.inc())
    else:
        gen_shapes_fill(lottie["shapes"][1], layer)

    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)
Exemple #7
0
def gen_linear_gradient(lottie, layer, idx):
    """
    Generates the dictionary corresponding to shapes/gFill.json but with linear gradient

    Args:
    """
    index = Count()
    lottie["ty"] = "gf"
    lottie["r"] = 1  # Don't know it's meaning yet, but works without this also
    lottie["o"] = {}  # Opacity of the gradient layer
    lottie["nm"] = layer.get_description()
    lottie["t"] = 1  # 1 means linear gradient layer
    lottie["s"] = {}  # Starting point of gradient
    lottie["e"] = {}  # Ending point of gradient
    lottie["g"] = {}  # Gradient information is stored here

    # Color Opacity
    opacity = layer.get_param("amount").get()
    is_animate = is_animated(opacity[0])
    if is_animate == settings.ANIMATED:
        # Telling the function that this is for opacity
        opacity[0].attrib['type'] = 'opacity'
        gen_value_Keyframed(lottie["o"], opacity[0], index.inc())

    else:
        if is_animate == settings.NOT_ANIMATED:
            val = float(opacity[0].attrib["value"]) * settings.OPACITY_CONSTANT
        else:
            val = float(
                opacity[0][0][0].attrib["value"]) * settings.OPACITY_CONSTANT
        gen_properties_value(lottie["o"], val, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

        # Starting point
        p1 = layer.get_param("p1")
        p1.animate("vector")
        p1.fill_path(lottie, "s")

        # Ending point
        p2 = layer.get_param("p2")
        p2.animate("vector")
        p2.fill_path(lottie, "e")

        # Gradient colors
        lottie["g"]["k"] = {}
        lottie["g"]["ix"] = index.inc()
        gradient = layer.get_param("gradient")
        modify_gradient(gradient)
        gradient.animate(
            "gradient")  # To find the lottie path of the modified gradient
        lottie["g"]["p"] = len(gradient.get()[0][0][0])
        gradient.fill_path(lottie["g"], "k")
        modify_gradient_according_to_latest_version(lottie["g"]["k"])
Exemple #8
0
def gen_layer_blur(lottie, layers):
    """
	This function will be called for each canvas/composition. Main function to
	generate all the layers

	Args:
		lottie (dict) : Lottie Dictionary for blur layers
		layers (List) : Dictionary of Synfig format layers

	Returns:
		(None)
	"""
    index = Count()
    for layer in layers:
        blur_dict_x = {}
        fill_blur_dict(blur_dict_x, layer, index.inc(), "horizontal")
        blur_dict_y = {}
        fill_blur_dict(blur_dict_y, layer, index.inc(), "vertical")
        lottie.append(blur_dict_x)
        lottie.append(blur_dict_y)
Exemple #9
0
def gen_layer_shape(lottie, layer, idx):
    """
    Generates the dictionary corresponding to layers/shape.json

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

    Returns:
        (None)
    """
    group.update_layer(layer)

    index = Count()
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_SHAPE_TYPE
    set_layer_desc(layer, settings.LAYER_SHAPE_NAME + str(idx), lottie)
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled

    gen_helpers_transform(lottie["ks"], layer)

    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT
    lottie["shapes"] = []  # Shapes to be filled yet
    lottie["shapes"].append({})
    if layer.attrib["type"] == "star":
        gen_shapes_star(lottie["shapes"][0], layer, index.inc())
    elif layer.attrib["type"] in {"circle", "simple_circle"}:
        gen_shapes_circle(lottie["shapes"][0], layer, index.inc())
    elif layer.attrib["type"] in {"filled_rectangle", "rectangle"}:
        gen_shapes_rectangle(lottie["shapes"][0], layer, index.inc())

    lottie["shapes"].append({})  # For the fill or color
    gen_shapes_fill(lottie["shapes"][1], layer)

    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)
Exemple #10
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)
Exemple #11
0
def gen_layer_solid(lottie, layer, idx):
    """
    Generates the dictionary corresponding to layers/solid.json

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

    Returns:
        (None)
    """
    index = Count()
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_SOLID_TYPE
    set_layer_desc(layer, settings.LAYER_SOLID_NAME + str(idx), lottie)
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled
    lottie["ef"] = []  # Stores the effects

    pos = [
        settings.lottie_format["w"] / 2 + get_additional_width() / 2,
        settings.lottie_format["h"] / 2 + get_additional_height() / 2
    ]

    anchor = pos
    gen_helpers_transform(lottie["ks"], layer, pos, anchor)

    lottie["ef"].append({})
    gen_effects_fill(lottie["ef"][-1], layer, index.inc())

    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT
    lottie["sw"] = settings.lottie_format["w"] + get_additional_width(
    )  # Solid Width
    lottie["sh"] = settings.lottie_format["h"] + get_additional_height(
    )  # Solid Height

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "color":
                lottie["sc"] = get_color_hex(chld[0])  # Solid Color

    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)
Exemple #12
0
def gen_shapes_shape(lottie, layer, idx):
    """
    Generates the dictionary corresponding to shapes/shape.json

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

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = "sh"  # Type: shape
    lottie["ix"] = idx  # Index
    lottie["ks"] = {}
    gen_properties_shapeKeyframed(lottie["ks"], layer, index.inc())
Exemple #13
0
def gen_effects_vfeather(lottie, idx):
    """
    Generates the dictionary corresponding to effects/vertical feather

    Args:
        lottie (dict)                : Lottie format effects stored in this
        idx    (int)                 : Index/Count of effect

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = settings.EFFECTS_VFEATHER  # Effect type
    lottie["nm"] = "Vertical Feather"  # Name
    lottie["ix"] = idx  # Index
    lottie["v"] = {}  # value
    gen_properties_value(lottie["v"], 0, index.inc(), 0, settings.NO_INFO)
Exemple #14
0
def gen_effects_fillmask(lottie, idx):
    """
    Generates the dictionary corresponding to effects/fillmask.json

    Args:
        lottie (dict)                : Lottie format effects stored in this
        idx    (int)                 : Index/Count of effect

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = settings.EFFECTS_FILL_MASK  # Effect type
    lottie["nm"] = "Fill Mask"  # Name
    lottie["ix"] = idx  # Index
    lottie["v"] = {}  # value
    gen_properties_value(lottie["v"], 0, index.inc(), 0, settings.NO_INFO)
Exemple #15
0
def gen_effects_hfeather(lottie, layer, idx):
    """
    Generates the dictionary corresponding to effects/horizontal feather

    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_HFEATHER        # Effect type
    lottie["nm"] = "Horizontal Feather"             # Name
    lottie["ix"] = idx                              # Index
    lottie["v"] = {}                                # value
    gen_properties_value(lottie["v"], 0, index.inc(), 0, settings.NO_INFO)
Exemple #16
0
def gen_effects_allmask(lottie, layer, idx):
    """
    Generates the dictionary corresponding to effects/allmask.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_ALL_MASK  # Effect type
    lottie["nm"] = "All Masks"  # Name
    lottie["ix"] = idx  # Index
    lottie["v"] = {}  # value
    gen_properties_value(lottie["v"], 0, index.inc(), 0, settings.NO_INFO)
Exemple #17
0
def gen_layer_solid(lottie, layer, idx):
    """
    Generates the dictionary corresponding to layers/solid.json

    Args:
        lottie (dict)       : Lottie generated solid layer stored here
        layer  (common.Layer.Layer) : Synfig format solid layer
        idx    (int)        : Stores the index(number of) of solid layer

    Returns:
        (None)
    """
    index = Count()
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_SOLID_TYPE
    lottie["nm"] = layer.get_description()
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled
    lottie["ef"] = []  # Stores the effects

    pos = [
        settings.lottie_format["w"] / 2 + get_additional_width() / 2,
        settings.lottie_format["h"] / 2 + get_additional_height() / 2
    ]

    anchor = pos
    gen_helpers_transform(lottie["ks"], pos, anchor)

    lottie["ef"].append({})
    gen_effects_fill(lottie["ef"][-1], layer, index.inc())

    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT
    lottie["sw"] = settings.lottie_format["w"] + get_additional_width(
    )  # Solid Width
    lottie["sh"] = settings.lottie_format["h"] + get_additional_height(
    )  # Solid Height

    lottie["sc"] = get_color_hex(layer.get_param("color").get()[0])

    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)
Exemple #18
0
def gen_effects_fill(lottie, layer, idx):
    """
    Generates the dictionary corresponding to effects/fill.json

    Args:
        lottie (dict)               : Lottie format layer
        layer  (common.Layer.Layer)  : Synfig format layer
        idx    (int)                : Index/Count of effect

    Returns:
        (None)
    """
    index = Count()
    lottie["ty"] = settings.EFFECTS_FILL  # Effect type
    lottie["nm"] = "Fill"  # Name
    lottie["ix"] = idx  # Index
    lottie["ef"] = []  # Effect list of properties

    # generating the fill mask, has no use in Synfig. But a necessity for
    # running the .json file
    lottie["ef"].append({})
    gen_effects_fillmask(lottie["ef"][-1], index.inc())

    # generating the all mask property as required by lottie
    lottie["ef"].append({})
    gen_effects_allmask(lottie["ef"][-1], index.inc())

    # generating the color property
    lottie["ef"].append({})
    gen_effects_color(lottie["ef"][-1], layer, index.inc())

    # generating the invert property as required by lottie
    lottie["ef"].append({})
    gen_effects_invert(lottie["ef"][-1], index.inc())

    # generating the horizontal feather as required by lottie
    lottie["ef"].append({})
    gen_effects_hfeather(lottie["ef"][-1], index.inc())

    # generating the vertical feather as required by lottie
    lottie["ef"].append({})
    gen_effects_vfeather(lottie["ef"][-1], index.inc())

    # generating the opacity
    lottie["ef"].append({})
    gen_effects_opacity(lottie["ef"][-1], layer, index.inc())
Exemple #19
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)
def gen_bline_outline_constant(lottie, bline_point, layer, transformation, idx):
	"""
	"""
	index = Count()
	lottie["ty"]  = "gr"
	lottie["nm"]  = "Shape "+ str(idx)
	lottie["np"]  = 3
	lottie["cix"] = 2
	lottie["bm"]  = 0
	lottie["ix"]  = idx
	lottie["mn"]  = "ADBE Vector Group " +str(idx)
	lottie["hd"]  = "false"
	lottie["it"]  = []
	lottie["it"].append({})
	lottie["it"].append({})
	lottie["it"].append({})

	bline = Bline(bline_point[0], bline_point)

	#Creating transformation dictionary
	lottie["it"][2]["ty"] = "tr"
	lottie["it"][2]["nm"] = "Transform"
	lottie["it"][2].update(transformation)
	#Creating stroke dictionary
	lottie["it"][1]["ty"] = "st"
	lottie["it"][1]["lc"] = 2
	lottie["it"][1]["lj"] = 1
	lottie["it"][1]["ml"] = 37
	lottie["it"][1]["bm"] = 0
	lottie["it"][1]["nm"] = "Stroke " + str(idx)
	lottie["it"][1]["mn"] = "ADBE Vector Graphic - Stroke " +str(idx)
	lottie["it"][1]["hd"] = "false"
	lottie["it"][1]["c"]  = {}
	lottie["it"][1]["o"]  = {}
	lottie["it"][1]["w"]  = {}

	#Color
	color = layer.get_param("color").get()
	is_animate = is_animated(color[0])
	if is_animate == settings.ANIMATED:
		gen_value_Keyframed(lottie["it"][1]["c"], color[0], index.inc())

	else:
		if is_animate == settings.NOT_ANIMATED:
			val = color[0]
		else:
			val = color[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[0]), green ** (1/settings.GAMMA[1]), blue ** (1/ settings.GAMMA[2])
		alpha = float(val[3].text)
		gen_properties_value(lottie["it"][1]["c"],
							[red, green, blue, alpha],
							index.inc(),
							settings.DEFAULT_ANIMATED,
							settings.NO_INFO)

	#Opacity
	opacity = layer.get_param("amount")
	opacity.animate("opacity")
	opacity.fill_path(lottie["it"][1],"o")

	#Constant width
	loop = bline.get_loop()
	width = layer.get_param("width")
	width.scale_convert_link(1)
	width.animate("real")
	width.fill_path(lottie["it"][1],"w")

	#Creating shape dictionary
	lottie["it"][0]["ind"] =  0
	lottie["it"][0]["ty"] = "sh"
	lottie["it"][0]["ix"] = 1
	lottie["it"][0]["ks"] = {}
	lottie["it"][0]["nm"] =  "Path 1"
	lottie["it"][0]["mn"] =  "ADBE Vector Shape - Group"
	lottie["it"][0]["hd"] =  "false"
	lottie["it"][0]["ks"]["a"] = 1 
	lottie["it"][0]["ks"]["ix"] = lottie["it"][0]["ix"] + 1 
	lottie["it"][0]["ks"]["k"] = []

	window = {}
	window["first"] = sys.maxsize
	window["last"] = -1

	for entry in bline.get_entry_list():
		pos = entry["point"]
		width = entry["width"]
		t1 = entry["t1"]
		t2 = entry["t2"]
		split_r = entry["split_radius"]
		split_a = entry["split_angle"]

		pos.update_frame_window(window)
		# Empty the pos and fill in the new animated pos
		pos.animate("vector")

		width.update_frame_window(window)
		width.animate("real")

		split_r.update_frame_window(window)
		split_r.animate_without_path("bool")

		split_a.update_frame_window(window)
		split_a.animate_without_path("bool")

		animate_tangents(t1, window)
		animate_tangents(t2, window)


	outer_width = layer.get_param("width")
	sharp_cusps = layer.get_param("sharp_cusps")
	expand = layer.get_param("expand")
	r_tip0 = layer.get_param("round_tip[0]")
	r_tip1 = layer.get_param("round_tip[1]")
	homo_width = layer.get_param("homogeneous_width")
	origin = layer.get_param("origin")

	# Animating the origin
	origin.update_frame_window(window)
	origin.animate("vector")

	# Animating the outer width
	outer_width.update_frame_window(window)
	outer_width.animate("real")

	# Animating the sharp_cusps
	sharp_cusps.update_frame_window(window)
	sharp_cusps.animate_without_path("bool")

	# Animating the expand param
	expand.update_frame_window(window)
	expand.animate("real")

	# Animating the round tip 0
	r_tip0.update_frame_window(window)
	r_tip0.animate_without_path("bool")

	# Animating the round tip 1
	r_tip1.update_frame_window(window)
	r_tip1.animate_without_path("bool")

	# Animating the homogeneous width
	homo_width.update_frame_window(window)
	homo_width.animate_without_path("bool")
	# Minimizing the window size
	if window["first"] == sys.maxsize and window["last"] == -1:
		window["first"] = window["last"] = 0
	
	frames = list(set(settings.WAYPOINTS_LIST))
	length = bline.get_len()

	flag = False
	if loop:
		flag = True

	for fr in frames:
		if fr!=1:
			st_val = insert_dict_at(lottie["it"][0]["ks"]["k"], -1, fr, flag,True)
			cur_origin = origin.get_value(fr)
			for point in range(0,length):
				pos_ret, width, t1, t2, split_r_val, split_a_val = get_outline_param_at_frame(bline[point],fr)
				cubic_to(pos_ret,t1,t2,st_val,cur_origin,False,True)
Exemple #21
0
def gen_helpers_transform(lottie, pos=settings.DEFAULT_POSITION, anchor=settings.DEFAULT_ANCHOR, scale=settings.DEFAULT_SCALE, rotation=settings.DEFAULT_ROTATION, opacity=settings.DEFAULT_OPACITY, skew=settings.DEFAULT_SKEW):
    """
    Generates the dictionary corresponding to helpers/transform.json

    Args:
        lottie (dict)                : Lottie 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
    lottie["sk"] = {}   # skew of the layer
    lottie["sa"] = {}   # skew axis 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:
        pos.fill_path(lottie, "p")

    # setting the opacity
    if isinstance(opacity, (float, int)):
        gen_properties_value(lottie["o"],
                             opacity,
                             index.inc(),
                             settings.DEFAULT_ANIMATED,
                             settings.NO_INFO)
    else:
        opacity.fill_path(lottie, "o")

    # setting the rotation
    if isinstance(rotation, (float, int)):
        gen_properties_value(lottie["r"],
                             rotation,
                             index.inc(),
                             settings.DEFAULT_ANIMATED,
                             settings.NO_INFO)
    else:
        rotation.fill_path(lottie, "r")

    # setting the anchor point
    if isinstance(anchor, list):
        gen_properties_value(lottie["a"],
                             anchor,
                             index.inc(),
                             settings.DEFAULT_ANIMATED,
                             settings.NO_INFO)
    else:
        anchor.fill_path(lottie, "a")

    # 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:
        scale.fill_path(lottie, "s")

    # setting the skew angle
    if isinstance(skew, (float, int)):
        gen_properties_value(lottie["sk"],
                             skew,
                             index.inc(),
                             settings.DEFAULT_ANIMATED,
                             settings.NO_INFO)
    else:
        skew.fill_path(lottie, "sk")

    # setting the skew axis
    gen_properties_value(lottie["sa"],
                         0,
                         index.inc(),
                         settings.DEFAULT_ANIMATED,
                         settings.NO_INFO)
Exemple #22
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 == 2:
        regular_polygon["prop"] = "changing"
        regular_polygon["animated"] = rp[0]
    elif is_animate == 1:
        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 == 2:
        # 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 == 0:
            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 == 2:
        gen_value_Keyframed(lottie["r"], angle[0], index.inc())
    else:
        theta = 0  # default angle for the star
        if is_animate == 0:
            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 == 2:
        gen_value_Keyframed(lottie["or"], radius1[0], index.inc())
    else:
        r_outer = 0  # default value for outer radius
        if is_animate == 0:
            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 == 2:
        gen_value_Keyframed(lottie["ir"], radius2[0], index.inc())
    else:
        r_inner = 0  # default value for inner radius
        if is_animate == 0:
            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 == 2:
        gen_properties_multi_dimensional_keyframed(lottie["p"], origin[0],
                                                   index.inc())
    else:
        x_val, y_val = 0, 0
        if is_animate == 0:
            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
Exemple #23
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)
Exemple #24
0
def gen_layer_group(lottie, layer, idx):
    """
    Will generate a pre composition but has small differences than pre-comp layer used in
    layers/preComp.py
    This function will be used for group layer as well as switch group layer

    Args:
        lottie (dict)               : Lottie format layer will be stored here
        layer (lxml.etree._Element) : Synfig format group/switch layer
        idx   (int)                 : Index of the layer

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

    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "canvas":
                canvas = chld
            elif chld.attrib["name"] == "transformation":
                transform = chld[0]
                for child in transform:
                    if child.tag == "scale":
                        scale = child
                    elif child.tag == "offset":
                        pos = child
                    elif child.tag == "angle":
                        angle = child
            elif chld.attrib["name"] == "origin":
                origin = chld
            elif chld.attrib["name"] == "amount":
                opacity = chld
            elif chld.attrib["name"] == "outline_grow":
                outline_grow = chld
            elif chld.attrib["name"] == "time_offset":
                time_offset = chld
            elif chld.attrib["name"] == "time_dilation":
                time_dilation = chld

    outline_grow = gen_dummy_waypoint(outline_grow, "param", "real")
    append_path(outline_grow[0], outline_grow, "outline_grow_path")

    origin = gen_dummy_waypoint(origin, "param", "vector")
    anchor = origin
    group.update_pos(anchor)

    angle = gen_dummy_waypoint(angle, "angle", "rotate_layer_angle")

    pos = gen_dummy_waypoint(pos, "offset", "vector")
    if settings.INSIDE_PRECOMP:
        group.update_pos(pos)

    scale = gen_dummy_waypoint(scale, "scale", "group_layer_scale")
    # Generate the transform properties here
    gen_helpers_transform(lottie["ks"], layer, pos[0], anchor[0], scale[0],
                          angle[0], opacity[0])

    # Store previous states, to be recovered at the end of group layer
    prev_state = settings.INSIDE_PRECOMP

    settings.OUTLINE_GROW.append(outline_grow)
    settings.INSIDE_PRECOMP = True

    settings.lottie_format["assets"].append({})
    asset = add_precomp_asset(settings.lottie_format["assets"][-1], canvas[0],
                              len(canvas[0]))
    lottie["refId"] = asset

    lottie["w"] = settings.lottie_format[
        "w"] + settings.ADDITIONAL_PRECOMP_WIDTH  # Experimental increase in width and height of precomposition
    lottie[
        "h"] = settings.lottie_format["h"] + settings.ADDITIONAL_PRECOMP_HEIGHT
    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)

    # Time offset and speed
    lottie["tm"] = {}
    gen_time_remap(lottie["tm"], time_offset, time_dilation, index.inc())

    # Change opacity of layers for switch-group layers
    if layer.attrib["type"] == "switch":
        change_opacity_switch(layer, lottie)
    # Change opacity of layers for group layers
    elif layer.attrib["type"] == "group":
        change_opacity_group(layer, lottie)

    # Return to previous state, when we go outside the group layer
    settings.INSIDE_PRECOMP = prev_state
    settings.OUTLINE_GROW.pop()
Exemple #25
0
def gen_layer_shape_solid(lottie, layer, idx):
    """
    Generates the dictionary corresponding to layers/shapes.json

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

    Returns:
        (None)
    """
    update_layer(layer)

    # Setting the solid layer which will be masked
    index = Count()
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_SOLID_TYPE
    set_layer_desc(layer, settings.LAYER_SOLID_NAME + str(idx), lottie)
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled
    lottie["ef"] = []  # Stores the effects

    pos = [
        settings.lottie_format["w"] / 2 + get_additional_width() / 2,
        settings.lottie_format["h"] / 2 + get_additional_height() / 2
    ]
    anchor = pos
    gen_helpers_transform(lottie["ks"], layer, pos, anchor)

    lottie["ef"].append({})
    gen_effects_fill(lottie["ef"][-1], layer, index.inc())

    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT
    lottie["sw"] = settings.lottie_format["w"] + get_additional_width(
    )  # Solid Width
    lottie["sh"] = settings.lottie_format["h"] + get_additional_height(
    )  # Solid Height

    invert = False
    for chld in layer:
        if chld.tag == "param":
            if chld.attrib["name"] == "color":
                lottie["sc"] = get_color_hex(chld[0])  # Solid Color
            elif chld.attrib["name"] == "invert":
                is_animate = is_animated(chld[0])
                if is_animate == 0:
                    val = chld[0].attrib["value"]
                elif is_animate == 1:
                    val = chld[0][0][0].attrib["value"]
                else:
                    # If animated, always set invert to false
                    val = "false"
                if val == "true":
                    invert = True
            elif chld.attrib["name"] in {"bline", "vector_list"}:
                bline_point = chld[0]

    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)

    hasMask = True

    lottie["hasMask"] = hasMask
    lottie["masksProperties"] = []
    lottie["masksProperties"].append({})

    if layer.attrib["type"] in {
            "star", "circle", "rectangle", "filled_rectangle"
    }:
        bline_point = layer

    gen_mask(lottie["masksProperties"][0], invert, bline_point, index.inc())
Exemple #26
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 = {}
    bevel_found = False
    expand_found = False  # For filled rectangle layers

    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_found = True
                param_expand = child

            elif child.attrib["name"] == "bevel":
                bevel_found = True
                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)
    if not bevel_found:  # For rectangle layer in stable version 1.2.2
        bevel = 0
        gen_properties_value(lottie["r"], bevel, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

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

    # If expand parameter is not animated
    param_expand = gen_dummy_waypoint(param_expand, "param", "real")

    # expand parameter needs to be positive: required by Synfig
    make_positive_valued(param_expand)

    # If p1 not animated
    points["1"] = gen_dummy_waypoint(points["1"], "param", "vector")

    # If p2 not animated
    points["2"] = gen_dummy_waypoint(points["2"], "param", "vector")

    both_points_animated(points["1"], points["2"], param_expand, lottie, index)
Exemple #27
0
def gen_radial_gradient(lottie, layer, idx):
    """
    Generates the dictionary correspnding to shapes/gFill.json but with radial gradient

    Args:
    """
    index = Count()
    lottie["ty"] = "gf"
    lottie["r"] = 1  # Don't know it's meaning yet, but works without this also
    lottie["o"] = {}  # Opacity of the gradient layer
    lottie["nm"] = layer.get_description()
    lottie["t"] = 2  # 2 means radial gradient layer
    lottie["s"] = {}  # Starting point of gradient
    lottie["e"] = {}  # Ending point of gradient
    lottie["g"] = {}  # Gradient information is stored here

    # Color Opacity
    opacity = layer.get_param("amount").get()
    is_animate = is_animated(opacity[0])
    if is_animate == settings.ANIMATED:
        # Telling the function that this is for opacity
        opacity[0].attrib['type'] = 'opacity'
        gen_value_Keyframed(lottie["o"], opacity[0], index.inc())

    else:
        if is_animate == settings.NOT_ANIMATED:
            val = float(opacity[0].attrib["value"]) * settings.OPACITY_CONSTANT
        else:
            val = float(
                opacity[0][0][0].attrib["value"]) * settings.OPACITY_CONSTANT
        gen_properties_value(lottie["o"], val, index.inc(),
                             settings.DEFAULT_ANIMATED, settings.NO_INFO)

        # Gradient colors
        lottie["g"]["k"] = {}
        lottie["g"]["ix"] = index.inc()
        gradient = layer.get_param("gradient")
        modify_gradient(gradient)
        gradient.animate(
            "gradient")  # To find the lottie path of the modified gradient
        lottie["g"]["p"] = len(gradient.get()[0][0][0])
        gradient.fill_path(lottie["g"], "k")
        modify_gradient_according_to_latest_version(lottie["g"]["k"])

        # Starting point and Ending points need to be retrieved from center and radius
        center = layer.get_param("center")
        center.animate("vector")
        center.fill_path(lottie, "s")

        radius = layer.get_param("radius")
        radius.animate("real")

        # Ending point will be (start[0] + radius, start[1])
        # Below is just a modification of fill_path function
        expression = "var $bm_rt; $bm_rt = {expr}"
        x_expr = "sum(" + center.expression + "[0], " + radius.expression + ")"
        y_expr = center.expression + "[1]"
        expr = "[" + x_expr + ", " + y_expr + "]"
        expression = expression.format(expr=expr)
        gen_properties_value(lottie["e"], [1, 1], 0, 0, expression)
        if "ef" not in center.get_layer().get_lottie_layer().keys():
            center.get_layer().get_lottie_layer()["ef"] = []
        # If center has any expression controllers, then they would have been pushed earlier by fill_path, hence no need
        # center.get_layer().get_lottie_layer()["ef"].extend(center.expression_controllers)
        center.get_layer().get_lottie_layer()["ef"].extend(
            radius.expression_controllers)
Exemple #28
0
def gen_layer_shape_solid(lottie, layer, idx):
    """
    Generates the dictionary corresponding to layers/shapes.json

    Args:
        lottie (dict)       : Lottie generated solid layer stored here
        layer  (common.Layer.Layer) : Synfig format solid layer
        idx    (int)        : Stores the index(number of) of solid layer

    Returns:
        (None)
    """
    layer.add_offset()

    # Setting the solid layer which will be masked
    index = Count()
    lottie["ddd"] = settings.DEFAULT_3D
    lottie["ind"] = idx
    lottie["ty"] = settings.LAYER_SOLID_TYPE
    lottie["nm"] = layer.get_description()
    lottie["sr"] = settings.LAYER_DEFAULT_STRETCH
    lottie["ks"] = {}  # Transform properties to be filled
    lottie["ef"] = []  # Stores the effects

    pos = [
        settings.lottie_format["w"] / 2 + get_additional_width() / 2,
        settings.lottie_format["h"] / 2 + get_additional_height() / 2
    ]
    anchor = pos
    gen_helpers_transform(lottie["ks"], pos, anchor)

    lottie["ef"].append({})
    gen_effects_fill(lottie["ef"][-1], layer, index.inc())

    lottie["ao"] = settings.LAYER_DEFAULT_AUTO_ORIENT
    lottie["sw"] = settings.lottie_format["w"] + get_additional_width(
    )  # Solid Width
    lottie["sh"] = settings.lottie_format["h"] + get_additional_height(
    )  # Solid Height

    lottie["sc"] = get_color_hex(layer.get_param("color").get()[0])

    invert = False
    Inv = layer.get_param("invert").get()
    flag = False
    #So far only 'not' convert method seems to be supported for invert param in circle, will add more subsequently.
    if Inv is not None:
        if "bool" not in str(Inv[0]) and "animated" not in str(Inv[0]):
            is_animate = is_animated(Inv[0][0][0])
            flag = True
        else:
            is_animate = is_animated(Inv[0])
        if is_animate == settings.NOT_ANIMATED:
            if flag:
                val = "false"
                if Inv[0][0][0].attrib["value"] == "false":
                    val = "true"
            else:
                val = Inv[0].attrib["value"]
        elif is_animate == settings.SINGLE_WAYPOINT:
            if flag:
                val = "false"
                if Inv[0][0][0][0][0].attrib["value"] == "false":
                    val = "true"
            else:
                val = Inv[0][0][0].attrib["value"]
        else:
            # If animated, always set invert to false
            val = "false"
        if val == "true":
            invert = True

    lottie["ip"] = settings.lottie_format["ip"]
    lottie["op"] = settings.lottie_format["op"]
    lottie["st"] = 0  # Don't know yet
    get_blend(lottie, layer)

    hasMask = True

    lottie["hasMask"] = hasMask
    lottie["masksProperties"] = []
    lottie["masksProperties"].append({})

    if layer.get_type() in {"star", "circle", "rectangle", "filled_rectangle"}:
        bline_point = layer
    else:
        bline_point = layer.get_param("bline", "vector_list")

    gen_mask(lottie["masksProperties"][0], invert, bline_point, index.inc())
Exemple #29
0
def gen_layer_group(lottie, layer, idx):
    """
    Will generate a pre composition but has small differences than pre-comp layer used in
    layers/preComp.py
    This function will be used for group layer as well as switch group layer

    Args:
        lottie (dict)               : Lottie format layer will be stored here
        layer (common.Layer.Layer) : Synfig format group/switch layer
        idx   (int)                 : Index of the layer

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

    # Extract parameters
    canvas = Canvas(layer.get_param("canvas"))
    origin = layer.get_param("origin")
    opacity = layer.get_param("amount")
    outline_grow = layer.get_param("outline_grow")
    time_offset = layer.get_param("time_offset")
    time_dilation = layer.get_param("time_dilation")
    transformation = layer.get_param("transformation")
    transform = transformation[0]
    try_par = Param(transform, Param(transformation.get(), layer))
    for child in transform:
        if child.tag == "scale":
            scale = Param(child, try_par)
        elif child.tag == "offset":
            pos = Param(child, try_par)
        elif child.tag == "angle":
            angle = Param(child, try_par)
        elif child.tag == "skew_angle":
            skew = Param(child, try_par)

    outline_grow.animate("real")

    origin.animate("vector")
    anchor = origin
    anchor.add_offset()

    angle.animate("rotate_layer_angle")

    pos.animate("vector")
    if settings.INSIDE_PRECOMP:
        pos.add_offset()

    scale.animate("group_layer_scale")
    # Generating animation for skew
    skew.animate("rotate_layer_angle")
    # Animating opacity
    opacity.animate("opacity")

    # Reset the animations after adding offset
    anchor.animate("vector", True)
    pos.animate("vector", True)
    # Generate the transform properties here
    gen_helpers_transform(lottie["ks"], pos, anchor, scale, angle, opacity,
                          skew)

    # Store previous states, to be recovered at the end of group layer
    prev_state = settings.INSIDE_PRECOMP
    settings.OUTLINE_GROW.append(
        outline_grow
    )  # Storing the outline grow in settings, will be used inside child outlines

    settings.INSIDE_PRECOMP = True

    settings.lottie_format["assets"].append({})
    asset = add_precomp_asset(settings.lottie_format["assets"][-1], canvas,
                              canvas.get_num_layers())
    lottie["refId"] = asset

    lottie["w"] = settings.lottie_format[
        "w"] + settings.ADDITIONAL_PRECOMP_WIDTH  # Experimental increase in width and height of precomposition
    lottie[
        "h"] = settings.lottie_format["h"] + settings.ADDITIONAL_PRECOMP_HEIGHT
    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)

    # Time offset and speed
    lottie["tm"] = {}
    gen_time_remap(lottie["tm"], time_offset, time_dilation, index.inc())

    # Change opacity of layers for switch-group layers
    if layer.get_type() == "switch":
        change_opacity_switch(layer, lottie)
    # Change opacity of layers for group layers
    elif layer.get_type() == "group":
        change_opacity_group(layer, lottie)

    # Return to previous state, when we go outside the group layer
    settings.INSIDE_PRECOMP = prev_state
    settings.OUTLINE_GROW.pop()