diff --git a/animation.py b/animation.py index 750b20d..30e92fc 100644 --- a/animation.py +++ b/animation.py @@ -1,5 +1,7 @@ +import random import colorsys from time import time +from typing import Tuple class Animation: @@ -41,6 +43,135 @@ class Steady(Animation): def name(self): return "steady" +class RandomSingle(Animation): + """ + by Max & Lightmoll (https://lght.ml) + from 2022-06-08 + """ + def __init__(self, color): + super().__init__() + self.PERIOD = 4 * 30 #frames + self.color = self._rand_color() + self.last_colors = [] + self.frame_counter = 0 + + + def update(self, index:int, count:int) -> Tuple[int, int, int]: + if index == 0: + if ((self.frame_counter % self.PERIOD) == 0): + self.last_colors = [] + for _ in range(count): + self.last_colors.append(self._rand_color()) + self.frame_counter += 1 + try: + return self.last_colors[index] + except IndexError: + print("INDEX ERROR: ", index, len(self.last_colors)) + raise Exception(f"{index}, {len(self.last_colors)}") + + + def _rand_color(self): + return ( + round(random.random() * 255), + round(random.random() * 255), + round(random.random() * 255) + ) + + + def __str__(self): + return "randomsingle" + + + def name(self): + return str(self) + + + +class TwoColor(Steady): + """ + by Max & Lightmoll (https://lght.ml) + from 2022-06-08 + """ + def __init__(self, color): + super().__init__(color) + self.start_time = time() + self.PERIOD = 0.5 #s + self.COL_1 = color #input color + + self.COL_2 = (255-self.r, 255-self.g, 255-self.b) #compl. color + + #of lights + def update(self, index:int, count:int) -> Tuple[int, int, int]: + time_diff = time() - self.start_time + #r,g,b + color = (0,0,0) + + if (self.PERIOD / 2 > (time_diff % self.PERIOD)): + color = self.COL_1 + else: + color = self.COL_2 + return color + + + def __str__(self): + return "twocolor" + + + def name(self): + return str(self) + +class Caramelldansen(Steady): + """ + by Max & Lightmoll (https://lght.ml) + from 2022-06-08 + """ + def __init__(self, color): + super().__init__(color) + self.start_time = time() + self.PERIOD = int(0.42 * 30) #frames + self.COLORS = [ + (230,50,50), + (255,0,0), + (50,230,50), + (0,255,0), + (50,50,230), + (0,0,255) + ] + """ + self.COLORS = [ + (255,0,0), + (0,255,0), + (0,0,255) + ] + """ + self.color_index = 0 + self.frame_counter = 0 + + + def update(self, index:int, count:int) -> Tuple[int, int, int]: + time_diff = round(time() - self.start_time) + #r,g,b + if index == 0: + self.frame_counter += 1 + + if (((self.frame_counter % self.PERIOD) == 0) and index == 0): + self.color_index += 1 + + if (self.color_index == len(self.COLORS)): + #self.frame_counter = 0 #prevent big numbers + self.color_index = 0 + + return self.COLORS[self.color_index] + + + def __str__(self): + # when is this endpoint called? + return "caramelldansen" + + + def name(self): + return str(self) + class FadeTo(Steady): def __init__(self, color, t=2.0): @@ -102,6 +233,27 @@ class Chase(Steady): return "chase" +class ChaseRandom(Animation): + def __init__(self, color, looptime=1.0): + super(Chase, self).__init__(color) + self.looptime = looptime + + def update(self, index, count): + angle = (time() / self.looptime + (index + 0.0) / count) % 1.0 + l = 1 - min(abs(angle - 1 / count) * .9, 1.0 / count) * count + # print(f"f({index}, {angle:.2f}) -> {l:.2f}") + return (int(self.r * l), int(self.g * l), int(self.b * l)) + + def __str__(self): + return f"{type(self).__name__}({self.r}, {self.g}, {self.b}, {self.looptime:.2f})" + + def name(self): + return "chase" + + def hsv_to_rgb(h, s, v): (r, g, b) = colorsys.hsv_to_rgb(h, s, v) - return [int(r * 255), int(g * 255), int(b * 255)] \ No newline at end of file + return [int(r * 255), int(g * 255), int(b * 255)] + +def rgb_to_hsv(r, g, b): + return colorsys.rgb_to_hsv(r/255,g/255,b/255) \ No newline at end of file diff --git a/dmx.py b/dmx.py index 64c5a1b..cc954de 100644 --- a/dmx.py +++ b/dmx.py @@ -5,7 +5,7 @@ from threading import Thread from time import sleep from typing import Union -from animation import Animation, Off, Steady, FadeTo, RotatingRainbow, Chase +from animation import Animation, Off, RandomSingle, Steady, FadeTo, RotatingRainbow, Chase, TwoColor, Caramelldansen def ledlog(value): @@ -125,6 +125,12 @@ class DMX: animation = RotatingRainbow() elif animation == "steady": animation = Steady(self._color) + elif animation == "twocolor": + animation = TwoColor(self._color) + elif animation == "caramelldansen": + animation = Caramelldansen(self._color) + elif animation == "randomsingle": + animation = RandomSingle(self._color) else: raise ValueError(f"No such animation {animation}") self._animation = animation diff --git a/static/main.css b/static/main.css index 1489660..be452d9 100644 --- a/static/main.css +++ b/static/main.css @@ -1,8 +1,23 @@ -body { - background: black; - color: white; +:root { + --bg-color: #403F3C; + --primary-color: #ccc; } +html { + background: var(--bg-color); +} + + +body { + padding-top: 20px; + width: 80%; + height: 100%; + color: var(--primary-color); + margin: auto; + font-family: "monospace"; +} + + .controls { display: flex; width: 40em; @@ -10,14 +25,21 @@ body { fieldset { flex: auto; + margin-right: 5px; } .buttons { width: 30em; + } input.button_color { width: 6em; + margin: 4px; + border: none; + padding: 5px 10px; + /* border-radius: 5px; */ + } .button_color_white { diff --git a/views/index.tpl b/views/index.tpl index 93ea8da..bb64fbb 100644 --- a/views/index.tpl +++ b/views/index.tpl @@ -25,6 +25,17 @@ +