Extract blend_colors from sparkline, implement opacity

This commit is contained in:
Darren Burns
2022-02-08 17:50:09 +00:00
parent 06749bf7af
commit 95c73ecc1a
3 changed files with 89 additions and 25 deletions

View File

@@ -1,8 +1,17 @@
from time import sleep
from rich.console import ConsoleOptions, Console, RenderResult, RenderableType
from rich.live import Live
from rich.panel import Panel
from rich.segment import Segment
from rich.style import Style
from rich.text import Text
from textual.renderables.utilities import blend_colors
class Opacity:
"""Return a renderable with the foreground color blended into the background color.
"""Wrap a renderable to blend foreground color into the background color.
Args:
renderable (RenderableType): The RenderableType to manipulate.
@@ -16,4 +25,56 @@ class Opacity:
def __rich_console__(
self, console: Console, options: ConsoleOptions
) -> RenderResult:
pass
lines = console.render_lines(self.renderable, options)
opacity = self.value
for line in lines:
for segment in line:
style = segment.style
if not style:
yield segment
continue
fg, bg = style.color, style.bgcolor
if fg and bg:
style = Style.from_color(
color=blend_colors(bg, fg, ratio=opacity),
bgcolor=bg,
)
yield Segment(
text=segment.text,
style=style,
control=segment.control,
)
else:
yield segment
yield ""
if __name__ == "__main__":
console = Console()
panel = Panel.fit(
Text("Steak: £30", style="#fcffde on #03761e"),
title="Menu",
style="#ffffff on #000000",
)
console.print(panel)
opacity_panel = Opacity(panel, value=0.5)
console.print(opacity_panel)
def frange(start, end, step):
current = start
while current < end:
yield current
current += step
while current >= 0:
yield current
current -= step
import itertools
with Live(opacity_panel, refresh_per_second=60) as live:
for value in itertools.cycle(frange(0, 1, 0.05)):
opacity_panel.value = value
sleep(0.05)

View File

@@ -8,6 +8,8 @@ from rich.console import ConsoleOptions, Console, RenderResult
from rich.segment import Segment
from rich.style import Style
from textual.renderables.utilities import blend_colors
T = TypeVar("T", int, float)
@@ -83,34 +85,12 @@ class Sparkline:
partition_summary = summary_func(partition)
height_ratio = (partition_summary - minimum) / extent
bar_index = int(height_ratio * (len(self.BARS) - 1))
bar_color = _blend_colors(min_color, max_color, height_ratio)
bar_color = blend_colors(min_color, max_color, height_ratio)
bars_rendered += 1
bucket_index += step
yield Segment(text=self.BARS[bar_index], style=Style.from_color(bar_color))
def _blend_colors(color1: Color, color2: Color, ratio: float) -> Color:
"""Given two RGB colors, return a color that sits some distance between
them in RGB color space.
Args:
color1 (Color): The first color.
color2 (Color): The second color.
ratio (float): The ratio of color1 to color2.
Returns:
Color: A Color representing the blending of the two supplied colors.
"""
r1, g1, b1 = color1.triplet
r2, g2, b2 = color2.triplet
dr = r2 - r1
dg = g2 - g1
db = b2 - b1
return Color.from_rgb(
red=r1 + dr * ratio, green=g1 + dg * ratio, blue=b1 + db * ratio
)
if __name__ == "__main__":
console = Console()

View File

@@ -0,0 +1,23 @@
from rich.color import Color
def blend_colors(color1: Color, color2: Color, ratio: float) -> Color:
"""Given two RGB colors, return a color that sits some distance between
them in RGB color space.
Args:
color1 (Color): The first color.
color2 (Color): The second color.
ratio (float): The ratio of color1 to color2.
Returns:
Color: A Color representing the blending of the two supplied colors.
"""
r1, g1, b1 = color1.triplet
r2, g2, b2 = color2.triplet
dr = r2 - r1
dg = g2 - g1
db = b2 - b1
return Color.from_rgb(
red=r1 + dr * ratio, green=g1 + dg * ratio, blue=b1 + db * ratio
)