minigame 4 font table question
This commit is contained in:
+33
-1
@@ -520,11 +520,26 @@
|
||||
var bw = bwEl ? parseInt(String(bwEl.value || '2'), 10) : 2;
|
||||
if (!Number.isFinite(bw)) bw = 2;
|
||||
bw = Math.max(0, Math.min(12, Math.round(bw)));
|
||||
var qfMinEl = el('quiz-carry-theme-qfont-min');
|
||||
var qfMaxEl = el('quiz-carry-theme-qfont-max');
|
||||
var qMin = qfMinEl ? parseInt(String(qfMinEl.value || '10'), 10) : 10;
|
||||
var qMax = qfMaxEl ? parseInt(String(qfMaxEl.value || '24'), 10) : 24;
|
||||
if (!Number.isFinite(qMin)) qMin = 10;
|
||||
if (!Number.isFinite(qMax)) qMax = 24;
|
||||
qMin = Math.max(10, Math.min(40, Math.round(qMin)));
|
||||
qMax = Math.max(14, Math.min(56, Math.round(qMax)));
|
||||
if (qMax < qMin) {
|
||||
var swap = qMin;
|
||||
qMin = qMax;
|
||||
qMax = swap;
|
||||
}
|
||||
return {
|
||||
panelBg: (sBg && sBg.trim()) ? sBg.trim().slice(0, 120) : quizCarryRgbToRgbaString(fbBg),
|
||||
panelBorder: (sBr && sBr.trim()) ? sBr.trim().slice(0, 120) : quizCarryRgbToRgbaString(fbBr),
|
||||
textColor: (sTx && sTx.trim()) ? sTx.trim().slice(0, 120) : quizCarryRgbToRgbaString(fbTx),
|
||||
borderWidthPx: bw,
|
||||
questionFontMinPx: qMin,
|
||||
questionFontMaxPx: qMax,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1223,7 +1238,14 @@
|
||||
gameQuizFetch('GET').then(function (data) {
|
||||
if (opts.themeOverride && typeof opts.themeOverride === 'object') {
|
||||
var ov = opts.themeOverride;
|
||||
if (ov.panelBg != null || ov.borderWidthPx != null || ov.panelBorder != null || ov.textColor != null) {
|
||||
if (
|
||||
ov.panelBg != null ||
|
||||
ov.borderWidthPx != null ||
|
||||
ov.panelBorder != null ||
|
||||
ov.textColor != null ||
|
||||
ov.questionFontMinPx != null ||
|
||||
ov.questionFontMaxPx != null
|
||||
) {
|
||||
data.carryMapPanelTheme = ov;
|
||||
} else if (ov.carryMapPanelTheme && typeof ov.carryMapPanelTheme === 'object') {
|
||||
data.carryMapPanelTheme = ov.carryMapPanelTheme;
|
||||
@@ -1279,6 +1301,16 @@
|
||||
var bw = parseInt(String(th.borderWidthPx), 10);
|
||||
bwInp.value = String(Number.isFinite(bw) && bw >= 0 ? Math.min(12, bw) : 2);
|
||||
}
|
||||
var qfMinInp = el('quiz-carry-theme-qfont-min');
|
||||
var qfMaxInp = el('quiz-carry-theme-qfont-max');
|
||||
if (qfMinInp) {
|
||||
var qm = parseInt(String(th.questionFontMinPx), 10);
|
||||
qfMinInp.value = String(Number.isFinite(qm) ? Math.max(10, Math.min(40, qm)) : 10);
|
||||
}
|
||||
if (qfMaxInp) {
|
||||
var qx = parseInt(String(th.questionFontMaxPx), 10);
|
||||
qfMaxInp.value = String(Number.isFinite(qx) ? Math.max(14, Math.min(56, qx)) : 24);
|
||||
}
|
||||
quizCarryEcdFillForm(data.carryEmbedCountdownTheme || {});
|
||||
quizCarryPlaqueFillAllFromApi(data);
|
||||
if (opts.clearMsg !== false) setMsg('quiz-carry-settings-msg', '', '');
|
||||
|
||||
@@ -226,6 +226,15 @@
|
||||
</div>
|
||||
<input type="hidden" id="quiz-carry-theme-text" value="" />
|
||||
</div>
|
||||
<div class="quiz-carry-theme-row quiz-carry-theme-row--narrow" style="flex-wrap:wrap;gap:0.75rem 1.25rem;align-items:flex-end">
|
||||
<label class="admin-field quiz-carry-theme-label">ขั้นต่ำ (px)
|
||||
<input type="number" id="quiz-carry-theme-qfont-min" class="admin-inp-num" min="10" max="40" step="1" value="10" title="ขั้นต่ำ px หลังสูตรเดียวกับป้ายคำตอบ" aria-describedby="quiz-carry-theme-qfont-hint" />
|
||||
</label>
|
||||
<label class="admin-field quiz-carry-theme-label">เพดานขนาด (px)
|
||||
<input type="number" id="quiz-carry-theme-qfont-max" class="admin-inp-num" min="14" max="56" step="1" value="24" title="เพดาน px (ค่าเริ่ม 24 = เหมือนป้ายคำตอบ)" />
|
||||
</label>
|
||||
</div>
|
||||
<p id="quiz-carry-theme-qfont-hint" class="muted" style="margin:-0.25rem 0 0;font-size:0.78rem;line-height:1.45">ในเกมใช้<strong>สูตรเดียวกับป้ายคำตอบบนพื้น</strong>: <code>clamp(10, 24, tileSize×zoom×0.24×carryChoicePlaqueMapScale)</code> แล้ว clamp อีกชั้นด้วยค่าสองช่องนี้ · <em>English:</em> Same px formula as floor answer plaques; theme min/max clamp on top.</p>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="quiz-carry-theme-fieldset" style="margin:0.75rem 0 1rem;padding:0.75rem 1rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-elevated)">
|
||||
@@ -661,6 +670,6 @@
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<script src="admin.js?v=47"></script>
|
||||
<script src="admin.js?v=51"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
"panelBg": "rgba(255, 0, 0, 0)",
|
||||
"panelBorder": "rgba(255, 255, 255, 0)",
|
||||
"textColor": "rgba(241, 245, 249, 1)",
|
||||
"borderWidthPx": 0
|
||||
"borderWidthPx": 0,
|
||||
"questionFontMinPx": 10,
|
||||
"questionFontMaxPx": 24
|
||||
},
|
||||
"carryEmbedCountdownTheme": {
|
||||
"overlayBackdrop": "rgba(8, 10, 20, 0.42)",
|
||||
"innerBg": "rgba(12, 14, 28, 0.82)",
|
||||
"overlayBackdrop": "rgba(8, 10, 20, 0)",
|
||||
"innerBg": "rgba(12, 14, 28, 0)",
|
||||
"innerBorder": "rgba(122, 162, 247, 0.45)",
|
||||
"innerBorderWpx": 1,
|
||||
"innerRadiusPx": 12,
|
||||
|
||||
+153
-28
@@ -406,17 +406,10 @@
|
||||
for (let li = 0; li < PLAY_LAYER_ORDER.length; li++) {
|
||||
const layerName = PLAY_LAYER_ORDER[li];
|
||||
if (diskLayers && layerName !== 'shadow' && !diskLayers.has(layerName)) continue;
|
||||
/* ห้าม fallback face จากทิศ down เมื่อเป็น up/left/right — จะได้ตาอยู่หลังหัวเพราะวางหน้าหน้าบนร่างหันหลัง */
|
||||
const urls = layerName === 'shadow'
|
||||
? shadowUrlCandidates(id, dir, frameIndex)
|
||||
: (layerName === 'face' && dir !== 'down'
|
||||
? (() => {
|
||||
const u = layerUrlCandidates(id, dir, layerName, frameIndex);
|
||||
layerUrlCandidates(id, 'down', layerName, frameIndex).forEach((x) => {
|
||||
if (u.indexOf(x) === -1) u.push(x);
|
||||
});
|
||||
return u;
|
||||
})()
|
||||
: layerUrlCandidates(id, dir, layerName, frameIndex));
|
||||
: layerUrlCandidates(id, dir, layerName, frameIndex);
|
||||
const r = resolvePlayLayerImage(urls);
|
||||
/* เงาโหลดช้า/404 บ่อย — อย่าให้บล็อกทั้งคอมโพส (ไม่งั้นตกไป fallback แถบแนวตั้งแทนเลเยอร์จริง) */
|
||||
if (r.status === 'pending' && layerName === 'shadow') {
|
||||
@@ -446,8 +439,8 @@
|
||||
/* เหมือนเดิม: มีเลเยอร์แยกไฟล์เมื่อ API บอก hasLayerFiles หรือ probe เจอ — gen สีทำบน canvas จาก *_layer_* เท่านั้น */
|
||||
const charHasLayerFiles = apiFlag === true
|
||||
|| (apiFlag == null && playCharAnyDirectionLayered(characterId));
|
||||
/* ct2: ยกเลิก composite เก่าที่เคย cache จาก fallback ย้อมทั้งสไปรต์ */
|
||||
const cacheKey = [characterId, dir, frameIndex, tint.head, tint.hair, tint.body, 'ct2'].join('|');
|
||||
/* ct3: ไม่ใช้ face จาก down บนทิศอื่น (แก้ตาหลังหัว) */
|
||||
const cacheKey = [characterId, dir, frameIndex, tint.head, tint.hair, tint.body, 'ct3'].join('|');
|
||||
const hit = playLayerCompositeCache.get(cacheKey);
|
||||
if (hit) return hit;
|
||||
|
||||
@@ -810,6 +803,12 @@
|
||||
textEl.style.removeProperty('--qmap-text-shadow');
|
||||
textEl.style.removeProperty('color');
|
||||
textEl.style.removeProperty('text-shadow');
|
||||
textEl.style.removeProperty('font-size');
|
||||
textEl.style.removeProperty('line-height');
|
||||
textEl.style.removeProperty('width');
|
||||
textEl.style.removeProperty('box-sizing');
|
||||
textEl.style.removeProperty('max-height');
|
||||
textEl.style.removeProperty('overflow');
|
||||
}
|
||||
|
||||
/** ค่าเริ่มต้นแผงคำถามบนแผนที่ (ตรงกับ server defaultCarryMapPanelTheme) — ใช้เมื่อยังไม่โหลดจาก API */
|
||||
@@ -819,9 +818,74 @@
|
||||
panelBorder: 'rgba(255, 214, 102, 0.7)',
|
||||
borderWidthPx: 2,
|
||||
textColor: '#f1f5f9',
|
||||
questionFontMinPx: 10,
|
||||
questionFontMaxPx: 24,
|
||||
};
|
||||
}
|
||||
|
||||
/** ตรงกับ drawQuizCarryChoiceLabels — carryChoicePlaqueMapScale */
|
||||
function quizCarryPlaqueMapScaleClampedPlay() {
|
||||
const sc = Number(quizCarryPlaqueMapScale);
|
||||
if (!Number.isFinite(sc)) return 1.25;
|
||||
return Math.max(0.85, Math.min(2.5, sc));
|
||||
}
|
||||
|
||||
/**
|
||||
* ขนาดตัวอักษรแผงคำถาม DOM ให้เท่าป้ายคำตอบบนพื้น: Math.max(10, Math.min(24, tileSize*zoom*0.24*ps))
|
||||
* แล้ว clamp ด้วย questionFontMinPx / questionFontMaxPx จากธีม (ถ้าต้องการใหญ่กว่าป้ายได้โดยยกเพดาน max)
|
||||
*/
|
||||
function quizMapQuestionFontPxLikeCarryPlaques(th, zoomVal) {
|
||||
const ts = tileSize * zoomVal;
|
||||
const ps = quizCarryPlaqueMapScaleClampedPlay();
|
||||
const base = Math.max(10, Math.min(24, ts * 0.24 * ps));
|
||||
const fb = defaultCarryMapPanelThemePlay();
|
||||
let mn = Number(th && th.questionFontMinPx);
|
||||
let mx = Number(th && th.questionFontMaxPx);
|
||||
if (!Number.isFinite(mn)) mn = fb.questionFontMinPx;
|
||||
if (!Number.isFinite(mx)) mx = fb.questionFontMaxPx;
|
||||
mn = Math.round(Math.max(8, Math.min(40, mn)));
|
||||
mx = Math.round(Math.max(10, Math.min(72, mx)));
|
||||
if (mx < mn) {
|
||||
const s = mn;
|
||||
mn = mx;
|
||||
mx = s;
|
||||
}
|
||||
return Math.max(mn, Math.min(mx, base));
|
||||
}
|
||||
|
||||
/**
|
||||
* ลด px ทีละ 1 จนเนื้อหาไม่ล้นกล่อง (ไม่ใช้ scrollbar)
|
||||
* zoom out กล่องเตี้ยมาก: อนุญาตต่ำกว่า questionFontMinPx ของธีมได้ถึง hardMin (≥6) ไม่ให้บรรทัดถูกตัด
|
||||
* แผงใช้ justify-content:flex-start ใน CSS — ไม่จัดกึ่งกลางแนวตั้งแล้วโดน overflow ตัดบน-ล่าง
|
||||
*/
|
||||
function fitQuizMapQuestionFontToPanel(panel, textEl, startPx, minPx) {
|
||||
const cs = window.getComputedStyle(panel);
|
||||
const padT = parseFloat(cs.paddingTop) || 0;
|
||||
const padB = parseFloat(cs.paddingBottom) || 0;
|
||||
const padL = parseFloat(cs.paddingLeft) || 0;
|
||||
const padR = parseFloat(cs.paddingRight) || 0;
|
||||
const availH = Math.max(12, panel.clientHeight - padT - padB);
|
||||
const availW = Math.max(24, panel.clientWidth - padL - padR);
|
||||
const themeMin = Math.max(8, Math.floor(Number(minPx) || 8));
|
||||
const hardMin = Math.min(themeMin, Math.max(6, Math.floor(availH / 7)));
|
||||
let px = Math.round(Math.min(80, Math.max(hardMin, Number(startPx) || hardMin)));
|
||||
textEl.style.setProperty('line-height', '1.28', 'important');
|
||||
textEl.style.setProperty('width', '100%', 'important');
|
||||
textEl.style.setProperty('box-sizing', 'border-box', 'important');
|
||||
textEl.style.removeProperty('max-height');
|
||||
textEl.style.setProperty('overflow', 'hidden', 'important');
|
||||
for (let i = 0; i < 96 && px > hardMin; i++) {
|
||||
textEl.style.setProperty('font-size', String(px) + 'px', 'important');
|
||||
const sh = textEl.scrollHeight;
|
||||
const sw = textEl.scrollWidth;
|
||||
if (sh <= availH + 2 && sw <= availW + 2) break;
|
||||
px -= 1;
|
||||
}
|
||||
textEl.style.setProperty('font-size', String(px) + 'px', 'important');
|
||||
textEl.style.setProperty('max-height', availH + 'px', 'important');
|
||||
}
|
||||
|
||||
/** ธีมจาก quiz-settings / join API — ถ้า JSON ไม่มีฟอนต์ให้ใช้ค่าเริ่มต้น */
|
||||
function parseCarryMapPanelThemeObject(raw) {
|
||||
let t = raw;
|
||||
if (typeof t === 'string') {
|
||||
@@ -834,14 +898,71 @@
|
||||
if (!t || typeof t !== 'object') return null;
|
||||
const bw = Number(t.borderWidthPx);
|
||||
const borderWidthPx = Number.isFinite(bw) ? Math.max(0, Math.min(12, Math.round(bw))) : 2;
|
||||
const fb = defaultCarryMapPanelThemePlay();
|
||||
let qMin = Number(t.questionFontMinPx);
|
||||
let qMax = Number(t.questionFontMaxPx);
|
||||
if (!Number.isFinite(qMin)) qMin = fb.questionFontMinPx;
|
||||
if (!Number.isFinite(qMax)) qMax = fb.questionFontMaxPx;
|
||||
qMin = Math.round(Math.max(10, Math.min(40, qMin)));
|
||||
qMax = Math.round(Math.max(14, Math.min(56, qMax)));
|
||||
if (qMax < qMin) {
|
||||
const s = qMin;
|
||||
qMin = qMax;
|
||||
qMax = s;
|
||||
}
|
||||
return {
|
||||
panelBg: String(t.panelBg || '').trim().slice(0, 120),
|
||||
panelBorder: String(t.panelBorder || '').trim().slice(0, 120),
|
||||
borderWidthPx,
|
||||
textColor: String(t.textColor || '').trim().slice(0, 120),
|
||||
questionFontMinPx: qMin,
|
||||
questionFontMaxPx: qMax,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* ชั้นทับจาก carryMapPanelTheme ในไฟล์แมป — ฟอนต์ใส่เฉพาะเมื่อ JSON มี key จริง
|
||||
* (กันธีมแมปมีแค่สีแล้วไปทับขนาดฟอนต์จาก Admin เป็นค่าเริ่ม 16/24)
|
||||
*/
|
||||
function parseCarryMapPanelThemeMapOverlay(raw) {
|
||||
let t = raw;
|
||||
if (typeof t === 'string') {
|
||||
try {
|
||||
t = JSON.parse(t);
|
||||
} catch (e) {
|
||||
t = null;
|
||||
}
|
||||
}
|
||||
if (!t || typeof t !== 'object') return null;
|
||||
const bw = Number(t.borderWidthPx);
|
||||
const borderWidthPx = Number.isFinite(bw) ? Math.max(0, Math.min(12, Math.round(bw))) : 2;
|
||||
const out = {
|
||||
panelBg: String(t.panelBg || '').trim().slice(0, 120),
|
||||
panelBorder: String(t.panelBorder || '').trim().slice(0, 120),
|
||||
borderWidthPx,
|
||||
textColor: String(t.textColor || '').trim().slice(0, 120),
|
||||
};
|
||||
const hasMin = Object.prototype.hasOwnProperty.call(t, 'questionFontMinPx');
|
||||
const hasMax = Object.prototype.hasOwnProperty.call(t, 'questionFontMaxPx');
|
||||
if (hasMin || hasMax) {
|
||||
const fb = defaultCarryMapPanelThemePlay();
|
||||
let qMin = hasMin ? Number(t.questionFontMinPx) : fb.questionFontMinPx;
|
||||
let qMax = hasMax ? Number(t.questionFontMaxPx) : fb.questionFontMaxPx;
|
||||
if (!Number.isFinite(qMin)) qMin = fb.questionFontMinPx;
|
||||
if (!Number.isFinite(qMax)) qMax = fb.questionFontMaxPx;
|
||||
qMin = Math.round(Math.max(10, Math.min(40, qMin)));
|
||||
qMax = Math.round(Math.max(14, Math.min(56, qMax)));
|
||||
if (qMax < qMin) {
|
||||
const s = qMin;
|
||||
qMin = qMax;
|
||||
qMax = s;
|
||||
}
|
||||
out.questionFontMinPx = qMin;
|
||||
out.questionFontMaxPx = qMax;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function setQuizCarryMapPanelThemeFromApi(s) {
|
||||
quizCarryMapPanelTheme = null;
|
||||
if (!s || typeof s !== 'object') return;
|
||||
@@ -1103,14 +1224,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** ธีมจากแผนที่ (ถ้ามี) ชนะค่าจาก API — ใส่ carryMapPanelTheme ใน JSON แมปได้โดยตรง */
|
||||
/** default ← quiz-settings/API ← แมป (สีจากแมปทับได้; ฟอนต์จากแมปเฉพาะเมื่อแมประบุ key) */
|
||||
function getEffectiveCarryMapPanelThemeForApply() {
|
||||
const d = defaultCarryMapPanelThemePlay();
|
||||
const api = quizCarryMapPanelTheme != null && typeof quizCarryMapPanelTheme === 'object' ? quizCarryMapPanelTheme : null;
|
||||
let merged = api ? { ...d, ...api } : { ...d };
|
||||
if (mapData && mapData.carryMapPanelTheme != null) {
|
||||
const parsed = parseCarryMapPanelThemeObject(mapData.carryMapPanelTheme);
|
||||
if (parsed) return parsed;
|
||||
const mp = parseCarryMapPanelThemeMapOverlay(mapData.carryMapPanelTheme);
|
||||
if (mp) merged = { ...merged, ...mp };
|
||||
}
|
||||
if (quizCarryMapPanelTheme != null) return quizCarryMapPanelTheme;
|
||||
return defaultCarryMapPanelThemePlay();
|
||||
return merged;
|
||||
}
|
||||
|
||||
function applyQuizCarryMapPanelThemeIfNeeded(panel, textEl) {
|
||||
@@ -1185,6 +1308,10 @@
|
||||
panel.classList.remove('is-hidden');
|
||||
panel.setAttribute('aria-hidden', 'false');
|
||||
applyQuizCarryMapPanelThemeIfNeeded(panel, textEl);
|
||||
const thFont = getEffectiveCarryMapPanelThemeForApply();
|
||||
const startFontPx = quizMapQuestionFontPxLikeCarryPlaques(thFont, zoom);
|
||||
const mnFont = Math.max(8, Math.round(Number(thFont.questionFontMinPx) || 10));
|
||||
fitQuizMapQuestionFontToPanel(panel, textEl, startFontPx, mnFont);
|
||||
}
|
||||
|
||||
function carryEmbedCountdownAnchorResolved() {
|
||||
@@ -2397,11 +2524,7 @@
|
||||
if (!choices || !choices.length) return;
|
||||
const maxSlots = choices.length;
|
||||
const ts = tileSize * zoom;
|
||||
const ps = (() => {
|
||||
const sc = Number(quizCarryPlaqueMapScale);
|
||||
if (!Number.isFinite(sc)) return 1.25;
|
||||
return Math.max(0.85, Math.min(2.5, sc));
|
||||
})();
|
||||
const ps = quizCarryPlaqueMapScaleClampedPlay();
|
||||
ctx.save();
|
||||
for (let i = 0; i < Math.min(choices.length, maxSlots); i++) {
|
||||
if (quizCarryOptionHeldByAnyone(i)) continue;
|
||||
@@ -7378,6 +7501,11 @@
|
||||
return s;
|
||||
}
|
||||
|
||||
/** ร่าง (cw×ch) ของผู้เล่นที่ (px,py) ครอบคลุมช่อง (tx,ty) หรือไม่ — ใช้กับ blockPlayer แทนการเช็คแค่มุมซ้ายบน */
|
||||
function playEntityFootprintContainsTile(px, py, tx, ty) {
|
||||
return quizTilesFootprintPlay(px, py).has(tx + ',' + ty);
|
||||
}
|
||||
|
||||
/** Footprint ชนกำแพง (objects=1) เท่านั้น — hub / interactive / blockPlayer / quiz ใช้ quizTilesFootprintPlay = เต็ม characterCells */
|
||||
function quizTilesWallCollisionFootprintPlay(px, py) {
|
||||
const s = new Set();
|
||||
@@ -7488,7 +7616,7 @@
|
||||
const tx = +p[0], ty = +p[1];
|
||||
if (!bp[ty] || bp[ty][tx] !== 1) continue;
|
||||
for (const [, o] of others) {
|
||||
if (Math.floor(o.x) === tx && Math.floor(o.y) === ty) return false;
|
||||
if (playEntityFootprintContainsTile(o.x, o.y, tx, ty)) return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7528,8 +7656,9 @@
|
||||
if (!bp[ty] || bp[ty][tx] !== 1) continue;
|
||||
for (const [, peer] of others) {
|
||||
if (o && peer === o) continue;
|
||||
if (Math.floor(peer.x) === tx && Math.floor(peer.y) === ty) return false;
|
||||
if (playEntityFootprintContainsTile(peer.x, peer.y, tx, ty)) return false;
|
||||
}
|
||||
if (o && playEntityFootprintContainsTile(me.x, me.y, tx, ty)) return false;
|
||||
}
|
||||
}
|
||||
if (isQuiz()) {
|
||||
@@ -8830,11 +8959,7 @@
|
||||
const raw = String(signText || '').trim();
|
||||
if (!raw && !imgUrlSan && !gridHeldDraw) return;
|
||||
ctx.save();
|
||||
const heldPs = (() => {
|
||||
const sc = Number(quizCarryPlaqueMapScale);
|
||||
if (!Number.isFinite(sc)) return 1.25;
|
||||
return Math.max(0.85, Math.min(2.5, sc));
|
||||
})();
|
||||
const heldPs = quizCarryPlaqueMapScaleClampedPlay();
|
||||
const bodyH = Math.max(18, feetSy - spriteTopY);
|
||||
const midBodyY = spriteTopY + bodyH * 0.48;
|
||||
const bodyCx = sxFeet;
|
||||
|
||||
@@ -897,7 +897,7 @@
|
||||
if (bp && bp[ty] && bp[ty][tx] === 1) {
|
||||
for (const [id, p] of peers) {
|
||||
if (id === socket.id) continue;
|
||||
if (Math.floor(p.x) === tx && Math.floor(p.y) === ty) return false;
|
||||
if (quizTilesFootprintLobby(p.x, p.y).has(tx + ',' + ty)) return false;
|
||||
}
|
||||
}
|
||||
if (mapData.gameType === 'quiz' && quizModeActive && quizPlayerLocal && !quizPlayerLocal.eliminated) {
|
||||
|
||||
@@ -123,10 +123,13 @@
|
||||
box-sizing: border-box;
|
||||
padding: clamp(6px, 1.5vw, 14px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
text-align: center;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
--qmap-bg: rgba(12, 14, 28, 0.88);
|
||||
--qmap-border: rgba(255, 214, 102, 0.7);
|
||||
--qmap-border-w: 2px;
|
||||
@@ -137,17 +140,37 @@
|
||||
box-shadow: var(--qmap-shadow);
|
||||
}
|
||||
#quiz-map-question-panel.is-hidden { display: none !important; }
|
||||
#quiz-map-question-panel::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
/* ขนาดตั้งต้น — โหมด quiz_carry ถูกทับด้วย play.js ตามสัดส่วนกล่อง + ธีม */
|
||||
#quiz-map-question-text {
|
||||
margin: 0;
|
||||
font-size: clamp(0.78rem, 2.4vmin, 1.12rem);
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
line-height: 1.45;
|
||||
--qmap-text: #f1f5f9;
|
||||
--qmap-text-shadow: 0 1px 10px rgba(0, 0, 0, 0.55);
|
||||
color: var(--qmap-text);
|
||||
text-shadow: var(--qmap-text-shadow);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
flex: 0 1 auto;
|
||||
min-height: 0;
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
white-space: pre-line;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
#quiz-map-question-text::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
#quiz-carry-embed-countdown {
|
||||
position: fixed;
|
||||
@@ -196,11 +219,21 @@
|
||||
#quiz-carry-embed-countdown-q {
|
||||
display: none;
|
||||
margin: 0;
|
||||
font: 600 clamp(0.88rem, 3.2vmin, 1.28rem) / 1.45 system-ui, "Kanit", sans-serif;
|
||||
font: 600 clamp(14px, 3.2vmin, 20px) / 1.45 system-ui, "Kanit", sans-serif;
|
||||
color: #f8fafc;
|
||||
text-shadow: 0 2px 20px rgba(0, 0, 0, 0.75);
|
||||
max-height: min(32vh, 220px);
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
white-space: pre-line;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
#quiz-carry-embed-countdown-q::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
#quiz-carry-embed-countdown-num {
|
||||
font: 800 min(var(--carry-ecd-screen-vw, 28vw), var(--carry-ecd-screen-max, 132px)) / 1.05 system-ui, "Kanit", sans-serif;
|
||||
@@ -980,7 +1013,7 @@
|
||||
</div>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0166"></script>
|
||||
<script src="js/play.js?v=0.145"></script>
|
||||
<script src="js/play.js?v=0.155"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -676,10 +676,13 @@
|
||||
box-sizing: border-box;
|
||||
padding: clamp(6px, 1.5vw, 14px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: flex-start;
|
||||
text-align: center;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
--qmap-bg: rgba(12, 14, 28, 0.88);
|
||||
--qmap-border: rgba(255, 214, 102, 0.7);
|
||||
--qmap-border-w: 2px;
|
||||
@@ -692,6 +695,11 @@
|
||||
#quiz-map-question-panel.is-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
#quiz-map-question-panel::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
/* ตอนเล่น quiz ซ่อนปุ่ม READY กลางล่าง — ไม่ให้ทับ/แย่งโฟกัสกับแถบคำถาม */
|
||||
body.room-lobby--quiz-active .room-lobby-ready-fixed {
|
||||
visibility: hidden;
|
||||
@@ -700,15 +708,29 @@
|
||||
#quiz-map-question-text {
|
||||
margin: 0;
|
||||
font-family: 'Kanit', system-ui, sans-serif;
|
||||
font-size: clamp(0.78rem, 2.4vmin, 1.12rem);
|
||||
font-size: clamp(14px, 2.5vmin, 18px);
|
||||
font-weight: 600;
|
||||
line-height: 1.45;
|
||||
--qmap-text: #f1f5f9;
|
||||
--qmap-text-shadow: 0 1px 10px rgba(0, 0, 0, 0.55);
|
||||
color: var(--qmap-text);
|
||||
text-shadow: var(--qmap-text-shadow);
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
flex: 0 1 auto;
|
||||
min-height: 0;
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
overflow: hidden;
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
white-space: pre-line;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
#quiz-map-question-text::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
#quiz-feedback-banner {
|
||||
position: fixed;
|
||||
@@ -1021,7 +1043,7 @@
|
||||
</div>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0122"></script>
|
||||
<script src="js/room-lobby.js?v=0.0180"></script>
|
||||
<script src="js/room-lobby.js?v=0.0182"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -123,6 +123,8 @@ function defaultCarryMapPanelTheme() {
|
||||
panelBorder: 'rgba(255, 214, 102, 0.7)',
|
||||
borderWidthPx: 2,
|
||||
textColor: '#f1f5f9',
|
||||
questionFontMinPx: 10,
|
||||
questionFontMaxPx: 24,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -141,6 +143,17 @@ function sanitizeCssColorToken(input, fallback) {
|
||||
function sanitizeCarryMapPanelTheme(raw) {
|
||||
const d = defaultCarryMapPanelTheme();
|
||||
if (!raw || typeof raw !== 'object') return d;
|
||||
let qMin = Number(raw.questionFontMinPx);
|
||||
let qMax = Number(raw.questionFontMaxPx);
|
||||
if (!Number.isFinite(qMin)) qMin = d.questionFontMinPx;
|
||||
if (!Number.isFinite(qMax)) qMax = d.questionFontMaxPx;
|
||||
qMin = Math.round(Math.max(10, Math.min(40, qMin)));
|
||||
qMax = Math.round(Math.max(14, Math.min(56, qMax)));
|
||||
if (qMax < qMin) {
|
||||
const t = qMin;
|
||||
qMin = qMax;
|
||||
qMax = t;
|
||||
}
|
||||
return {
|
||||
panelBg: sanitizeCssColorToken(raw.panelBg, d.panelBg),
|
||||
panelBorder: sanitizeCssColorToken(raw.panelBorder, d.panelBorder),
|
||||
@@ -150,6 +163,8 @@ function sanitizeCarryMapPanelTheme(raw) {
|
||||
return Math.max(0, Math.min(12, Math.round(w)));
|
||||
})(),
|
||||
textColor: sanitizeCssColorToken(raw.textColor, d.textColor),
|
||||
questionFontMinPx: qMin,
|
||||
questionFontMaxPx: qMax,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user