summaryrefslogtreecommitdiffstats
path: root/share/extensions/interp_att_g.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xshare/extensions/interp_att_g.py197
1 files changed, 197 insertions, 0 deletions
diff --git a/share/extensions/interp_att_g.py b/share/extensions/interp_att_g.py
new file mode 100755
index 0000000..61b8d8b
--- /dev/null
+++ b/share/extensions/interp_att_g.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python
+# coding=utf-8
+#
+# Copyright (C) 2009 Aurelio A. Heckert, aurium (a) gmail dot com
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+"""
+Interpolation of attributes in selected objects or group's children.
+"""
+
+import inkex
+from inkex.localization import inkex_gettext as _
+from inkex.tween import ColorInterpolator, ValueInterpolator, AttributeInterpolator
+from inkex.utils import is_number
+
+
+class InterpAttG(inkex.EffectExtension):
+ """
+ This effect applies a value for any interpolatable attribute for all
+ elements inside the selected group or for all elements in a multiple selection.
+ """
+
+ def __init__(self):
+ super(InterpAttG, self).__init__()
+ self.arg_parser.add_argument(
+ "-a",
+ "--att",
+ type=str,
+ dest="att",
+ default="width",
+ help="Attribute to be interpolated.",
+ )
+ self.arg_parser.add_argument(
+ "-o",
+ "--att-other",
+ type=str,
+ dest="att_other",
+ help="Other attribute (for a limited UI).",
+ )
+ self.arg_parser.add_argument(
+ "-t",
+ "--att-other-type",
+ type=self.arg_class([ColorInterpolator, ValueInterpolator]),
+ dest="att_other_type",
+ help="The other attribute type.",
+ )
+ self.arg_parser.add_argument(
+ "-w",
+ "--att-other-where",
+ type=str,
+ dest="att_other_where",
+ default="tag",
+ help="That is a tag attribute or a style attribute?",
+ )
+ self.arg_parser.add_argument(
+ "-s",
+ "--start-val",
+ type=str,
+ dest="start_val",
+ default="#F00",
+ help="Initial interpolation value.",
+ )
+ self.arg_parser.add_argument(
+ "-e",
+ "--end-val",
+ type=str,
+ dest="end_val",
+ default="#00F",
+ help="End interpolation value.",
+ )
+ self.arg_parser.add_argument(
+ "-u", "--unit", type=str, dest="unit", default="none", help="Values unit."
+ )
+ self.arg_parser.add_argument(
+ "--zsort",
+ type=inkex.Boolean,
+ dest="zsort",
+ default=False,
+ help="use z-order instead of selection order",
+ )
+ self.arg_parser.add_argument(
+ "--tab",
+ type=str,
+ dest="tab",
+ help="The selected UI-tab when OK was pressed",
+ )
+
+ def get_elements(self):
+ """Returns a list of elements to work on"""
+ if not self.svg.selection:
+ return []
+
+ if len(self.svg.selection) > 1:
+ # multiple selection
+ if self.options.zsort:
+ return list(self.svg.selection.rendering_order().values())
+ return list(self.svg.selection.values())
+
+ # must be a group
+ node = self.svg.selection.filter(inkex.Group).first()
+ return list(node) or []
+
+ def create_dummy_nodes(self, path):
+ """Create dummy nodes to use the interpolation classes defined in inkex.tween"""
+ pat1 = inkex.PathElement()
+ pat2 = inkex.PathElement()
+
+ start_value = self.options.start_val.replace(",", ".")
+ end_value = self.options.end_val.replace(",", ".")
+ if self.options.unit != "none":
+ start_value += self.options.unit
+ end_value += self.options.unit
+ self.apply_value(pat1, path, start_value)
+ self.apply_value(pat2, path, end_value)
+ return pat1, pat2
+
+ @staticmethod
+ def apply_value(node, path, value):
+ """Applies a value to a given node. If path starts with "transform/" or "style/", the
+ value is applied to either transform or style."""
+ if path.startswith("style/"):
+ att_name = path[6:]
+ node.style[att_name] = value
+ elif path.startswith("transform/"):
+ if not is_number(value):
+ raise inkex.AbortExtension(
+ _("Unable to set attribute {} to {}").format(path, value)
+ )
+ if path == "transform/trans-x":
+ node.transform.add_translate(value, 0)
+ elif path == "transform/trans-y":
+ node.transform.add_translate(0, value)
+ elif path == "transform/scale":
+ node.transform.add_scale(value)
+ elif path == "transform":
+ node.transform @= value
+ else:
+ node.set(path, value)
+
+ def effect(self):
+ method = None
+ if self.options.att == "other":
+ if self.options.att_other is None:
+ raise inkex.AbortExtension(
+ _("You selected 'Other'. Please enter an attribute to interpolate.")
+ )
+ if self.options.att_other_where == "tag":
+ path = self.options.att_other
+ else:
+ path = self.options.att_other_where + "/" + self.options.att_other
+ method = self.options.att_other_type
+ else:
+ path = self.options.att
+ if self.options.att == "height" or self.options.att == "width":
+ method = inkex.tween.UnitValueInterpolator
+
+ path1, path2 = self.create_dummy_nodes(path)
+ if path.startswith("transform"):
+ path = "transform"
+ try:
+ # maybe tween knows what do do with this attribute?
+ interpolator = AttributeInterpolator.create_from_attribute(
+ path1, path2, path, None
+ )
+ except:
+ # okay, apparently not
+ interpolator = AttributeInterpolator.create_from_attribute(
+ path1, path2, path, method
+ )
+ collection = self.get_elements()
+ if not collection:
+ raise inkex.AbortExtension(_("There is no selection to interpolate"))
+
+ steps = [1.0 / (len(collection) - 1) * i for i in range(len(collection))]
+
+ for time, node in zip(steps, collection):
+ new_value = interpolator.interpolate(time)
+ InterpAttG.apply_value(node, path, new_value)
+
+ return True
+
+
+if __name__ == "__main__":
+ InterpAttG().run()