250 lines
7.4 KiB
Python
250 lines
7.4 KiB
Python
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"
|
|
)
|