import drawsvg as dw import json import os from typing import cast from pathlib import Path from draw_functions import create_gold_icon, create_effects, draw_champion_shield from card_types import Card, SkinData, SkinFile, Translation from drawsvg.drawing import Drawing from edit_card import finish_card with open("src/data/translation_fr.json", encoding="utf-8") as f: translation_fr: Translation = json.load(f) with open("src/data/heron_skin.json", encoding="utf-8") as f: all_skin_data: SkinFile = json.load(f) cards: list[Card] = [] for p in Path("src/data/cards").glob("*.json"): with open(p, encoding="utf-8") as f: temp: list[Card] = json.load(f)["cards"] cards.extend(temp) # Params x_width = 298 y_height = 417 border_width_x = 12 border_width_y = 17 x_internal_width = x_width - (border_width_x * 2) border_upper_offset = 5 title_y_offset = 24 title_font_size = 19 title_font_size_small = 16 subtitle_font_size = 13 cost_right_offset = 38 background_colors = { "blue": "lightblue", "red": "lightcoral", "yellow": "rgb(206, 182, 167)", "green": "lightgreen", "base": "lightgrey", } gradient_colors = { "red": "red", "blue": "blue", "yellow": "yellow", "green": "green", "base": "gray", } icon_colors = { "yellow": ["#ff9935", "#ffe744"], "blue": ["#ff9935", "#ffe744"], "red": ["#ff9935", "#ffe744"], "green": ["#ff9935", "#ffe744"], "base": ["#ff9935", "#ffe744"], } shadowFilter = dw.Filter(id="drop-shadow") shadowFilter.append(dw.FilterItem("feDropShadow", dx=1, dy=1, stdDeviation=0)) # Draw faction icon faction_icon = dw.Group(id="faction_icon") faction_icon.append(dw.Circle(cx=1, cy=1, r=20, fill="black", filter=shadowFilter)) faction_icon.append( dw.Circle( cx=0, cy=0, r=20, fill="url(#grad2)", ) ) for card_data in cards: # Get card skin data try: card_skin_data = all_skin_data["cards"][str(card_data["id"])] except KeyError: print( "Missing skin data for card id:", card_data["id"], "using default skin data" ) card_skin_data = SkinData( title=card_data["name"], image_path="../../img/missing.png", flavor_text_type=None, ) # Check if card image really exists if not Path(card_skin_data["image_path"].replace("../../", "")).absolute().exists(): print("Missing image for card id: ", card_data["id"], " , using default image") card_skin_data["image_path"] = "../../img/missing.png" # Create a new SVG drawing output_dir = "output/" + all_skin_data["skin_name"] os.makedirs(output_dir, exist_ok=True) d = Drawing( x_width, y_height, id="card" + str(card_data["id"]), id_prefix=str(card_data.get("id")) + "_", **{ "class": "card", "xmlns:v-bind": "https://vuejs.org/guide/essentials/class-and-style.html", "xmlns:v-on": "https://vuejs.org/guide/essentials/event-handling.html", }, ) d.append(shadowFilter) # Define linear colored gradient gradient = dw.LinearGradient( 0, 0, 1, 0, gradientUnits="objectBoundingBox", id="grad1" ) gradient.add_stop(0, gradient_colors[card_data["faction"]], opacity=1) gradient.add_stop(1, gradient_colors[card_data["faction"]], opacity=0) d.append_def(gradient) # Define linear colored gradient for faction icon gradient_faction_icon = dw.LinearGradient( 0, 1, 0, 0, gradientUnits="objectBoundingBox", id="grad2" ) gradient_faction_icon.add_stop(0, icon_colors[card_data["faction"]][0], opacity=1) gradient_faction_icon.add_stop(1, icon_colors[card_data["faction"]][1], opacity=1) d.append_def(gradient_faction_icon) # Draw card background background = dw.Group(id="background") background.append( dw.Rectangle( 0, 0, x_width, y_height, rx=15, ry=18, fill="black", stroke="white", stroke_width=1, ) ) background.append( dw.Rectangle( border_width_x, border_width_y - border_upper_offset, x_internal_width, y_height - border_width_y * 2 + border_upper_offset, rx=0, ry=0, fill=background_colors[card_data["faction"]], ) ) d.append(background) # Draw title area # dwg.add(dwg.rect(insert=(0, 0), size=(str(x_width) + 'px', '50px'), fill='white')) title = dw.Group(id="title") card_title = card_skin_data["title"] if len(card_title) > 20: temp_title_font_size = title_font_size_small elif len(card_title) > 23: temp_title_font_size = title_font_size_small - 2 else: temp_title_font_size = title_font_size title.append( dw.Text( card_title, x=x_width / 2, y=title_y_offset + border_width_y - border_upper_offset, text_anchor="middle", fill="black", font_size=temp_title_font_size, font_weight="bold", font_family="Helvetica", ) ) # Draw type area card_type_text = translation_fr["card_type"].get( card_data["card_type"], card_data["card_type"] ) if card_skin_data.get("flavor_text_type") is not None: card_type_text += ", " + str(card_skin_data["flavor_text_type"]) title.append( dw.Text( card_type_text, font_size=subtitle_font_size, x=x_width / 2, y=title_y_offset + title_font_size + 10, text_anchor="middle", fill="black", font_family="Helvetica", ) ) d.append(title) # Draw faction icon d.append( dw.Group( children=[faction_icon], transform=f"translate({border_width_x + 23 + 1},{border_width_y - border_upper_offset + 20 + 4 + 1})", ) ) # Draw card cost if card_data.get("cost") is not None: d.append( dw.Group( children=[create_gold_icon(cast(int, card_data.get("cost")))], transform=f"translate({x_width - cost_right_offset},{19 + border_width_y})", ) ) # Draw image d.append(dw.Rectangle(x=1, y=65, width=x_width-2, height=200)) d.append( dw.Image( x=0, y=65, width=x_width, height=200, path=card_skin_data["image_path"] ) ) d.append(dw.Rectangle(x=2, y=65-1, width=border_width_x-2, height=200+2)) # d.append(dw.Rectangle(x=0, y=65+1, width=1, height=200+2, fill='white')) d.append(dw.Rectangle(x=x_width-border_width_x, y=65-1, width=border_width_x-2, height=200+2)) # Draw effects effects = card_data.get("effects") if effects is not None: effects = create_effects(effects=effects, height=135, width=x_internal_width) d.append( dw.Group( effects, transform=f"translate({border_width_x},{265})", ) ) # If champion, draw champion shield with defense if card_data["card_type"] == "champion": shield = draw_champion_shield(card_data, border_width_x) d.append( dw.Group( shield, transform=f"translate({x_width-30},{y_height})", ) ) # Save the SVG file d.save_svg( f"output/{all_skin_data['skin_name']}/{str(card_data['id']).zfill(3)}.svg" )