support wrapped recharge reward slots
This commit is contained in:
parent
f888682c13
commit
196438b02c
@ -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]);
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user