File indexing completed on 2025-02-02 04:10:05

0001 # SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0002 # SPDX-License-Identifier: GPL-3.0-or-later
0003 import glaxnimate
0004 
0005 
0006 class HueShiftVisitor(glaxnimate.model.Visitor):
0007     def __init__(self, amount, times, easing):
0008         super().__init__()
0009         self.amount = amount
0010         self.gradients = set()
0011         self.named_colors = set()
0012         self.times = times
0013         self.easing = easing
0014 
0015     def _color(self, color, amount):
0016         return glaxnimate.utils.Color.from_hsv(
0017             (color.hue + amount) % 360,
0018             color.saturation,
0019             color.value,
0020             color.alpha
0021         )
0022 
0023     def _prop_color(self, value, amount):
0024         if isinstance(value, list):
0025             return [
0026                 (offset, self._color(color, amount))
0027                 for offset, color in value
0028             ]
0029         return self._color(value, amount)
0030 
0031     def set_time(self, time):
0032         self.gradients = set()
0033         self.named_colors = set()
0034         self.time = time
0035 
0036     def _set_value(self, prop):
0037         value = prop.value
0038         if not self.times:
0039             prop.value = self._prop_color(value, self.amount)
0040         else:
0041             amount = 0
0042             for time in self.times:
0043                 kf = prop.set_keyframe(time, self._prop_color(value, amount))
0044                 kft = kf.transition
0045                 kft.before_descriptive = self.easing
0046                 kft.after_descriptive = self.easing
0047                 kf.transition = kft
0048                 amount += self.amount
0049 
0050     def on_visit_node(self, node):
0051         if isinstance(node, glaxnimate.model.shapes.Styler):
0052             self._set_value(node.color)
0053             if node.use:
0054                 if isinstance(node.use, glaxnimate.model.assets.NamedColor):
0055                     if node.use not in self.named_colors:
0056                         self._set_value(node.use.color)
0057                         self.named_colors.add(node.use)
0058                 elif isinstance(node.use, glaxnimate.model.assets.Gradient) and node.use.colors:
0059                     if node.use.colors not in self.gradients:
0060                         self._set_value(node.use.colors.colors)
0061                         self.gradients.add(node.use.colors)
0062 
0063 
0064 def hue_shift(window, document, settings):
0065     with document.macro("Hue Shift"):
0066         visitor = HueShiftVisitor(settings["amount"], None, None)
0067         for shape in window.cleaned_selection:
0068             visitor.visit(shape, True)
0069 
0070 
0071 def hue_shift_cycle(window, document, settings):
0072     with document.macro("Hue Shift Cycle"):
0073         easing_str = settings["easing"]
0074         easing = glaxnimate.model.KeyframeTransition.Descriptive.Linear
0075         if easing_str == "Ease":
0076             easing = glaxnimate.model.KeyframeTransition.Descriptive.Ease
0077         elif easing_str == "Hold":
0078             easing = glaxnimate.model.KeyframeTransition.Descriptive.Hold
0079 
0080         amount = settings["amount"]
0081         duration = settings["duration"]
0082         times = [
0083             document.current_time + step * duration
0084             for step in range(settings["step_count"])
0085         ]
0086 
0087         visitor = HueShiftVisitor(amount, times, easing)
0088 
0089         for shape in window.cleaned_selection:
0090             visitor.visit(shape, True)
0091 
0092 
0093 
0094 
0095