From 79febec2722b8bb6600e3ef6c4f1d5291d3bf12a Mon Sep 17 00:00:00 2001 From: Konstantin Dmitriev Date: Nov 27 2019 07:28:59 +0000 Subject: Merge PR #1018: Lottie export - Add support for Exponent Convert method and Stretch Layer --- diff --git a/synfig-studio/plugins/lottie-exporter/canvas.py b/synfig-studio/plugins/lottie-exporter/canvas.py index 049ca8a..30e3e96 100644 --- a/synfig-studio/plugins/lottie-exporter/canvas.py +++ b/synfig-studio/plugins/lottie-exporter/canvas.py @@ -65,8 +65,8 @@ def gen_canvas(lottie, root): else: lottie["h"] = settings.DEFAULT_HEIGHT - settings.ADDITIONAL_PRECOMP_WIDTH = 3*lottie["w"] - settings.ADDITIONAL_PRECOMP_HEIGHT = 3*lottie["h"] + settings.ADDITIONAL_PRECOMP_WIDTH = 4*lottie["w"] + settings.ADDITIONAL_PRECOMP_HEIGHT = 4*lottie["h"] name = settings.DEFAULT_NAME for child in root: diff --git a/synfig-studio/plugins/lottie-exporter/common/Param.py b/synfig-studio/plugins/lottie-exporter/common/Param.py index 692bdc2..cfda9ae 100644 --- a/synfig-studio/plugins/lottie-exporter/common/Param.py +++ b/synfig-studio/plugins/lottie-exporter/common/Param.py @@ -172,7 +172,7 @@ class Param: If this parameter is not animated, it generates dummy waypoints and animates this parameter """ - if anim_type == "vector": # This will never happen, can remove this latter + if anim_type in {"vector", "group_layer_scale", "stretch_layer_scale"}: # This will never happen, can remove this latter self.dimension = 2 # Check if we are dealing with convert methods @@ -206,7 +206,7 @@ class Param: """ Internal private method for animating """ - if anim_type == "vector": + if anim_type in {"vector", "group_layer_scale", "stretch_layer_scale"}: self.dimension = 2 # Check if we are dealing with convert methods @@ -298,6 +298,17 @@ class Param: self.expression = ret return ret, self.expression_controllers # Might have to return copy.deepcopy because these expressions are destroyed on animating this parameter again, and this param might be child to 2 params + elif self.param[0].tag == "exp": + self.subparams["exp"].extract_subparams() + exp, effects_1 = self.subparams["exp"].subparams["exp"].recur_animate("scalar_multiply") + scale, effects_2 = self.subparams["exp"].subparams["scale"].recur_animate(anim_type) + self.expression_controllers.extend(effects_1) + self.expression_controllers.extend(effects_2) + ret = "mul(Math.exp({exp}), {scale})" + ret = ret.format(exp=exp, scale=scale) + self.expression = ret + return ret, self.expression_controllers + elif self.param[0].tag == "average": self.subparams["average"].extract_subparams() # Entries will be extracted here lst = self.subparams["average"].subparams["entry"] @@ -639,6 +650,11 @@ class Param: ret += ret2 ret *= mul + elif self.param[0].tag == "exp": + exp = self.subparams["exp"].subparams["exp"].__get_value(frame) + scale = self.subparams["exp"].subparams["scale"].__get_value(frame) + ret = scale * math.exp(exp) + elif self.param[0].tag == "average": lst = self.subparams["average"].subparams["entry"] if not isinstance(lst, list): @@ -843,6 +859,11 @@ class Param: for it in self.subparams["average"]: it.update_frame_window(window) + elif node.tag == "exp": + self.subparams["exp"].extract_subparams() + self.subparams["exp"].subparams["exp"].update_frame_window(window) + self.subparams["exp"].subparams["scale"].update_frame_window(window) + elif node.tag == "weighted_average": self.subparams["weighted_average"].extract_subparams() for it in self.subparams["weighted_average"].subparams["entry"]: diff --git a/synfig-studio/plugins/lottie-exporter/common/Vector.py b/synfig-studio/plugins/lottie-exporter/common/Vector.py index 499fffa..efd5a95 100644 --- a/synfig-studio/plugins/lottie-exporter/common/Vector.py +++ b/synfig-studio/plugins/lottie-exporter/common/Vector.py @@ -181,7 +181,7 @@ class Vector: ret = [self.val1, self.val2] elif self.type == "circle_radius": ret = [self.val1, self.val1] - elif self.type in {"rectangle_size", "image_scale", "scale_layer_zoom", "group_layer_scale"}: + elif self.type in {"rectangle_size", "image_scale", "scale_layer_zoom", "group_layer_scale", "stretch_layer_scale"}: ret = [self.val1, self.val3] else: ret = [self.val1] diff --git a/synfig-studio/plugins/lottie-exporter/common/misc.py b/synfig-studio/plugins/lottie-exporter/common/misc.py index a9b9cb7..8433809 100644 --- a/synfig-studio/plugins/lottie-exporter/common/misc.py +++ b/synfig-studio/plugins/lottie-exporter/common/misc.py @@ -145,6 +145,13 @@ def parse_position(animated, i): vec.add_new_val(val) return vec + elif animated.attrib["type"] == "stretch_layer_scale": + val1 = float(animated[i][0][0].text) * 100 + val3 = float(animated[i][0][1].text) * 100 + vec = Vector(val1, get_frame(animated[i]), animated.attrib["type"]) + vec.add_new_val(val3) + return vec + elif animated.attrib["type"] == "group_layer_scale": val1 = float(animated[i][0][0].text) * 100 val3 = float(animated[i][0][1].text) * 100 diff --git a/synfig-studio/plugins/lottie-exporter/effects/controller.py b/synfig-studio/plugins/lottie-exporter/effects/controller.py index 12b001d..2119711 100644 --- a/synfig-studio/plugins/lottie-exporter/effects/controller.py +++ b/synfig-studio/plugins/lottie-exporter/effects/controller.py @@ -23,7 +23,7 @@ def gen_effects_controller(lottie, value, anim_type): lottie["ef"] = [] lottie["ef"].append({}) - if anim_type == "vector": + if anim_type in {"vector", "group_layer_scale", "stretch_layer_scale"}: gen_effects_point(lottie["ef"][-1], value, idx) else: gen_effects_slider(lottie["ef"][-1], value, idx) diff --git a/synfig-studio/plugins/lottie-exporter/layers/preComp.py b/synfig-studio/plugins/lottie-exporter/layers/preComp.py index 8853668..3c0383d 100644 --- a/synfig-studio/plugins/lottie-exporter/layers/preComp.py +++ b/synfig-studio/plugins/lottie-exporter/layers/preComp.py @@ -39,11 +39,14 @@ def gen_layer_precomp(lottie, layer, idx): gen_layer_rotate(lottie["ks"], layer) settings.INSIDE_PRECOMP = True elif layer.get_type() == "zoom": - gen_layer_scale(lottie["ks"], layer) + gen_layer_scale(lottie["ks"], layer, "scale_layer") settings.INSIDE_PRECOMP = True elif layer.get_type() == "translate": gen_layer_translate(lottie["ks"], layer) settings.INSIDE_PRECOMP = True + elif layer.get_type() == "stretch": + gen_layer_scale(lottie["ks"], layer, "stretch_layer") + settings.INSIDE_PRECOMP = True settings.lottie_format["assets"].append({}) asset = add_precomp_asset(settings.lottie_format["assets"][-1], layer.getparent(), idx) diff --git a/synfig-studio/plugins/lottie-exporter/layers/scale_layer.py b/synfig-studio/plugins/lottie-exporter/layers/scale_layer.py index 3a2efab..8929235 100644 --- a/synfig-studio/plugins/lottie-exporter/layers/scale_layer.py +++ b/synfig-studio/plugins/lottie-exporter/layers/scale_layer.py @@ -9,7 +9,7 @@ from helpers.transform import gen_helpers_transform sys.path.append("..") -def gen_layer_scale(lottie, layer): +def gen_layer_scale(lottie, layer, layer_name="scale_layer"): """ Help generate transform properties of a scale layer @@ -20,6 +20,10 @@ def gen_layer_scale(lottie, layer): Returns: (None) """ + animation_type = "scale_layer_zoom" + if layer_name == "stretch_layer": + animation_type = "stretch_layer_scale" + center = layer.get_param("center") center.animate("vector") anchor = copy.deepcopy(center) @@ -28,7 +32,7 @@ def gen_layer_scale(lottie, layer): pos = center scale = layer.get_param("amount") # This is scale amount - scale.animate("scale_layer_zoom") + scale.animate(animation_type) anchor.add_offset() if settings.INSIDE_PRECOMP: diff --git a/synfig-studio/plugins/lottie-exporter/settings.py b/synfig-studio/plugins/lottie-exporter/settings.py index 64d476a..ca55687 100644 --- a/synfig-studio/plugins/lottie-exporter/settings.py +++ b/synfig-studio/plugins/lottie-exporter/settings.py @@ -65,11 +65,11 @@ SHAPE_LAYER = {"simple_circle"} SOLID_LAYER = {"SolidColor"} SHAPE_SOLID_LAYER = {"region", "polygon", "outline", "circle", "rectangle", "filled_rectangle", "star"} IMAGE_LAYER = {"import"} -PRE_COMP_LAYER = {"rotate", "zoom", "translate"} +PRE_COMP_LAYER = {"rotate", "zoom", "translate", "stretch"} GROUP_LAYER = {"group", "switch"} SKELETON_LAYER = {"skeleton"} UNKNOWN_LAYER = "unknown_layer" -CONVERT_METHODS = {"add", "average", "composite", "linear", "radial_composite", "scale", "subtract", "switch", "weighted_average", "bone_link", "bone", "bone_root"} +CONVERT_METHODS = {"add", "average", "composite", "exp", "linear", "radial_composite", "scale", "subtract", "switch", "weighted_average", "bone_link", "bone", "bone_root"} BONES = {"bone", "bone_root"}