diff --git a/h5/activity/recharge/index.html b/h5/activity/recharge/index.html
index c0dea65..93b7ee5 100644
--- a/h5/activity/recharge/index.html
+++ b/h5/activity/recharge/index.html
@@ -765,6 +765,13 @@
var LEVEL_GAP = 814;
var LEVEL_PANEL_HEIGHT = 618;
var LEVEL_BOTTOM_PADDING = 57;
+ var REWARD_COLUMNS = 3;
+ var REWARD_ROW_GAP = 330;
+ var REWARD_FRAME_LEFTS = {
+ 1: [420],
+ 2: [269, 571],
+ 3: [118, 420, 722],
+ };
var query = buildPageQueryParams();
var countdownTimer = null;
var countdownEndsAt = 0;
@@ -1024,22 +1031,68 @@
});
}
- function setCanvasHeight(levelCount) {
- var count = Math.max(0, Number(levelCount) || 0);
- var height = count > 0
- ? LEVEL_PANEL_TOP + ((count - 1) * LEVEL_GAP) + LEVEL_PANEL_HEIGHT + LEVEL_BOTTOM_PADDING
+ function layoutPanel(panel, panelHeight) {
+ if (!panel) return;
+ panel.style.height = panelHeight + "px";
+ var middleHeight = Math.max(0, panelHeight - 382);
+ var middles = Array.prototype.slice.call(panel.querySelectorAll(".panel-middle"));
+ var middle = middles[0];
+ if (middle) {
+ middle.classList.remove("is-hidden");
+ middle.style.top = "191px";
+ middle.style.height = middleHeight + "px";
+ }
+ middles.slice(1).forEach(function (node) {
+ node.classList.add("is-hidden");
+ });
+ var bottom = panel.querySelector(".panel-edge.bottom");
+ if (bottom) bottom.style.top = (panelHeight - 191) + "px";
+ }
+
+ function rewardRowCount(level) {
+ var rewardCount = levelRewards(level).length;
+ return Math.max(1, Math.ceil(rewardCount / REWARD_COLUMNS));
+ }
+
+ function rewardExtraHeight(rowCount) {
+ return Math.max(0, Number(rowCount || 1) - 1) * REWARD_ROW_GAP;
+ }
+
+ function buildLevelLayouts(levels) {
+ var offset = 0;
+ return levels.map(function (level) {
+ var rowCount = rewardRowCount(level);
+ var layout = {
+ offset: offset,
+ rowCount: rowCount,
+ panelHeight: LEVEL_PANEL_HEIGHT + rewardExtraHeight(rowCount),
+ };
+ offset += LEVEL_GAP + rewardExtraHeight(rowCount);
+ return layout;
+ });
+ }
+
+ function setCanvasHeight(layouts) {
+ var count = Array.isArray(layouts) ? layouts.length : 0;
+ var last = count > 0 ? layouts[count - 1] : null;
+ var height = last
+ ? LEVEL_PANEL_TOP + last.offset + last.panelHeight + LEVEL_BOTTOM_PADDING
: LEVEL_BASE_HEIGHT;
document.documentElement.style.setProperty("--canvas-height", height + "px");
}
- function layoutLevelSection(section, index) {
+ function layoutLevelSection(section, index, layout) {
if (!section) return;
- var offset = index * LEVEL_GAP;
+ var offset = layout ? layout.offset : index * LEVEL_GAP;
+ var panelHeight = layout ? layout.panelHeight : LEVEL_PANEL_HEIGHT;
+ var rowCount = layout ? layout.rowCount : 1;
section.setAttribute("data-level-section", String(index));
+ section.setAttribute("data-level-offset", String(offset));
+ section.setAttribute("data-level-row-count", String(rowCount));
section.setAttribute("aria-label", "Recharge level " + (index + 1));
var panel = firstLevelPanel(section);
setTop(panel, LEVEL_PANEL_TOP + offset);
- if (panel) panel.style.height = LEVEL_PANEL_HEIGHT + "px";
+ layoutPanel(panel, panelHeight);
setTop(section.querySelector(".section-badge"), LEVEL_BADGE_TOP + offset);
setTop(section.querySelector("[data-level-title]"), LEVEL_TITLE_TOP + offset);
Array.prototype.slice.call(section.querySelectorAll("[data-level-frame]")).forEach(function (node) {
@@ -1053,8 +1106,9 @@
});
}
- function ensureLevelSections(levelCount) {
- var targetCount = Math.max(0, Number(levelCount) || 0);
+ function ensureLevelSections(levels) {
+ var targetCount = Array.isArray(levels) ? levels.length : Math.max(0, Number(levels) || 0);
+ var layouts = Array.isArray(levels) ? buildLevelLayouts(levels) : [];
var sections = Array.prototype.slice.call(document.querySelectorAll("[data-level-section]"));
var template = sections[0];
if (!template) return [];
@@ -1064,14 +1118,71 @@
sections.push(next);
}
sections.forEach(function (section, index) {
- layoutLevelSection(section, index);
+ layoutLevelSection(section, index, layouts[index]);
section.classList.toggle("is-hidden", index >= targetCount);
});
- setCanvasHeight(targetCount);
+ setCanvasHeight(layouts);
els.sections = sections;
return sections;
}
+ function ensureRewardSlots(section, rewardCount) {
+ var targetCount = Math.max(0, Number(rewardCount) || 0);
+ var frames = Array.prototype.slice.call(section.querySelectorAll("[data-level-frame]"));
+ var images = Array.prototype.slice.call(section.querySelectorAll("[data-reward-image]"));
+ var prices = Array.prototype.slice.call(section.querySelectorAll(".reward-price"));
+ var frameTemplate = frames[0];
+ var imageTemplate = images[0];
+ var priceTemplate = prices[0];
+
+ while (frames.length < targetCount && frameTemplate) {
+ var frame = frameTemplate.cloneNode(true);
+ frame.setAttribute("data-level-frame", String(frames.length));
+ section.appendChild(frame);
+ frames.push(frame);
+ }
+ while (images.length < targetCount && imageTemplate) {
+ var image = imageTemplate.cloneNode(true);
+ image.setAttribute("data-reward-image", String(images.length));
+ section.appendChild(image);
+ images.push(image);
+ }
+ while (prices.length < targetCount && priceTemplate) {
+ var price = priceTemplate.cloneNode(true);
+ var label = price.querySelector("[data-reward-label]");
+ if (label) label.setAttribute("data-reward-label", String(prices.length));
+ section.appendChild(price);
+ prices.push(price);
+ }
+ }
+
+ function rewardFrameLeft(rowSize, slotIndex) {
+ var positions = REWARD_FRAME_LEFTS[Math.max(1, Math.min(REWARD_COLUMNS, rowSize))] || REWARD_FRAME_LEFTS[3];
+ return positions[Math.max(0, Math.min(slotIndex, positions.length - 1))];
+ }
+
+ function positionRewardNodes(section, index, totalRewards, nodes) {
+ var offset = Number(section.getAttribute("data-level-offset") || 0);
+ var rowIndex = Math.floor(index / REWARD_COLUMNS);
+ var rowStart = rowIndex * REWARD_COLUMNS;
+ var rowSize = Math.min(REWARD_COLUMNS, totalRewards - rowStart);
+ var slotIndex = index - rowStart;
+ var frameLeft = rewardFrameLeft(rowSize, slotIndex);
+ var rowOffset = rowIndex * REWARD_ROW_GAP;
+ if (nodes.frame) {
+ nodes.frame.style.left = frameLeft + "px";
+ setTop(nodes.frame, LEVEL_FRAME_TOP + offset + rowOffset);
+ }
+ if (nodes.image) {
+ nodes.image.style.left = (frameLeft + 20) + "px";
+ setTop(nodes.image, LEVEL_ICON_TOP + offset + rowOffset);
+ }
+ if (nodes.price) {
+ nodes.price.style.left = (frameLeft - 22) + "px";
+ setTop(nodes.price, LEVEL_PRICE_TOP + offset + rowOffset);
+ }
+ }
+
function renderLevel(section, level) {
if (!section) return;
if (!level) {
@@ -1082,6 +1193,7 @@
var title = section.querySelector("[data-level-title]");
if (title) title.textContent = "Recharge $" + formatAmountCents(centsValue(level));
var rewards = levelRewards(level);
+ ensureRewardSlots(section, rewards.length);
var images = Array.prototype.slice.call(section.querySelectorAll("[data-reward-image]"));
var labels = Array.prototype.slice.call(section.querySelectorAll("[data-reward-label]"));
var frames = Array.prototype.slice.call(section.querySelectorAll("[data-level-frame]"));
@@ -1093,6 +1205,11 @@
if (node) node.classList.toggle("is-hidden", !reward);
});
if (!reward) continue;
+ positionRewardNodes(section, i, rewards.length, {
+ frame: frames[i],
+ image: images[i],
+ price: prices[i],
+ });
setImage(images[i], reward.cover, DEFAULT_REWARD_ICON);
if (labels[i]) labels[i].textContent = rewardLabel(reward);
}
@@ -1111,7 +1228,7 @@
startCountdown(body.countdownMillis);
var levels = normalizeLevels(body.levelConfigs);
if (Array.isArray(body.levelConfigs)) {
- ensureLevelSections(levels.length).forEach(function (section, index) {
+ ensureLevelSections(levels).forEach(function (section, index) {
renderLevel(section, levels[index]);
});
}