summaryrefslogtreecommitdiff
path: root/draw.lua
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-09-17 04:43:44 +0000
committersanine <sanine.not@pm.me>2023-09-17 04:43:44 +0000
commitbfcc2e759807a692d8e0353e3bbecd109175032b (patch)
tree67949de6992714c703b390ef5f99ac5c06bfb28a /draw.lua
parent4f124ec785486c8505c6303e0d0aa3e7090612c7 (diff)
add yarrow-ui.cgi and theming
Diffstat (limited to 'draw.lua')
-rw-r--r--draw.lua146
1 files changed, 72 insertions, 74 deletions
diff --git a/draw.lua b/draw.lua
index 586f804..5d39cc5 100644
--- a/draw.lua
+++ b/draw.lua
@@ -37,14 +37,14 @@ local function pad(top, bottom, f, h)
end
-local function _divider()
+local function _divider(theme)
local size = 3
return function(y) return m.rect{
x=0, y=y, width=500, height=size,
- style="fill:darkred;",
+ style="fill:"..theme.flair,
} end, size
end
-local divider = function() return pad(0, 10, _divider()) end
+local divider = function(theme) return pad(0, 10, _divider(theme)) end
local function empty()
@@ -115,41 +115,33 @@ end
--===== basic stats =====--
-local function header(stats)
+local function header(stats, theme)
local f, h = stack(
--{pad(10, 10, name(stats))},
{pad(10, 10, text(
stats.name, 40,
- 'font-variant-caps:small-caps;stroke:black;fill:darkred;font-family:serif'
+ 'font-variant-caps:small-caps;stroke:'..theme.text..';fill:'..theme.flair..';font-family:serif'
))},
{pad(0, 10, text(
string.format("%s %s, %s", capitalize(stats.size), stats.type, stats.alignment),
- 14, 'font-style:italic'
+ 14, 'font-style:italic;fill:'..theme.text
))}
)
return f, h
end
-local function _statline(name, value)
- local size = 14
- return function(y) return m.text(
- '<tspan style="font-weight:bold">'..name..'</tspan> '..value,
- { x=10, y=y+size, style="font-size:"..size.."px;fill:darkred;" }
- ) end, 14
-end
---local statline = function(name, value) return pad(0, 2, _statline(name, value)) end
-local function statline(name, value)
+local function statline(name, value, theme)
return pad(0, 2, wrapped_text(
string.format('<tspan style="font-weight:bold">%s</tspan> %s', name, value),
- 80, 10, 14, 2, 'fill:darkred'
+ 80, 10, 14, 2, 'fill:'..theme.flair
))
end
-local function armor_hp(stats)
+local function armor_hp(stats, theme)
local f, h = pad(0, 10, stack(
- {statline('Armor Class', stats.ac)},
- {statline('Hit Points', stats.hp)},
- {statline('Speed', stats.speed)}
+ {statline('Armor Class', stats.ac, theme)},
+ {statline('Hit Points', stats.hp, theme)},
+ {statline('Speed', stats.speed, theme)}
))
return f, h
end
@@ -157,63 +149,63 @@ end
local function bonus(ability_score)
return math.floor( (ability_score-10)/2 )
end
-local function scorebox(name, ability_score, x, y)
+local function scorebox(name, ability_score, x, y, theme)
local score = tonumber(ability_score)
local value = string.format("%d (%s%d)", score, (score<0 and '-') or '+', bonus(score))
return m.g{
- m.text(name, { x=x+10, y=y+15, style="font-weight:bold;font-size:15px;fill:darkred" }),
- m.text(value, {x=x, y=y+30, style="font-size:15px;fill:darkred;" }),
+ m.text(name, { x=x+10, y=y+15, style="font-weight:bold;font-size:15px;fill:"..theme.flair }),
+ m.text(value, {x=x, y=y+30, style="font-size:15px;fill:"..theme.flair }),
}
end
-local function ability_scores(stats)
+local function ability_scores(stats, theme)
return function(y) return m.g{
- scorebox('STR', stats.str, 10, y),
- scorebox('DEX', stats.dex, 90, y),
- scorebox('CON', stats.con, 170, y),
- scorebox('INT', stats.int, 250, y),
- scorebox('WIS', stats.wis, 330, y),
- scorebox('CHA', stats.cha, 410, y),
+ scorebox('STR', stats.str, 10, y, theme),
+ scorebox('DEX', stats.dex, 90, y, theme),
+ scorebox('CON', stats.con, 170, y, theme),
+ scorebox('INT', stats.int, 250, y, theme),
+ scorebox('WIS', stats.wis, 330, y, theme),
+ scorebox('CHA', stats.cha, 410, y, theme),
} end, 40
end
-local function optional_attribute(stats, name, key)
+local function optional_attribute(stats, name, key, theme)
local value = stats[key]
if value then
- local f, h = statline(name, value)
+ local f, h = statline(name, value, theme)
return f, h
else
local f, h = empty()
return f, h
end
end
-local function misc_attributes(stats)
+local function misc_attributes(stats, theme)
local f, h = stack(
- {optional_attribute(stats, 'Saving Throws', 'saving_throws')},
- {optional_attribute(stats, 'Skills', 'skills')},
- {optional_attribute(stats, 'Damage Vulnerabilities', 'vulnerabilities')},
- {optional_attribute(stats, 'Damage Resistances', 'resistances')},
- {optional_attribute(stats, 'Damage Immunities', 'immunities')},
- {optional_attribute(stats, 'Condition Immunities', 'condition_immunities')},
- {optional_attribute(stats, 'Senses', 'senses')},
- {optional_attribute(stats, 'Languages', 'languages')},
- {optional_attribute(stats, 'Challenge', 'cr')}
+ {optional_attribute(stats, 'Saving Throws', 'saving_throws', theme)},
+ {optional_attribute(stats, 'Skills', 'skills', theme)},
+ {optional_attribute(stats, 'Damage Vulnerabilities', 'vulnerabilities', theme)},
+ {optional_attribute(stats, 'Damage Resistances', 'resistances', theme)},
+ {optional_attribute(stats, 'Damage Immunities', 'immunities', theme)},
+ {optional_attribute(stats, 'Condition Immunities', 'condition_immunities', theme)},
+ {optional_attribute(stats, 'Senses', 'senses', theme)},
+ {optional_attribute(stats, 'Languages', 'languages', theme)},
+ {optional_attribute(stats, 'Challenge', 'cr', theme)}
)
- if h > 0 then return stack({pad(0, 10, f, h)}, {divider()})
+ if h > 0 then return stack({pad(0, 10, f, h)}, {divider(theme)})
else return empty(), 0 end
end
-local function base(stats)
+local function base(stats, theme)
local f, h = stack(
- {header(stats)},
- {divider()},
- {armor_hp(stats)},
- {divider()},
- {ability_scores(stats)},
- {divider()},
- {misc_attributes(stats)}
+ {header(stats, theme)},
+ {divider(theme)},
+ {armor_hp(stats, theme)},
+ {divider(theme)},
+ {ability_scores(stats, theme)},
+ {divider(theme)},
+ {misc_attributes(stats, theme)}
)
return f, h
end
@@ -221,18 +213,18 @@ end
--===== traits =====--
-local function trait(t)
+local function trait(t, theme)
return pad(0, 10, wrapped_text(
string.format('<tspan style="font-weight:bold;font-style:italic">%s.</tspan> %s', t.name, format(t.value)),
- 80, 10, 14, 5
+ 80, 10, 14, 5, 'fill:'..theme.text
))
end
-local function traits(stats)
+local function traits(stats, theme)
if not stats.traits then return empty() end
local tbl = {}
for _, t in ipairs(stats.traits) do
- table.insert(tbl, {trait(t)})
+ table.insert(tbl, {trait(t, theme)})
end
return stack(unpack(tbl))
end
@@ -240,51 +232,51 @@ end
--===== actions =====--
-local function subheader(title)
+local function subheader(title, theme)
return pad(0, 10, stack(
- {pad(0, 5, text(title, 25, 'font-variant-caps:small-caps;stroke:black;fill:darkred'))},
- {divider()}
+ {pad(0, 5, text(title, 25, 'font-variant-caps:small-caps;stroke:'..theme.text..';fill:'..theme.flair))},
+ {divider(theme)}
))
end
-local function actions(stats)
+local function actions(stats, theme)
if not stats.actions then return empty() end
local tbl = {}
for _, action in ipairs(stats.actions) do
- table.insert(tbl, {trait(action)})
+ table.insert(tbl, {trait(action, theme)})
end
return stack(
- {subheader('Actions')},
+ {subheader('Actions', theme)},
unpack(tbl)
)
end
-local function reactions(stats)
+local function reactions(stats, theme)
if not stats.reactions then return empty() end
local tbl = {}
for _, reaction in ipairs(stats.reactions) do
- table.insert(tbl, {trait(reaction)})
+ table.insert(tbl, {trait(reaction, theme)})
end
return stack(
- {subheader('Reactions')},
+ {subheader('Reactions', theme)},
unpack(tbl)
)
end
-local function legendary(stats)
+local function legendary(stats, theme)
if not stats.legendary then return empty() end
local tbl = {}
for _, action in ipairs(stats.legendary.actions) do
- table.insert(tbl, {trait(action)})
+ table.insert(tbl, {trait(action, theme)})
end
return stack(
- {subheader('Legendary Actions')},
- {pad(0, 10, wrapped_text(stats.legendary.description, 80, 10, 14, 2, ''))},
+ {subheader('Legendary Actions', theme)},
+ {pad(0, 10, wrapped_text(stats.legendary.description, 80, 10, 14, 2, 'fill:'..theme.text))},
unpack(tbl)
)
end
@@ -294,19 +286,25 @@ end
--===== draw =====--
-function draw(stats)
+function draw(stats, theme)
+ local theme = theme or {
+ bg = '#020202',
+ text = 'beige',
+ flair = 'tomato',
+ }
local f, h = stack(
- {base(stats)},
- {traits(stats)},
- {actions(stats)},
- {reactions(stats)},
- {legendary(stats)}
+ {base(stats, theme)},
+ {traits(stats, theme)},
+ {actions(stats, theme)},
+ {reactions(stats, theme)},
+ {legendary(stats, theme)}
)
return m.render(m.svg{
viewBox = string.format("0 0 500 %d", h),
width = 500,
height = height,
style = "font-family:sans-serif;",
+ m.rect{x=0, y=0, width=500, height=h, style='fill:'..theme.bg},
f(0),
})
end