From bac65f6511c7921ad7f88fc7a34cb2d94b9da728 Mon Sep 17 00:00:00 2001 From: Valerie Date: Sat, 24 May 2025 07:32:57 -0400 Subject: [PATCH] Refactor stats layer in default.py for improved visual presentation. Update stats area dimensions, enhance glass effect properties, and adjust font sizes for better readability. Streamline layout for stats icons and reposition profile picture for a more polished card design. --- levelup/generator/styles/default.py | 157 +++++++++++----------------- 1 file changed, 61 insertions(+), 96 deletions(-) diff --git a/levelup/generator/styles/default.py b/levelup/generator/styles/default.py index 34654d5..a9a2342 100644 --- a/levelup/generator/styles/default.py +++ b/levelup/generator/styles/default.py @@ -240,119 +240,85 @@ def generate_default_profile( # Create the stats layer with glass effect stats_layer = Image.new("RGBA", desired_card_size, (0, 0, 0, 0)) - # Define the stats area to be larger and more prominent + # Define the stats area (right side of the card) stats_area = ( - 450, # x1 - Start from the middle - 50, # y1 - Start higher up - 950, # x2 - Extend further right - 400 # y2 - Extend lower down + 400, # x1 - Start after profile picture + 20, # y1 - Start near top + 1000, # x2 - End near right edge + 430 # y2 - End near bottom ) # Create glass effect for stats area stats_bg = card.crop(stats_area) if stats_bg.mode != "RGBA": stats_bg = stats_bg.convert("RGBA") - glass_bg = imgtools.create_glass_effect(stats_bg, opacity=0.3, blur_radius=20) - stats_layer.paste(glass_bg, stats_area, glass_bg) # Use glass_bg as mask + glass_bg = imgtools.create_glass_effect(stats_bg, opacity=0.25, blur_radius=15) # Add rounded corners to the glass effect - stats_mask = imgtools.get_rounded_corner_mask(glass_bg, radius=30) + stats_mask = imgtools.get_rounded_corner_mask(glass_bg, radius=20) glass_bg.putalpha(stats_mask) - stats_layer.paste(glass_bg, stats_area, glass_bg) # Use glass_bg as mask again + stats_layer.paste(glass_bg, stats_area, glass_bg) # Draw stats with improved styling draw = ImageDraw.Draw(stats_layer) - font_size = 32 # Increased font size - font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), font_size) - # Add stats with icons and modern layout - icon_size = font_size + 8 # Slightly larger icons - spacing = icon_size + 15 # More spacing between items - - # Messages stat with icon - msg_y = stats_area[1] + 50 # Start lower down - msg_icon = "💬" - draw.text( - (stats_area[0] + 30, msg_y), - msg_icon, - font=font, - fill=stat_color, - ) - draw.text( - (stats_area[0] + 30 + spacing, msg_y), - f"{humanize_number(messages)}", - font=font, - fill=stat_color, - ) - - # Voice time stat with icon - voice_y = msg_y + spacing + 20 # Add extra padding between stats - voice_icon = "🎤" - draw.text( - (stats_area[0] + 30, voice_y), - voice_icon, - font=font, - fill=stat_color, - ) - draw.text( - (stats_area[0] + 30 + spacing, voice_y), - imgtools.abbreviate_time(voicetime), - font=font, - fill=stat_color, - ) - - # Stars stat with icon - star_y = voice_y + spacing + 20 # Add extra padding between stats - star_icon = "⭐" - draw.text( - (stats_area[0] + 30, star_y), - star_icon, - font=font, - fill=stat_color, - ) - draw.text( - (stats_area[0] + 30 + spacing, star_y), - f"{humanize_number(stars)}", - font=font, - fill=stat_color, - ) - - # Add XP progress bar with enhanced glass effect - progress = (current_xp - previous_xp) / (next_xp - previous_xp) - bar_width = stats_area[2] - stats_area[0] - 60 # Slightly narrower for padding - bar_height = 30 # Taller bar - progress_bar = imgtools.make_progress_bar( - bar_width, - bar_height, - progress, - color=level_bar_color, - background_color=(100, 100, 100, 160) # More visible background - ) - progress_bar_y = stats_area[3] - 60 # Move up slightly - stats_layer.paste(progress_bar, (stats_area[0] + 30, progress_bar_y), progress_bar) - # Add level text with enhanced modern styling level_text = f"LEVEL {level}" if prestige > 0: level_text = f"P{prestige} • {level_text}" - level_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 48) # Larger font - level_y = stats_area[1] + 10 # Position at the top of stats area + level_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 48) + level_y = stats_area[1] + 20 draw.text( - (stats_area[0] + 30, level_y), + (stats_area[0] + 20, level_y), level_text, font=level_font, fill=user_color, - stroke_width=3, # Thicker stroke + stroke_width=2, stroke_fill=(0, 0, 0) ) - # Add XP text below progress bar + # Stats section + font_size = 32 + font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), font_size) + spacing = 50 # Vertical spacing between stats + + # Starting positions + start_x = stats_area[0] + 20 + start_y = level_y + 80 + + # Messages stat + draw.text((start_x, start_y), "💬", font=font, fill=stat_color) + draw.text((start_x + 40, start_y), f"{humanize_number(messages)}", font=font, fill=stat_color) + + # Voice time stat + draw.text((start_x, start_y + spacing), "🎤", font=font, fill=stat_color) + draw.text((start_x + 40, start_y + spacing), imgtools.abbreviate_time(voicetime), font=font, fill=stat_color) + + # Stars stat + draw.text((start_x, start_y + spacing * 2), "⭐", font=font, fill=stat_color) + draw.text((start_x + 40, start_y + spacing * 2), f"{humanize_number(stars)}", font=font, fill=stat_color) + + # Progress bar + progress = (current_xp - previous_xp) / (next_xp - previous_xp) + bar_width = stats_area[2] - stats_area[0] - 40 + bar_height = 25 + bar_y = stats_area[3] - 60 + + progress_bar = imgtools.make_progress_bar( + bar_width, + bar_height, + progress, + color=level_bar_color, + background_color=(100, 100, 100, 160) + ) + stats_layer.paste(progress_bar, (start_x, bar_y), progress_bar) + + # XP text xp_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 24) xp_text = f"{humanize_number(current_xp)} / {humanize_number(next_xp)} XP" - xp_y = progress_bar_y + bar_height + 5 draw.text( - (stats_area[0] + 30, xp_y), + (start_x, bar_y + bar_height + 5), xp_text, font=xp_font, fill=stat_color, @@ -363,32 +329,31 @@ def generate_default_profile( # Composite the layers if not render_gif or (not pfp_animated and not bg_animated): if card.mode != "RGBA": - log.debug(f"Converting card mode '{card.mode}' to RGBA") card = card.convert("RGBA") if pfp.mode != "RGBA": - log.debug(f"Converting pfp mode '{pfp.mode}' to RGBA") pfp = pfp.convert("RGBA") # Fit the background to the desired size card = imgtools.fit_aspect_ratio(card, desired_card_size) - if blur: - blur_section = imgtools.blur_section(card, (blur_edge, 0, card.width, card.height)) - card.paste(blur_section, (blur_edge, 0), blur_section) - # Round the card corners - card = imgtools.round_image_corners(card, 45) + card = imgtools.round_image_corners(card, 20) # Create circular profile picture - pfp_size = (350, 350) # Set fixed size for profile picture + pfp_size = (320, 320) # Profile picture size pfp = pfp.resize(pfp_size, Image.Resampling.LANCZOS) pfp = imgtools.make_profile_circle(pfp) - # Calculate position to center the profile picture in the left section - pfp_x = (450 - pfp_size[0]) // 2 # Center in left section - pfp_y = (card.height - pfp_size[1]) // 2 # Center vertically + # Position profile picture on the left + pfp_x = 40 + pfp_y = (card.height - pfp_size[1]) // 2 - # Paste the items onto the card + # Add blur effect if enabled + if blur: + blur_section = imgtools.blur_section(card, (stats_area[0], 0, card.width, card.height)) + card.paste(blur_section, (stats_area[0], 0), blur_section) + + # Paste the layers card.paste(stats_layer, (0, 0), stats_layer) card.paste(pfp, (pfp_x, pfp_y), pfp)