卡牌/display:修订间差异
来自卡厄思梦境WIKI
< 模块:卡牌
< 模块:卡牌
无编辑摘要 标签:已被回退 |
无编辑摘要 |
||
| (未显示同一用户的4个中间版本) | |||
| 第206行: | 第206行: | ||
local function renderSkillCardLayersSmall(info) | local function renderSkillCardLayersSmall(info) | ||
local html = {} | local html = {} | ||
table.insert(html, '<div style="position:absolute;top:0px;left: | table.insert(html, '<div style="position:absolute;top:0px;left:5px;z-index:0;">[[File:' .. escFile(info.art) .. '|164px|link=]]</div>') | ||
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:1;">[[File:card_skill_黑色蒙版.png|169px|link=]]</div>') | table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:1;">[[File:card_skill_黑色蒙版.png|169px|link=]]</div>') | ||
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_skill_ego_' .. escFile(info.ego) .. '.png|169px|link=]]</div>') | table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_skill_ego_' .. escFile(info.ego) .. '.png|169px|link=]]</div>') | ||
| 第226行: | 第226行: | ||
local function renderSkillCardLayersLarge(info) | local function renderSkillCardLayersLarge(info) | ||
local html = {} | local html = {} | ||
table.insert(html, '<div style="position:absolute;top:0px;left: | table.insert(html, '<div style="position:absolute;top:0px;left:10px;z-index:0;">[[File:' .. escFile(info.art) .. '|328px|link=]]</div>') | ||
table.insert(html, '<div style="position:absolute;top:2px;left:0px;z-index:1;">[[File:card_skill_黑色蒙版.png|338px|link=]]</div>') | table.insert(html, '<div style="position:absolute;top:2px;left:0px;z-index:1;">[[File:card_skill_黑色蒙版.png|338px|link=]]</div>') | ||
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_skill_ego_' .. escFile(info.ego) .. '.png|338px|link=]]</div>') | table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_skill_ego_' .. escFile(info.ego) .. '.png|338px|link=]]</div>') | ||
| 第245行: | 第245行: | ||
return table.concat(html, '') | return table.concat(html, '') | ||
end | end | ||
function p.renderSmallCard(cardInfo, cardId, dictDisplay) | function p.renderSmallCard(cardInfo, cardId, dictDisplay) | ||
| 第299行: | 第297行: | ||
-- 普通小卡牌 | -- 普通小卡牌 | ||
table.insert(html, '<div class="card-small-wrapper" data-card-id="' .. escText(cardId) .. '" style="display:inline-block;vertical-align:top;position:relative;width:183px;height:257px;overflow:hidden;cursor:pointer;">') | table.insert(html, '<div class="card-small-wrapper" data-card-id="' .. escText(cardId) .. '" style="display:inline-block;vertical-align:top;position:relative;width:183px;height:257px;overflow:hidden;cursor:pointer;">') | ||
table.insert(html, renderNormalCardLayers(cardInfo, 183)) | table.insert(html, renderNormalCardLayers(cardInfo, 183)) | ||
| 第439行: | 第375行: | ||
table.insert(html, '<div style="position:absolute;z-index:10;top:280px;left:24px;width:310px;height:220px;color:white;text-align:center;font-size:26px;line-height:30px;">') | table.insert(html, '<div style="position:absolute;z-index:10;top:280px;left:24px;width:310px;height:220px;color:white;text-align:center;font-size:26px;line-height:30px;">') | ||
local largeContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or '')) | local largeContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. largeContent .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第665行: | 第601行: | ||
table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">') | table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">') | ||
local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. inspContent .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第682行: | 第618行: | ||
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">') | table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">') | ||
local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. inspContent .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第723行: | 第659行: | ||
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:28px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">') | table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:28px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">') | ||
local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. inspContent .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第762行: | 第698行: | ||
table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">') | table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">') | ||
local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. content .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第779行: | 第715行: | ||
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">') | table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">') | ||
local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. content .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第795行: | 第731行: | ||
-- 标题背景条 | -- 标题背景条 | ||
local barBg = rarityBarColor(variantInfo.rarity) | local barBg = rarityBarColor(variantInfo.rarity) | ||
table.insert(html, '<div style="position:absolute;top: | table.insert(html, '<div style="position:absolute;top:55px;left:23px;width:245px;height:14px;background:' .. barBg .. ';z-index:2;"></div>') | ||
-- EGO框架 | -- EGO框架 | ||
| 第805行: | 第741行: | ||
-- 能量线 | -- 能量线 | ||
table.insert(html, '<div style="position:absolute;top: | table.insert(html, '<div style="position:absolute;top:86px;left:30px;z-index:5;">[[File:energy_line_蓝.png|38px|link=]]</div>') | ||
-- AP显示 | -- AP显示 | ||
table.insert(html, renderApDiv(apDisplay, ' | table.insert(html, renderApDiv(apDisplay, '37px', '38px', '57px', variantInfo.apStyle or 'blue')) | ||
-- 名称 | -- 名称 | ||
table.insert(html, '<div style="position:absolute;z-index:10;top: | table.insert(html, '<div style="position:absolute;z-index:10;top:45px;left:75px;width:173px;font-size:28px;color:' .. nameColor .. '">' .. escText(variantInfo.displayTitleShort or variantInfo.displayTitle or variantInfo.cardName) .. '</div>') | ||
-- 类型图标和文字 | -- 类型图标和文字 | ||
table.insert(html, '<div style="position:absolute;z-index:10;top: | table.insert(html, '<div style="position:absolute;z-index:10;top:76px;left:72px;">[[File:card_type_' .. escFile(variantInfo.cardType) .. '.png|24px|link=]]</div>') | ||
table.insert(html, '<div style="position:absolute;z-index:10;top: | table.insert(html, '<div style="position:absolute;z-index:10;top:78px;left:99px;font-size:18px;color:white">' .. escText(variantInfo.cardType) .. '</div>') | ||
-- 描述 | -- 描述 | ||
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left: | table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:30px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">') | ||
local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. content .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第887行: | 第823行: | ||
table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">') | table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">') | ||
local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or '')) | local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. subContent .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第904行: | 第840行: | ||
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">') | table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">') | ||
local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or '')) | local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. subContent .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
| 第945行: | 第881行: | ||
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:28px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">') | table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:28px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">') | ||
local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or '')) | local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or '')) | ||
table.insert(html, '<div class="scroll-text | table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. subContent .. '</div></div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
2025年10月29日 (三) 14:18的最新版本
此模块的文档可以在模块:卡牌/display/doc创建
local p = {}
-- 页面内唯一 ID 计数器(避免同页重复)
local uid_counter = 0
local function escFile(s)
s = tostring(s or '')
s = mw.text.trim(s)
s = s:gsub('[%[%]%{%}%|]', '')
return s
end
local function escText(s)
return mw.text.encode(tostring(s or ''))
end
local function expandWikitext(s)
if s == nil or s == '' then
return ''
end
local ok, frame = pcall(mw.getCurrentFrame)
if not ok or not frame then
return tostring(s)
end
return frame:preprocess(tostring(s))
end
local function normalizeRarity(r)
local s = tostring(r or ''):gsub('%s+', '')
if s == '' then return nil end
if s == '白' then return '白' end
if s == '蓝' then return '蓝' end
if s == '橙' then return '橙' end
if s == '彩' then return '彩' end
return nil
end
local function rarityBarColor(r)
local key = normalizeRarity(r) or '蓝'
local map = {
['白'] = 'rgba(239, 237, 237, 0.5)',
['蓝'] = 'rgba(119, 236, 254, 0.5)',
['橙'] = 'rgba(255, 200, 110, 0.5)',
['彩'] = 'rgba(180, 125, 242, 0.5)',
}
return map[key] or map['蓝']
end
local function rarityNameColor(r)
local key = normalizeRarity(r) or '蓝'
local map = {
['白'] = '#cccccc',
['蓝'] = '#75ebff',
['橙'] = '#eee9a2',
['彩'] = '#cb75e1',
}
return map[key] or map['蓝']
end
local function generateUniqueId(cardInfo)
uid_counter = uid_counter + 1
local base = (cardInfo.moduleName or '') .. '-' .. (cardInfo.cardName or '') .. (cardInfo.variantSuffix or '')
local safeName = mw.uri.anchorEncode(base):gsub("%%", "-")
return "card-" .. safeName .. "-" .. tostring(uid_counter)
end
local function apTextShadow(style)
if style == 'red' then
return 'text-shadow:0 0 10px #7a0e0e,0 0 20px #7a0e0e,0 0 30px #ff3030,0 0 40px #ff3030,0 0 50px #ff3030,0 0 60px #ff3030,0 0 70px #ff3030;'
elseif style == 'green' then
return 'text-shadow:0 0 10px #0e6f36,0 0 20px #0e6f36,0 0 30px #29ff85,0 0 40px #29ff85,0 0 50px #29ff85,0 0 60px #29ff85,0 0 70px #29ff85;'
elseif style == 'blue' then
return 'text-shadow:0 0 10px #132cbf,0 0 20px #132cbf,0 0 30px #4169ff,0 0 40px #4169ff,0 0 50px #4169ff,0 0 60px #4169ff,0 0 70px #4169ff;'
else
return ''
end
end
local function renderApDiv(content, top, left, fontSize, style)
content = tostring(content or '')
local shadow = apTextShadow(style)
local color = (style == 'gray') and '#cfcfcf' or 'white'
return string.format(
'<div style="position:absolute;z-index:10;top:%s;left:%s;font-family:number;font-size:%s;color:%s;%s">%s</div>',
top, left, fontSize, color, shadow, content
)
end
local function dictSpanFromTokens(tokens, color)
if type(tokens) ~= 'table' or #tokens == 0 then
return ''
end
local parts = {}
for _, t in ipairs(tokens) do
local value = mw.text.trim(t.value or '')
if value ~= '' then -- ✅ 只处理非空词
if t.type == 'template' then
table.insert(parts, '{{词典|' .. value .. '}}')
elseif t.type == 'text' then
table.insert(parts, value)
end
end
end
if #parts == 0 then return '' end
local colorMap = {
default = '#f2ba02',
green = '#b5f651'
}
local c = colorMap[color or 'default'] or colorMap.default
return '<span style="color: ' .. c .. '">[' .. table.concat(parts, '/') .. ']</span><br>'
end
local function renderMechanismCard(title, desc)
title = escText(title or '')
local d = tostring(desc or '')
if d == '' then
d = '暂无详细说明'
end
local body = expandWikitext(d)
local dhtml = {}
table.insert(dhtml, '<div class="mechanism-card" style="width: 250px; margin-bottom: 10px">')
table.insert(dhtml, '<div style="width: 250px; height: 2px; background-color: #f2ba02;"></div>')
table.insert(dhtml, '<div style="width: 100%; background-color: #343434; color: white; padding: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.3); line-height: 1.6;">')
table.insert(dhtml, '<div style="font-weight: bold;">' .. title .. '</div>')
table.insert(dhtml, '<div>' .. body .. '</div>')
table.insert(dhtml, '</div>')
table.insert(dhtml, '</div>')
return table.concat(dhtml, '')
end
local function renderDictMechanisms(dictEntries)
if type(dictEntries) ~= 'table' or #dictEntries == 0 then return '' end
local html = {}
table.insert(html, '<div class="dict-mechanisms" style="display:flex;flex-direction:column;align-items:flex-start;gap-right:0px;gap-left:15px;margin-left:10px;width:250px;flex:0 0 250px;overflow:visible;">')
for _, entry in ipairs(dictEntries) do
table.insert(html, renderMechanismCard(entry.key, entry.desc))
end
table.insert(html, '</div>')
return table.concat(html, '')
end
-- 渲染普通卡牌的立绘和覆盖层
local function renderNormalCardLayers(info, width)
local html = {}
local barColor = rarityBarColor(info.rarity)
-- 立绘层
table.insert(html, '<div style="position:absolute;top:2px;left:15px;z-index:0;">[[File:' .. escFile(info.art) .. '|164px|link=]]</div>')
-- 黑色蒙版
table.insert(html, '<div style="position:absolute;top:1px;left:3px;z-index:1;">[[File:card_黑色蒙版.png|179px|link=]]</div>')
-- 标题背景条
table.insert(html, '<div style="position:absolute;top:33px;left:15px;width:163px;height:10px;background:' .. barColor .. ';z-index:2;"></div>')
-- EGO框架
table.insert(html, '<div style="position:absolute;top:0px;left:2px;z-index:3;">[[File:card_ego_' .. escFile(info.ego) .. '.png|179px|link=]]</div>')
-- 稀有度标识
table.insert(html, '<div style="position:absolute;top:25px;left:1px;z-index:4;">[[File:card_rarity_' .. escFile(info.rarity) .. '.png|21px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:27px;right:0px;z-index:4;">[[File:card_rarity_' .. escFile(info.rarity) .. '_sub.png|10px|link=]]</div>')
-- 能量线
table.insert(html, '<div style="position:absolute;top:50px;left:20px;z-index:5;">[[File:energy_line_蓝.png|25px|link=]]</div>')
return table.concat(html, '')
end
-- 渲染状态异常卡牌的立绘和覆盖层(小)
local function renderAbnormalCardLayersSmall(info)
local html = {}
table.insert(html, '<div style="position:absolute;top:5px;left:5px;z-index:0;">[[File:' .. escFile(info.art) .. '|165px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:1;">[[File:card_状态异常_黑色蒙版.png|179px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_ego_状态异常.png|179px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:50px;left:20px;z-index:5;">[[File:energy_line_蓝.png|25px|link=]]</div>')
return table.concat(html, '')
end
-- 渲染状态异常卡牌的立绘和覆盖层(中)
local function renderAbnormalCardLayersMedium(info)
local html = {}
table.insert(html, '<div style="position:absolute;top:8px;left:8px;z-index:0;">[[File:' .. escFile(info.art) .. '|248px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:1px;left:3px;z-index:1;">[[File:card_状态异常_黑色蒙版.png|269px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_ego_状态异常.png|269px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:80px;left:30px;z-index:5;">[[File:energy_line_蓝.png|38px|link=]]</div>')
return table.concat(html, '')
end
-- 渲染状态异常卡牌的立绘和覆盖层(大)
local function renderAbnormalCardLayersLarge(info)
local html = {}
table.insert(html, '<div style="position:absolute;top:10px;left:10px;z-index:0;">[[File:' .. escFile(info.art) .. '|330px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:1;">[[File:card_状态异常_黑色蒙版.png|358px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_ego_状态异常.png|358px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:110px;left:40px;z-index:5;">[[File:energy_line_蓝.png|50px|link=]]</div>')
return table.concat(html, '')
end
-- 渲染自我意识技能卡牌的立绘和覆盖层(小)
local function renderSkillCardLayersSmall(info)
local html = {}
table.insert(html, '<div style="position:absolute;top:0px;left:5px;z-index:0;">[[File:' .. escFile(info.art) .. '|164px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:1;">[[File:card_skill_黑色蒙版.png|169px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_skill_ego_' .. escFile(info.ego) .. '.png|169px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:3;">[[File:card_skill_line.png|169px|link=]]</div>')
return table.concat(html, '')
end
-- 渲染自我意识技能卡牌的立绘和覆盖层(中)
local function renderSkillCardLayersMedium(info)
local html = {}
table.insert(html, '<div style="position:absolute;top:0px;left:5px;z-index:0;">[[File:' .. escFile(info.art) .. '|246px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:1;">[[File:card_skill_黑色蒙版.png|254px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_skill_ego_' .. escFile(info.ego) .. '.png|254px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:3;">[[File:card_skill_line.png|254px|link=]]</div>')
return table.concat(html, '')
end
-- 渲染自我意识技能卡牌的立绘和覆盖层(大)
local function renderSkillCardLayersLarge(info)
local html = {}
table.insert(html, '<div style="position:absolute;top:0px;left:10px;z-index:0;">[[File:' .. escFile(info.art) .. '|328px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:2px;left:0px;z-index:1;">[[File:card_skill_黑色蒙版.png|338px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:2;">[[File:card_skill_ego_' .. escFile(info.ego) .. '.png|338px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:3;">[[File:card_skill_line.png|338px|link=]]</div>')
return table.concat(html, '')
end
function p.render(cardInfo, subCardInfo)
if not cardInfo then
return '<span style="color:red;">错误: 卡牌信息为空</span>'
end
local dictDisplay = dictSpanFromTokens(cardInfo.dictTokens, cardInfo.dictColor)
local cardId = generateUniqueId(cardInfo)
local html = {}
table.insert(html, p.renderSmallCard(cardInfo, cardId, dictDisplay))
table.insert(html, p.renderLargeCard(cardInfo, cardId, dictDisplay, subCardInfo))
return table.concat(html, '')
end
function p.renderSmallCard(cardInfo, cardId, dictDisplay)
local html = {}
local apDisplay = cardInfo.apText or ''
local nameColor = rarityNameColor(cardInfo.rarity)
local isAbnormal = (cardInfo.cardType == "状态异常")
local isSkill = (cardInfo.group == "自我意识技能")
if isSkill then
-- 自我意识技能小卡牌
table.insert(html, '<div class="card-small-wrapper" data-card-id="' .. escText(cardId) .. '" style="display:inline-block;vertical-align:top;position:relative;width:169px;height:260px;overflow:hidden;cursor:pointer;">')
table.insert(html, renderSkillCardLayersSmall(cardInfo))
-- 标题
table.insert(html, '<div style="position:absolute;top:90px;left:24px;z-index:10;font-size:16px;color:white">' .. escText(cardInfo.displayTitle or cardInfo.cardName) .. '</div>')
-- 类型图标和文字
table.insert(html, '<div style="position:absolute;top:110px;left:22px;z-index:10;">[[File:icon_tp_skill_type_awaken.png|20px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:111px;left:42px;z-index:10;font-size:13px;color:white">自我意识技能</div>')
-- 分隔线
table.insert(html, '<div style="position:absolute;top:132px;left:22px;width:141px;height:1px;background-color:rgba(255,255,255);z-index:10;"></div>')
-- AP显示
local apNum = tonumber(apDisplay) or 0
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:10;">[[File:card_skill_ap_' .. apNum .. '.png|169px|link=]]</div>')
-- 描述
table.insert(html, '<div style="position:absolute;top:137px;left:22px;width:140px;height:105px;color:white;text-align:left;font-size:13px;line-height:15px;z-index:10;">')
local smallContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or ''))
table.insert(html, '<div><div>' .. smallContent .. '</div></div>')
table.insert(html, '</div>')
elseif isAbnormal then
-- 状态异常小卡牌
table.insert(html, '<div class="card-small-wrapper" data-card-id="' .. escText(cardId) .. '" style="display:inline-block;vertical-align:top;position:relative;width:179px;height:265px;overflow:hidden;cursor:pointer;">')
table.insert(html, renderAbnormalCardLayersSmall(cardInfo))
table.insert(html, renderApDiv(apDisplay, '15px', '25px', '38px', cardInfo.apStyle or 'blue'))
table.insert(html, '<div style="position:absolute;z-index:10;top:20px;left:50px;width:115px;font-size:22px;color:' .. nameColor .. '">' .. escText(cardInfo.displayTitleShort or cardInfo.displayTitle or cardInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:44px;left:48px;">[[File:card_type_' .. escFile(cardInfo.cardType) .. '.png|16px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:48px;left:66px;font-size:12px;color:white">状态异常</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:140px;left:12px;width:155px;height:110px;color:white;text-align:center;font-size:13px;line-height:15px; display: flex; align-items: center; justify-content: center;">')
local smallContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. smallContent .. '</div></div>')
table.insert(html, '</div>')
else
-- 普通小卡牌
table.insert(html, '<div class="card-small-wrapper" data-card-id="' .. escText(cardId) .. '" style="display:inline-block;vertical-align:top;position:relative;width:183px;height:257px;overflow:hidden;cursor:pointer;">')
table.insert(html, renderNormalCardLayers(cardInfo, 183))
table.insert(html, renderApDiv(apDisplay, '22px', '25px', '38px', cardInfo.apStyle or 'blue'))
table.insert(html, '<div style="position:absolute;z-index:10;top:27px;left:50px;width:115px;font-size:19px;color:' .. nameColor .. '">' .. escText(cardInfo.displayTitleShort or cardInfo.displayTitle or cardInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:45px;left:48px;">[[File:card_type_' .. escFile(cardInfo.cardType) .. '.png|16px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:48px;left:66px;font-size:14px;color:white">' .. escText(cardInfo.cardType) .. '</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:140px;left:20px;width:155px;height:110px;color:white;text-align:center;font-size:13px;line-height:15px; display: flex; align-items: center; justify-content: center;">')
local smallContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. smallContent .. '</div></div>')
table.insert(html, '</div>')
end
table.insert(html, '</div>')
return table.concat(html, '')
end
function p.renderLargeCard(cardInfo, cardId, dictDisplay, subCardInfos)
local html = {}
local apDisplay = cardInfo.apText or ''
local nameColor = rarityNameColor(cardInfo.rarity)
local isAbnormal = (cardInfo.cardType == "状态异常")
local isSkill = (cardInfo.group == "自我意识技能")
table.insert(html, '<div id="' .. escText(cardId) .. '-modal" class="card-modal" style="display:none;position:fixed;z-index:9999;left:0;top:0;width:100%;height:100%;background-color:rgba(0,0,0,0.8);">')
table.insert(html, '<div class="modal-close-button" style="position:fixed;top:20px;right:20px;z-index:10001;width:40px;height:40px;background:rgba(255,255,255,0.2);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all 0.3s;">')
table.insert(html, '<span style="color:white;font-size:24px;line-height:1;">×</span>')
table.insert(html, '</div>')
table.insert(html, '<div class="card-modal-inner" style="height:100vh;display:flex;align-items:center;justify-content:center;">')
table.insert(html, '<div class="original-card-view" style="display:flex;align-items:flex-start;justify-content:center;gap-right:0px;gap-left:15px;flex-wrap:wrap;">')
-- 左侧:衍生卡牌
if subCardInfos and type(subCardInfos) == 'table' and #subCardInfos > 0 then
table.insert(html, '<div class="ocv-col-left" style="display:flex;flex-direction:column;align-items:center;margin-right:30px; max-width:240px;">')
table.insert(html, p.renderSubCard(subCardInfos[1]))
if #subCardInfos > 1 then
table.insert(html, '<div class="subcards-button" style="display:inline-block;padding:10px 10px;background:linear-gradient(135deg,#6fd8fe 0%,#4da6cc 100%);color:white;font-size:18px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">查看所有衍生卡牌</div>')
end
table.insert(html, '</div>')
end
-- 中间:放大卡片
if isSkill then
-- 自我意识技能大卡牌
table.insert(html, '<div class="ocv-col-center" style="display:flex;flex-direction:column;align-items:center;gap-right:0px;gap-left:15px;max-width:338px;">')
table.insert(html, '<div style="display:inline-block;vertical-align:top;position:relative;width:338px;height:510px;overflow:hidden;">')
table.insert(html, renderSkillCardLayersLarge(cardInfo))
table.insert(html, '<div style="position:absolute;top:180px;left:48px;z-index:10;font-size:32px;color:white">' .. escText(cardInfo.displayTitle or cardInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;top:223px;left:44px;z-index:10;">[[File:icon_tp_skill_type_awaken.png|40px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:222px;left:84px;z-index:10;font-size:26px;color:white">自我意识技能</div>')
table.insert(html, '<div style="position:absolute;top:264px;left:44px;width:282px;height:2px;background-color:rgba(255,255,255);z-index:10;"></div>')
local apNum = tonumber(apDisplay) or 0
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:10;">[[File:card_skill_ap_' .. apNum .. '.png|338px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:270px;left:43px;width:285px;height:220px;color:white;text-align:left;font-size:26px;line-height:30px;z-index:10;">')
local largeContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or ''))
table.insert(html, '<div><div>' .. largeContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
elseif isAbnormal then
-- 状态异常大卡牌
table.insert(html, '<div class="ocv-col-center" style="display:flex;flex-direction:column;align-items:center;gap-right:0px;gap-left:15px;max-width:358px;">')
table.insert(html, '<div style="display:inline-block;vertical-align:top;position:relative;width:358px;height:524px;overflow:hidden;">')
table.insert(html, renderAbnormalCardLayersLarge(cardInfo))
table.insert(html, renderApDiv(apDisplay, '30px', '50px', '76px', cardInfo.apStyle or 'blue'))
table.insert(html, '<div style="position:absolute;z-index:10;top:40px;left:100px;width:230px;font-size:44px;color:' .. nameColor .. '">' .. escText(cardInfo.displayTitleShort or cardInfo.displayTitle or cardInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:95px;left:96px;">[[File:card_type_' .. escFile(cardInfo.cardType) .. '.png|32px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:94px;left:132px;font-size:24px;color:white">状态异常</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:280px;left:24px;width:310px;height:220px;color:white;text-align:center;font-size:26px;line-height:30px;">')
local largeContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. largeContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
else
-- 普通放大卡牌
table.insert(html, '<div class="ocv-col-center" style="display:flex;flex-direction:column;align-items:center;gap-right:0px;gap-left:15px;max-width:366px;">')
table.insert(html, '<div style="display:inline-block;vertical-align:top;position:relative;width:366px;height:514px;overflow:hidden;">')
-- 立绘层
table.insert(html, '<div style="position:absolute;top:4px;left:29px;z-index:0;">[[File:' .. escFile(cardInfo.art) .. '|328px|link=]]</div>')
-- 黑色蒙版
table.insert(html, '<div style="position:absolute;top:2px;left:5px;z-index:1;">[[File:card_黑色蒙版.png|358px|link=]]</div>')
-- 标题背景条
local barColor = rarityBarColor(cardInfo.rarity)
table.insert(html, '<div style="position:absolute;top:66px;left:30px;width:326px;height:20px;background:' .. barColor .. ';z-index:2;"></div>')
-- EGO框架
table.insert(html, '<div style="position:absolute;top:0px;left:4px;z-index:3;">[[File:card_ego_' .. escFile(cardInfo.ego) .. '.png|358px|link=]]</div>')
-- 稀有度标识
table.insert(html, '<div style="position:absolute;top:50px;left:2px;z-index:4;">[[File:card_rarity_' .. escFile(cardInfo.rarity) .. '.png|42px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:54px;right:0px;z-index:4;">[[File:card_rarity_' .. escFile(cardInfo.rarity) .. '_sub.png|20px|link=]]</div>')
-- 能量线
table.insert(html, '<div style="position:absolute;top:114px;left:40px;z-index:5;">[[File:energy_line_蓝.png|50px|link=]]</div>')
-- AP显示
table.insert(html, renderApDiv(apDisplay, '44px', '50px', '76px', cardInfo.apStyle or 'blue'))
-- 卡牌名称
table.insert(html, '<div style="position:absolute;z-index:10;top:55px;left:100px;width:230px;font-size:38px;color:' .. nameColor .. '">' .. escText(cardInfo.displayTitleShort or cardInfo.displayTitle or cardInfo.cardName) .. '</div>')
-- 类型图标和文字
table.insert(html, '<div style="position:absolute;z-index:10;top:98px;left:96px;">[[File:card_type_' .. escFile(cardInfo.cardType) .. '.png|32px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:98px;left:132px;font-size:28px;color:white">' .. escText(cardInfo.cardType) .. '</div>')
-- 描述文本
table.insert(html, '<div style="position:absolute;z-index:10;top:280px;left:40px;width:310px;height:220px;color:white;text-align:center;font-size:26px;line-height:30px; display: flex; align-items: center; justify-content: center;">')
local largeContent = expandWikitext((dictDisplay or '') .. (cardInfo.desc or ''))
table.insert(html, '<div class="scroll-text" ><div class="scroll-text-content">' .. largeContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
end
-- 灵光一闪和神光一闪按钮
if (cardInfo.hasInspiration and cardInfo.inspirationVariants and type(cardInfo.inspirationVariants) == 'table' and #cardInfo.inspirationVariants > 0) or
(cardInfo.hasGodInspiration and cardInfo.godInspirationGroups and cardInfo.godInspirationGroupOrder) then
table.insert(html, '<div class="variant-buttons" style="display:flex;gap:15px;align-items:center;justify-content:center;flex-wrap:wrap;">')
if cardInfo.hasInspiration and cardInfo.inspirationVariants and type(cardInfo.inspirationVariants) == 'table' and #cardInfo.inspirationVariants > 0 then
table.insert(html, '<div class="inspiration-button" style="display:inline-block;padding:10px 10px;background:linear-gradient(135deg,#6fd8fe 0%,#4da6cc 100%);color:white;font-size:18px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">灵光一闪</div>')
end
if cardInfo.hasGodInspiration and cardInfo.godInspirationGroups and cardInfo.godInspirationGroupOrder then
table.insert(html, '<div class="god-inspiration-button" style="display:inline-block;padding:10px 10px;background:linear-gradient(135deg,#ffd36a 0%,#e6a600 100%);color:white;font-size:18px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">神光一闪</div>')
end
table.insert(html, '</div>')
end
table.insert(html, '</div>') -- 结束中间列
-- 右侧:词典机制说明
table.insert(html, '<div class="ocv-col-right" style="display:flex;flex-direction:column;align-items:flex-start;gap-right:0px;gap-left:15px;max-width:250px;">')
table.insert(html, renderDictMechanisms(cardInfo.dictEntries))
table.insert(html, '</div>')
table.insert(html, '</div>') -- original-card-view
table.insert(html, '</div>') -- card-modal-inner
-- 其他视图
if subCardInfos and type(subCardInfos) == 'table' and #subCardInfos > 1 then
table.insert(html, p.renderSubcardsView(subCardInfos))
end
if cardInfo.hasInspiration and cardInfo.inspirationVariants and type(cardInfo.inspirationVariants) == 'table' and #cardInfo.inspirationVariants > 0 then
table.insert(html, '<div class="inspiration-view" style="display:none;position:absolute;top:0;left:0;width:100%;height:100%;flex-direction:column;align-items:center;justify-content:center;">')
table.insert(html, '<div class="back-to-card-button" style="position:fixed;top:20px;left:20px;z-index:10001;padding:10px 25px;background:linear-gradient(135deg,#ff6b6b 0%,#cc5555 100%);color:white;font-size:16px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">← 返回卡牌</div>')
table.insert(html, '<div style="color:white;font-size:24px;margin-bottom:20px;">灵光一闪</div>')
table.insert(html, '<div class="inspiration-cards-wrapper" style="display:flex;gap-right:0px;gap-left:15px;justify-content:center;flex-wrap:wrap;max-width:90vw;align-items:flex-start;">')
for i, variantInfo in ipairs(cardInfo.inspirationVariants) do
table.insert(html, p.renderInspirationVariant(variantInfo, i))
end
table.insert(html, '</div>')
table.insert(html, '</div>')
for i, variantInfo in ipairs(cardInfo.inspirationVariants) do
if variantInfo.subCards and type(variantInfo.subCards) == 'table' and #variantInfo.subCards > 0 then
table.insert(html, p.renderInspirationSubcardsView(variantInfo, i))
for j, subCardInfo in ipairs(variantInfo.subCards) do
if subCardInfo.subCards and type(subCardInfo.subCards) == 'table' and #subCardInfo.subCards > 0 then
table.insert(html, p.renderInspirationNestedSubcardsView(variantInfo, i, subCardInfo, j))
end
end
end
end
end
if cardInfo.hasGodInspiration and cardInfo.godInspirationGroups and cardInfo.godInspirationGroupOrder then
table.insert(html, '<div class="god-inspiration-view" style="display:none;position:absolute;top:0;left:0;width:100%;height:100%;flex-direction:column;align-items:center;justify-content:flex-start;padding-top:60px;">')
table.insert(html, '<div class="back-to-card-button" style="position:fixed;top:20px;left:20px;z-index:10001;padding:10px 25px;background:linear-gradient(135deg,#ff6b6b 0%,#cc5555 100%);color:white;font-size:16px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">← 返回卡牌</div>')
table.insert(html, '<div style="color:white;font-size:24px;margin-bottom:20px;">神光一闪</div>')
-- 第一行:前三组,每组3张卡牌
local firstRowGroups = {}
for i = 1, math.min(3, #cardInfo.godInspirationGroupOrder) do
table.insert(firstRowGroups, cardInfo.godInspirationGroupOrder[i])
end
if #firstRowGroups > 0 then
table.insert(html, '<div class="god-inspiration-row-1" style="display:flex;gap:30px;justify-content:center;margin-bottom:30px;flex-wrap:nowrap;">')
for _, groupName in ipairs(firstRowGroups) do
local groupList = cardInfo.godInspirationGroups[groupName]
if groupList and type(groupList) == 'table' and #groupList > 0 then
table.insert(html, '<div class="god-group" style="display:flex;flex-direction:column;align-items:center;">')
table.insert(html, '<div style="color:#ffd36a;font-size:18px;margin-bottom:10px;">' .. escText(groupName) .. '</div>')
table.insert(html, '<div style="display:flex;gap:10px;justify-content:center;">')
for _, variantInfo in ipairs(groupList) do
table.insert(html, p.renderGodVariantCardSmall(variantInfo))
end
table.insert(html, '</div>')
table.insert(html, '</div>')
end
end
table.insert(html, '</div>')
end
-- 第二行:后两组,每组3张卡牌
local secondRowGroups = {}
for i = 4, math.min(5, #cardInfo.godInspirationGroupOrder) do
table.insert(secondRowGroups, cardInfo.godInspirationGroupOrder[i])
end
if #secondRowGroups > 0 then
table.insert(html, '<div class="god-inspiration-row-2" style="display:flex;gap:30px;justify-content:center;flex-wrap:nowrap;">')
for _, groupName in ipairs(secondRowGroups) do
local groupList = cardInfo.godInspirationGroups[groupName]
if groupList and type(groupList) == 'table' and #groupList > 0 then
table.insert(html, '<div class="god-group" style="display:flex;flex-direction:column;align-items:center;">')
table.insert(html, '<div style="color:#ffd36a;font-size:18px;margin-bottom:10px;">' .. escText(groupName) .. '</div>')
table.insert(html, '<div style="display:flex;gap:10px;justify-content:center;">')
for _, variantInfo in ipairs(groupList) do
table.insert(html, p.renderGodVariantCardSmall(variantInfo))
end
table.insert(html, '</div>')
table.insert(html, '</div>')
end
end
table.insert(html, '</div>')
end
table.insert(html, '</div>')
end
-- 关闭最外层 modal
table.insert(html, '</div>')
return table.concat(html, '')
end
function p.renderSubcardsView(subCardInfos)
local html = {}
table.insert(html, '<div class="subcards-view" style="display:none;position:absolute;top:0;left:0;width:100%;height:100%;flex-direction:column;align-items:center;justify-content:center;">')
table.insert(html, '<div class="back-to-card-button" style="position:fixed;top:20px;left:20px;z-index:10001;padding:10px 25px;background:linear-gradient(135deg,#ff6b6b 0%,#cc5555 100%);color:white;font-size:16px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">← 返回卡牌</div>')
table.insert(html, '<div style="color:white;font-size:24px;margin-bottom:20px;">衍生卡牌</div>')
table.insert(html, '<div class="subcards-wrapper" style="display:flex;gap-right:0px;gap-left:15px;justify-content:center;flex-wrap:wrap;max-width:90vw;">')
for i, subCardInfo in ipairs(subCardInfos) do
table.insert(html, '<div style="display:flex;flex-direction:column;align-items:center;gap-right:0px;gap-left:15px;">')
table.insert(html, p.renderSubCard(subCardInfo))
if subCardInfo.subCards and type(subCardInfo.subCards) == 'table' and #subCardInfo.subCards > 0 then
table.insert(html, '<div class="view-nested-subcards-button" data-subcard-index="' .. i .. '" style="display:inline-block;padding:10px 20px;background:linear-gradient(135deg,#ffa500 0%,#cc8400 100%);color:white;font-size:15px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">查看衍生卡牌</div>')
end
table.insert(html, '</div>')
end
table.insert(html, '</div>')
table.insert(html, '</div>')
for i, subCardInfo in ipairs(subCardInfos) do
if subCardInfo.subCards and type(subCardInfo.subCards) == 'table' and #subCardInfo.subCards > 0 then
table.insert(html, p.renderNestedSubcardsView(subCardInfo, i))
end
end
return table.concat(html, '')
end
function p.renderNestedSubcardsView(parentCardInfo, parentIndex)
local html = {}
table.insert(html, '<div class="nested-subcards-view" data-subcard-index="' .. parentIndex .. '" style="display:none;position:absolute;top:0;left:0;width:100%;height:100%;flex-direction:column;align-items:center;justify-content:center;">')
table.insert(html, '<div class="back-to-subcards-button" style="position:fixed;top:20px;left:20px;z-index:10001;padding:10px 25px;background:linear-gradient(135deg,#ff6b6b 0%,#cc5555 100%);color:white;font-size:16px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">← 返回所有衍生</div>')
table.insert(html, '<div style="color:white;font-size:24px;margin-bottom:20px;">' .. escText(parentCardInfo.displayTitle or parentCardInfo.cardName) .. ' 的衍生卡牌</div>')
table.insert(html, '<div class="nested-subcards-wrapper" style="display:flex;gap-right:0px;gap-left:15px;justify-content:center;flex-wrap:wrap;max-width:90vw;">')
for _, nestedCardInfo in ipairs(parentCardInfo.subCards) do
table.insert(html, '<div style="display:flex;flex-direction:column;align-items:center;gap-right:0px;gap-left:15px;">')
table.insert(html, p.renderSubCard(nestedCardInfo))
table.insert(html, '</div>')
end
table.insert(html, '</div>')
table.insert(html, '</div>')
return table.concat(html, '')
end
function p.renderInspirationVariant(variantInfo, index)
local html = {}
local dictDisplay = dictSpanFromTokens(variantInfo.dictTokens, variantInfo.dictColor)
local apDisplay = variantInfo.apText or ''
local nameColor = rarityNameColor(variantInfo.rarity)
local isAbnormal = (variantInfo.cardType == "状态异常")
local isSkill = (variantInfo.group == "自我意识技能")
table.insert(html, '<div class="inspiration-variant" style="display:flex;flex-direction:column;align-items:center;gap:8px;width:270px;">')
if isSkill then
-- 自我意识技能中卡牌
table.insert(html, '<div class="inspiration-variant-card" style="display:inline-block;vertical-align:top;position:relative;width:254px;height:390px;overflow:hidden;">')
table.insert(html, renderSkillCardLayersMedium(variantInfo))
table.insert(html, '<div style="position:absolute;top:135px;left:36px;z-index:10;font-size:24px;color:white">' .. escText(variantInfo.displayTitle or variantInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;top:162px;left:33px;z-index:10;">[[File:icon_tp_skill_type_awaken.png|30px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:167px;left:63px;z-index:10;font-size:20px;color:white">自我意识技能</div>')
table.insert(html, '<div style="position:absolute;top:198px;left:33px;width:212px;height:2px;background-color:rgba(255,255,255);z-index:10;"></div>')
local apNum = tonumber(apDisplay) or 0
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:10;">[[File:card_skill_ap_' .. apNum .. '.png|254px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">')
local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. inspContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
elseif isAbnormal then
-- 状态异常中卡牌
table.insert(html, '<div class="inspiration-variant-card" style="display:inline-block;vertical-align:top;position:relative;width:269px;height:395px;overflow:hidden;">')
table.insert(html, renderAbnormalCardLayersMedium(variantInfo))
table.insert(html, renderApDiv(apDisplay, '23px', '38px', '57px', variantInfo.apStyle or 'blue'))
table.insert(html, '<div style="position:absolute;z-index:10;top:30px;left:75px;width:173px;font-size:32px;color:' .. nameColor .. '">' .. escText(variantInfo.displayTitleShort or variantInfo.displayTitle or variantInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:72px;left:72px;">[[File:card_type_' .. escFile(variantInfo.cardType) .. '.png|24px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:71px;left:99px;font-size:18px;color:white">状态异常</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">')
local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. inspContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
else
-- 普通中卡牌
table.insert(html, '<div class="inspiration-variant-card" style="display:inline-block;vertical-align:top;position:relative;width:275px;height:386px;overflow:hidden;">')
-- 立绘层
table.insert(html, '<div style="position:absolute;top:3px;left:22px;z-index:0;">[[File:' .. escFile(variantInfo.art) .. '|246px|link=]]</div>')
-- 黑色蒙版
table.insert(html, '<div style="position:absolute;top:1px;left:3px;z-index:1;">[[File:card_黑色蒙版.png|269px|link=]]</div>')
-- 标题背景条
local barBg = rarityBarColor(variantInfo.rarity)
table.insert(html, '<div style="position:absolute;top:54px;left:23px;width:246px;height:14px;background:' .. barBg .. ';z-index:2;"></div>')
-- EGO框架
table.insert(html, '<div style="position:absolute;top:0px;left:2px;z-index:3;">[[File:card_ego_' .. escFile(variantInfo.ego) .. '.png|269px|link=]]</div>')
-- 稀有度标识
table.insert(html, '<div style="position:absolute;top:43px;left:2px;z-index:4;">[[File:card_rarity_' .. escFile(variantInfo.rarity) .. '.png|31px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:45px;right:0px;z-index:4;">[[File:card_rarity_' .. escFile(variantInfo.rarity) .. '_sub.png|15px|link=]]</div>')
-- 能量线
table.insert(html, '<div style="position:absolute;top:84px;left:30px;z-index:5;">[[File:energy_line_蓝.png|38px|link=]]</div>')
-- AP显示
table.insert(html, renderApDiv(apDisplay, '35px', '38px', '57px', variantInfo.apStyle or 'blue'))
-- 名称
table.insert(html, '<div style="position:absolute;z-index:10;top:45px;left:75px;width:173px;font-size:28px;color:' .. nameColor .. '">' .. escText(variantInfo.displayTitleShort or variantInfo.displayTitle or variantInfo.cardName) .. '</div>')
-- 类型图标和文字
table.insert(html, '<div style="position:absolute;z-index:10;top:76px;left:72px;">[[File:card_type_' .. escFile(variantInfo.cardType) .. '.png|24px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:76px;left:99px;font-size:18px;color:white">' .. escText(variantInfo.cardType) .. '</div>')
-- 描述
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:28px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">')
local inspContent = expandWikitext((dictDisplay or '') .. (variantInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. inspContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
end
-- 如果该变体有衍生卡牌,提供查看按钮
if variantInfo.subCards and type(variantInfo.subCards) == 'table' and #variantInfo.subCards > 0 and index and index > 0 then
table.insert(html, '<div class="view-insp-subcards-button" data-variant-index="' .. tostring(index) .. '" style="display:inline-block;padding:8px 12px;background:linear-gradient(135deg,#ffa500 0%,#cc8400 100%);color:white;font-size:14px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">查看衍生卡牌</div>')
end
table.insert(html, '</div>')
return table.concat(html, '')
end
function p.renderGodVariantCardSmall(variantInfo)
local html = {}
local dictDisplay = dictSpanFromTokens(variantInfo.dictTokens, variantInfo.dictColor)
local apDisplay = variantInfo.apText or ''
local nameColor = rarityNameColor(variantInfo.rarity)
local isAbnormal = (variantInfo.cardType == "状态异常")
local isSkill = (variantInfo.group == "自我意识技能")
table.insert(html, '<div class="god-variant-card" style="display:flex;flex-direction:column;align-items:center;gap:8px;width:270px;">')
if isSkill then
-- 自我意识技能中卡
table.insert(html, '<div class="god-variant-card-inner" style="display:inline-block;vertical-align:top;position:relative;width:254px;height:390px;overflow:hidden;">')
table.insert(html, renderSkillCardLayersMedium(variantInfo))
table.insert(html, '<div style="position:absolute;top:135px;left:36px;z-index:10;font-size:24px;color:white">' .. escText(variantInfo.displayTitle or variantInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;top:162px;left:33px;z-index:10;">[[File:icon_tp_skill_type_awaken.png|30px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:167px;left:63px;z-index:10;font-size:20px;color:white">自我意识技能</div>')
table.insert(html, '<div style="position:absolute;top:198px;left:33px;width:212px;height:2px;background-color:rgba(255,255,255);z-index:10;"></div>')
local apNum = tonumber(apDisplay) or 0
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:10;">[[File:card_skill_ap_' .. apNum .. '.png|254px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">')
local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. content .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
elseif isAbnormal then
-- 状态异常中卡
table.insert(html, '<div class="god-variant-card-inner" style="display:inline-block;vertical-align:top;position:relative;width:269px;height:395px;overflow:hidden;">')
table.insert(html, renderAbnormalCardLayersMedium(variantInfo))
table.insert(html, renderApDiv(apDisplay, '23px', '38px', '57px', variantInfo.apStyle or 'blue'))
table.insert(html, '<div style="position:absolute;z-index:10;top:30px;left:75px;width:173px;font-size:32px;color:' .. nameColor .. '">' .. escText(variantInfo.displayTitleShort or variantInfo.displayTitle or variantInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:72px;left:72px;">[[File:card_type_' .. escFile(variantInfo.cardType) .. '.png|24px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:71px;left:99px;font-size:18px;color:white">状态异常</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">')
local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. content .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
else
-- 普通中卡
table.insert(html, '<div class="god-variant-card-inner" style="display:inline-block;vertical-align:top;position:relative;width:275px;height:386px;overflow:hidden;">')
-- 立绘层
table.insert(html, '<div style="position:absolute;top:3px;left:22px;z-index:0;">[[File:' .. escFile(variantInfo.art) .. '|246px|link=]]</div>')
-- 黑色蒙版
table.insert(html, '<div style="position:absolute;top:1px;left:3px;z-index:1;">[[File:card_黑色蒙版.png|269px|link=]]</div>')
-- 标题背景条
local barBg = rarityBarColor(variantInfo.rarity)
table.insert(html, '<div style="position:absolute;top:55px;left:23px;width:245px;height:14px;background:' .. barBg .. ';z-index:2;"></div>')
-- EGO框架
table.insert(html, '<div style="position:absolute;top:0px;left:2px;z-index:3;">[[File:card_ego_' .. escFile(variantInfo.ego) .. '.png|269px|link=]]</div>')
-- 稀有度标识
table.insert(html, '<div style="position:absolute;top:43px;left:2px;z-index:4;">[[File:card_rarity_' .. escFile(variantInfo.rarity) .. '.png|31px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:45px;right:0px;z-index:4;">[[File:card_rarity_' .. escFile(variantInfo.rarity) .. '_sub.png|15px|link=]]</div>')
-- 能量线
table.insert(html, '<div style="position:absolute;top:86px;left:30px;z-index:5;">[[File:energy_line_蓝.png|38px|link=]]</div>')
-- AP显示
table.insert(html, renderApDiv(apDisplay, '37px', '38px', '57px', variantInfo.apStyle or 'blue'))
-- 名称
table.insert(html, '<div style="position:absolute;z-index:10;top:45px;left:75px;width:173px;font-size:28px;color:' .. nameColor .. '">' .. escText(variantInfo.displayTitleShort or variantInfo.displayTitle or variantInfo.cardName) .. '</div>')
-- 类型图标和文字
table.insert(html, '<div style="position:absolute;z-index:10;top:76px;left:72px;">[[File:card_type_' .. escFile(variantInfo.cardType) .. '.png|24px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:78px;left:99px;font-size:18px;color:white">' .. escText(variantInfo.cardType) .. '</div>')
-- 描述
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:30px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">')
local content = expandWikitext((dictDisplay or '') .. (variantInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. content .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
end
table.insert(html, '</div>')
return table.concat(html, '')
end
function p.renderInspirationSubcardsView(variantInfo, variantIndex)
local html = {}
table.insert(html, '<div class="inspiration-subcards-view" data-variant-index="' .. tostring(variantIndex) .. '" style="display:none;position:absolute;top:0;left:0;width:100%;height:100%;flex-direction:column;align-items:center;justify-content:center;">')
table.insert(html, '<div class="back-to-inspiration-button" style="position:fixed;top:20px;left:20px;z-index:10001;padding:10px 25px;background:linear-gradient(135deg,#ff6b6b 0%,#cc5555 100%);color:white;font-size:16px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">← 返回灵光一闪</div>')
table.insert(html, '<div style="color:white;font-size:24px;margin-bottom:20px;">衍生卡牌</div>')
table.insert(html, '<div class="inspiration-subcards-wrapper" style="display:flex;gap-right:0px;gap-left:15px;justify-content:center;flex-wrap:wrap;max-width:90vw;">')
for j, subCardInfo in ipairs(variantInfo.subCards) do
table.insert(html, '<div style="display:flex;flex-direction:column;align-items:center;gap-right:0px;gap-left:15px;">')
table.insert(html, p.renderSubCard(subCardInfo))
if subCardInfo.subCards and type(subCardInfo.subCards) == 'table' and #subCardInfo.subCards > 0 then
table.insert(html, '<div class="view-insp-nested-subcards-button" data-variant-index="' .. tostring(variantIndex) .. '" data-subcard-index="' .. tostring(j) .. '" style="display:inline-block;padding:8px 15px;background:linear-gradient(135deg,#ffa500 0%,#cc8400 100%);color:white;font-size:14px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">查看衍生卡牌</div>')
end
table.insert(html, '</div>')
end
table.insert(html, '</div>')
table.insert(html, '</div>')
return table.concat(html, '')
end
function p.renderInspirationNestedSubcardsView(variantInfo, variantIndex, subCardInfo, subCardIndex)
local html = {}
table.insert(html, '<div class="inspiration-nested-subcards-view" data-variant-index="' .. tostring(variantIndex) .. '" data-subcard-index="' .. tostring(subCardIndex) .. '" style="display:none;position:absolute;top:0;left:0;width:100%;height:100%;flex-direction:column;align-items:center;justify-content:center;">')
table.insert(html, '<div class="back-to-insp-subcards-button" data-variant-index="' .. tostring(variantIndex) .. '" style="position:fixed;top:20px;left:20px;z-index:10001;padding:10px 25px;background:linear-gradient(135deg,#ff6b6b 0%,#cc5555 100%);color:white;font-size:16px;font-weight:bold;border-radius:8px;cursor:pointer;box-shadow:0 4px 6px rgba(0,0,0,0.3);transition:all 0.3s;user-select:none;">← 返回所有衍生</div>')
table.insert(html, '<div style="color:white;font-size:24px;margin-bottom:20px;">' .. escText(subCardInfo.displayTitle or subCardInfo.cardName) .. ' 的衍生卡牌</div>')
table.insert(html, '<div class="inspiration-nested-subcards-wrapper" style="display:flex;gap-right:0px;gap-left:15px;justify-content:center;flex-wrap:wrap;max-width:90vw;">')
for _, nestedCardInfo in ipairs(subCardInfo.subCards) do
table.insert(html, '<div style="display:flex;flex-direction:column;align-items:center;gap-right:0px;gap-left:15px;">')
table.insert(html, p.renderSubCard(nestedCardInfo))
table.insert(html, '</div>')
end
table.insert(html, '</div>')
table.insert(html, '</div>')
return table.concat(html, '')
end
function p.renderSubCard(subInfo)
local html = {}
local dictDisplay = dictSpanFromTokens(subInfo.dictTokens, subInfo.dictColor)
local apDisplay = subInfo.apText or ''
local nameColor = rarityNameColor(subInfo.rarity)
local isAbnormal = (subInfo.cardType == "状态异常")
local isSkill = (subInfo.group == "自我意识技能")
if isSkill then
-- 自我意识技能中卡牌
table.insert(html, '<div class="subcard" style="display:inline-block;vertical-align:top;position:relative;width:254px;height:390px;overflow:hidden;">')
table.insert(html, renderSkillCardLayersMedium(subInfo))
table.insert(html, '<div style="position:absolute;top:135px;left:36px;z-index:10;font-size:24px;color:white">' .. escText(subInfo.displayTitle or subInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;top:162px;left:33px;z-index:10;">[[File:icon_tp_skill_type_awaken.png|30px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:167px;left:63px;z-index:10;font-size:20px;color:white">自我意识技能</div>')
table.insert(html, '<div style="position:absolute;top:198px;left:33px;width:212px;height:2px;background-color:rgba(255,255,255);z-index:10;"></div>')
local apNum = tonumber(apDisplay) or 0
table.insert(html, '<div style="position:absolute;top:0px;left:0px;z-index:10;">[[File:card_skill_ap_' .. apNum .. '.png|254px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:210px;left:30px;width:218px;height:158px;color:white;text-align:center;font-size:20px;line-height:23px;z-index:10;">')
local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. subContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
elseif isAbnormal then
-- 状态异常中卡牌
table.insert(html, '<div class="subcard" style="display:inline-block;vertical-align:top;position:relative;width:269px;height:395px;overflow:hidden;">')
table.insert(html, renderAbnormalCardLayersMedium(subInfo))
table.insert(html, renderApDiv(apDisplay, '23px', '38px', '57px', subInfo.apStyle or 'blue'))
table.insert(html, '<div style="position:absolute;z-index:10;top:30px;left:75px;width:173px;font-size:32px;color:' .. nameColor .. '">' .. escText(subInfo.displayTitleShort or subInfo.displayTitle or subInfo.cardName) .. '</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:72px;left:72px;">[[File:card_type_' .. escFile(subInfo.cardType) .. '.png|24px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:71px;left:99px;font-size:18px;color:white">状态异常</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:18px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px;">')
local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. subContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
else
-- 普通中卡牌
table.insert(html, '<div class="subcard" style="display:inline-block;vertical-align:top;position:relative;width:275px;height:386px;overflow:hidden;">')
-- 立绘层
table.insert(html, '<div style="position:absolute;top:3px;left:22px;z-index:0;">[[File:' .. escFile(subInfo.art) .. '|246px|link=]]</div>')
-- 黑色蒙版
table.insert(html, '<div style="position:absolute;top:1px;left:3px;z-index:1;">[[File:card_黑色蒙版.png|269px|link=]]</div>')
-- 标题背景条
local barBg = rarityBarColor(subInfo.rarity)
table.insert(html, '<div style="position:absolute;top:54px;left:23px;width:246px;height:14px;background:' .. barBg .. ';z-index:2;"></div>')
-- EGO框架
table.insert(html, '<div style="position:absolute;top:0px;left:2px;z-index:3;">[[File:card_ego_' .. escFile(subInfo.ego) .. '.png|269px|link=]]</div>')
-- 稀有度标识
table.insert(html, '<div style="position:absolute;top:43px;left:2px;z-index:4;">[[File:card_rarity_' .. escFile(subInfo.rarity) .. '.png|31px|link=]]</div>')
table.insert(html, '<div style="position:absolute;top:45px;right:0px;z-index:4;">[[File:card_rarity_' .. escFile(subInfo.rarity) .. '_sub.png|15px|link=]]</div>')
-- 能量线
table.insert(html, '<div style="position:absolute;top:86px;left:30px;z-index:5;">[[File:energy_line_蓝.png|38px|link=]]</div>')
-- AP显示
table.insert(html, renderApDiv(apDisplay, '35px', '38px', '57px', subInfo.apStyle or 'blue'))
-- 名称
table.insert(html, '<div style="position:absolute;z-index:10;top:42px;left:70px;width:173px;font-size:32px;color:' .. nameColor .. '">' .. escText(subInfo.displayTitleShort or subInfo.displayTitle or subInfo.cardName) .. '</div>')
-- 类型图标和文字
table.insert(html, '<div style="position:absolute;z-index:10;top:78px;left:70px;">[[File:card_type_' .. escFile(subInfo.cardType) .. '.png|24px|link=]]</div>')
table.insert(html, '<div style="position:absolute;z-index:10;top:78px;left:98px;font-size:20px;color:white">' .. escText(subInfo.cardType) .. '</div>')
-- 描述
table.insert(html, '<div style="position:absolute;z-index:10;top:210px;left:28px;width:233px;height:165px;color:white;text-align:center;font-size:20px;line-height:23px; display: flex; align-items: center; justify-content: center;">')
local subContent = expandWikitext((dictDisplay or '') .. (subInfo.desc or ''))
table.insert(html, '<div class="scroll-text"><div class="scroll-text-content">' .. subContent .. '</div></div>')
table.insert(html, '</div>')
table.insert(html, '</div>')
end
return table.concat(html, '')
end
return p