mirror of
https://github.com/Coldsmiles/infstarweb.git
synced 2026-04-23 02:30:41 +08:00
feat: add toggle for secret coordinates and dimension selection in town editor
This commit is contained in:
@@ -1210,6 +1210,61 @@
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* Toggle Switch */
|
||||
.town-editor-modal-content .toggle-label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
width: 44px;
|
||||
height: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.toggle-switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.toggle-slider {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: #ccc;
|
||||
border-radius: 24px;
|
||||
transition: 0.25s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.toggle-slider::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
transition: 0.25s;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.toggle-switch input:checked + .toggle-slider {
|
||||
background: var(--accent-color, #0071e3);
|
||||
}
|
||||
|
||||
.toggle-switch input:checked + .toggle-slider::before {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
/* Tags Input */
|
||||
.town-editor-modal-content .tags-input-wrapper {
|
||||
display: flex;
|
||||
|
||||
@@ -6,11 +6,8 @@
|
||||
"from": "#95ea66",
|
||||
"to": "#4aa18b"
|
||||
},
|
||||
"coordinates": {
|
||||
"x": 0,
|
||||
"y": 64,
|
||||
"z": 0
|
||||
},
|
||||
"dimension": "overworld",
|
||||
"coordinatesSecret": true,
|
||||
"scale": "small",
|
||||
"townType": "building",
|
||||
"recruitment": "closed",
|
||||
|
||||
@@ -211,13 +211,26 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
recruitBadge.innerHTML = '<i class="fas ' + getRecruitIcon(item.recruitment) + '"></i> ' + getRecruitText(item.recruitment);
|
||||
badgesContainer.appendChild(recruitBadge);
|
||||
|
||||
// Coordinates
|
||||
var coords = item.coordinates;
|
||||
document.getElementById('town-modal-coords').innerText = 'X: ' + coords.x + ', Y: ' + coords.y + ', Z: ' + coords.z;
|
||||
|
||||
// Map Link
|
||||
// Coordinates & Dimension
|
||||
var coords = item.coordinates || { x: 0, y: 64, z: 0 };
|
||||
var dimension = item.dimension || 'overworld';
|
||||
var isSecret = item.coordinatesSecret === true;
|
||||
var locationTitleEl = document.getElementById('town-modal-location-title');
|
||||
var dimensionEl = document.getElementById('town-modal-dimension');
|
||||
var coordsEl = document.getElementById('town-modal-coords');
|
||||
var mapLink = document.getElementById('town-modal-map-link');
|
||||
mapLink.href = 'https://mcmap.lunadeer.cn/#world:' + coords.x + ':' + coords.y + ':' + coords.z + ':500:0:0:0:1:flat';
|
||||
|
||||
locationTitleEl.innerHTML = '<i class="fas fa-map-marker-alt"></i> 位置信息';
|
||||
if (isSecret) {
|
||||
dimensionEl.innerText = '';
|
||||
coordsEl.innerText = '保密';
|
||||
mapLink.style.display = 'none';
|
||||
} else {
|
||||
dimensionEl.innerText = getDimensionText(dimension) + ': ';
|
||||
coordsEl.innerText = 'X: ' + coords.x + ', Y: ' + coords.y + ', Z: ' + coords.z;
|
||||
mapLink.style.display = '';
|
||||
mapLink.href = 'https://mcmap.lunadeer.cn/#' + getDimensionMapWorld(dimension) + ':' + coords.x + ':' + coords.y + ':' + coords.z + ':500:0:0:0:1:flat';
|
||||
}
|
||||
|
||||
// Founders
|
||||
var foundersContainer = document.getElementById('town-modal-founders');
|
||||
@@ -342,6 +355,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
return map[recruitment] || 'fa-info-circle';
|
||||
}
|
||||
|
||||
function getDimensionText(dimension) {
|
||||
var map = { 'overworld': '主世界', 'nether': '下界', 'the_end': '末地' };
|
||||
return map[dimension] || '主世界';
|
||||
}
|
||||
|
||||
function getDimensionMapWorld(dimension) {
|
||||
var map = { 'overworld': 'world', 'nether': 'world_nether', 'the_end': 'world_the_end' };
|
||||
return map[dimension] || 'world';
|
||||
}
|
||||
|
||||
function normalizeHexColor(value, fallback) {
|
||||
if (!value || typeof value !== 'string') return fallback;
|
||||
var trimmed = value.trim();
|
||||
@@ -496,6 +519,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
setCustomSelectValue('editor-town-scale', item ? item.scale : 'small');
|
||||
setCustomSelectValue('editor-town-type', item ? item.townType : 'building');
|
||||
setCustomSelectValue('editor-town-recruit', item ? item.recruitment : 'welcome');
|
||||
setCustomSelectValue('editor-town-dimension', item && item.dimension ? item.dimension : 'overworld');
|
||||
|
||||
var secretCheckbox = document.getElementById('editor-town-secret');
|
||||
secretCheckbox.checked = item ? (item.coordinatesSecret === true) : false;
|
||||
toggleCoordsRow();
|
||||
|
||||
document.getElementById('editor-town-x').value = item ? item.coordinates.x : '';
|
||||
document.getElementById('editor-town-y').value = item ? item.coordinates.y : '';
|
||||
@@ -701,7 +729,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// --- Live Preview ---
|
||||
['editor-town-title', 'editor-town-logo', 'editor-town-scale', 'editor-town-type',
|
||||
'editor-town-recruit', 'editor-town-x', 'editor-town-y', 'editor-town-z'].forEach(function(id) {
|
||||
'editor-town-recruit', 'editor-town-dimension', 'editor-town-x', 'editor-town-y', 'editor-town-z'].forEach(function(id) {
|
||||
var el = document.getElementById(id);
|
||||
el.addEventListener('input', updatePreview);
|
||||
el.addEventListener('change', updatePreview);
|
||||
@@ -713,6 +741,20 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
el.addEventListener('change', updatePreview);
|
||||
});
|
||||
|
||||
// Secret coordinates toggle
|
||||
function toggleCoordsRow() {
|
||||
var secret = document.getElementById('editor-town-secret').checked;
|
||||
var dimensionGroup = document.getElementById('editor-dimension-group');
|
||||
var coordsRow = document.getElementById('editor-coords-row');
|
||||
dimensionGroup.style.display = secret ? 'none' : '';
|
||||
coordsRow.style.display = secret ? 'none' : '';
|
||||
}
|
||||
|
||||
document.getElementById('editor-town-secret').addEventListener('change', function() {
|
||||
toggleCoordsRow();
|
||||
updatePreview();
|
||||
});
|
||||
|
||||
function updatePreview() {
|
||||
var preview = document.getElementById('town-editor-preview-area');
|
||||
var title = document.getElementById('editor-town-title').value || '未命名城镇';
|
||||
@@ -723,6 +765,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
var x = document.getElementById('editor-town-x').value || '0';
|
||||
var y = document.getElementById('editor-town-y').value || '64';
|
||||
var z = document.getElementById('editor-town-z').value || '0';
|
||||
var dimension = document.getElementById('editor-town-dimension').value || 'overworld';
|
||||
var isSecret = document.getElementById('editor-town-secret').checked;
|
||||
var gradient = {
|
||||
from: normalizeHexColor(document.getElementById('editor-town-gradient-from').value, DEFAULT_GRADIENT.from),
|
||||
to: normalizeHexColor(document.getElementById('editor-town-gradient-to').value, DEFAULT_GRADIENT.to)
|
||||
@@ -748,8 +792,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
html += '<div class="preview-detail-body">';
|
||||
|
||||
html += '<div class="preview-section">';
|
||||
html += '<h4 class="preview-section-title"><i class="fas fa-map-marker-alt"></i> 位置信息</h4>';
|
||||
html += '<p class="preview-inline-text">主世界: X: ' + escapeHtml(x) + ', Y: ' + escapeHtml(y) + ', Z: ' + escapeHtml(z) + '</p>';
|
||||
html += '<h4 class="preview-section-title"><i class="fas fa-map-marker-alt"></i> ' + (isSecret ? '位置信息(保密)' : '位置信息') + '</h4>';
|
||||
if (isSecret) {
|
||||
html += '<p class="preview-inline-text">坐标保密</p>';
|
||||
} else {
|
||||
html += '<p class="preview-inline-text">' + escapeHtml(getDimensionText(dimension)) + ': X: ' + escapeHtml(x) + ', Y: ' + escapeHtml(y) + ', Z: ' + escapeHtml(z) + '</p>';
|
||||
}
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="preview-section">';
|
||||
@@ -810,6 +858,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
return;
|
||||
}
|
||||
|
||||
var isSecret = document.getElementById('editor-town-secret').checked;
|
||||
var townObj = {
|
||||
title: title,
|
||||
logo: document.getElementById('editor-town-logo').value.trim(),
|
||||
@@ -817,11 +866,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
from: normalizeHexColor(document.getElementById('editor-town-gradient-from').value, DEFAULT_GRADIENT.from),
|
||||
to: normalizeHexColor(document.getElementById('editor-town-gradient-to').value, DEFAULT_GRADIENT.to)
|
||||
},
|
||||
coordinates: {
|
||||
x: parseInt(document.getElementById('editor-town-x').value) || 0,
|
||||
y: parseInt(document.getElementById('editor-town-y').value) || 64,
|
||||
z: parseInt(document.getElementById('editor-town-z').value) || 0
|
||||
},
|
||||
dimension: document.getElementById('editor-town-dimension').value || 'overworld',
|
||||
coordinatesSecret: isSecret,
|
||||
scale: document.getElementById('editor-town-scale').value,
|
||||
townType: document.getElementById('editor-town-type').value,
|
||||
recruitment: document.getElementById('editor-town-recruit').value,
|
||||
@@ -832,6 +878,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
})
|
||||
};
|
||||
|
||||
if (!isSecret) {
|
||||
townObj.coordinates = {
|
||||
x: parseInt(document.getElementById('editor-town-x').value) || 0,
|
||||
y: parseInt(document.getElementById('editor-town-y').value) || 64,
|
||||
z: parseInt(document.getElementById('editor-town-z').value) || 0
|
||||
};
|
||||
}
|
||||
|
||||
var jsonStr = JSON.stringify(townObj, null, 4);
|
||||
document.getElementById('town-json-output').value = jsonStr;
|
||||
jsonOutputModal.style.display = 'block';
|
||||
|
||||
33
towns.html
33
towns.html
@@ -140,10 +140,10 @@
|
||||
</div>
|
||||
|
||||
<div class="town-modal-body">
|
||||
<div class="modal-section">
|
||||
<h4 class="modal-section-title"><i class="fas fa-map-marker-alt"></i> 位置信息</h4>
|
||||
<div class="modal-section" id="town-modal-location-section">
|
||||
<h4 class="modal-section-title" id="town-modal-location-title"><i class="fas fa-map-marker-alt"></i> 位置信息</h4>
|
||||
<p>
|
||||
主世界:
|
||||
<span id="town-modal-dimension"></span>
|
||||
<span id="town-modal-coords"></span>
|
||||
<a href="#" target="_blank" id="town-modal-map-link" class="town-map-link">
|
||||
<i class="fas fa-map-marked-alt"></i> 查看地图
|
||||
@@ -261,7 +261,32 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row coords-row">
|
||||
<div class="form-group">
|
||||
<label class="toggle-label">
|
||||
<span>坐标保密</span>
|
||||
<div class="toggle-switch">
|
||||
<input type="checkbox" id="editor-town-secret">
|
||||
<span class="toggle-slider"></span>
|
||||
</div>
|
||||
</label>
|
||||
<p class="field-hint">开启后将隐藏坐标信息,适用于不希望公开位置的城镇。</p>
|
||||
</div>
|
||||
<div class="form-group" id="editor-dimension-group">
|
||||
<label>所在世界</label>
|
||||
<div class="custom-select">
|
||||
<input type="hidden" id="editor-town-dimension" value="overworld">
|
||||
<div class="custom-select-trigger">
|
||||
<span class="custom-select-text">主世界</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</div>
|
||||
<div class="custom-select-options">
|
||||
<div class="custom-option selected" data-value="overworld">主世界</div>
|
||||
<div class="custom-option" data-value="nether">下界</div>
|
||||
<div class="custom-option" data-value="the_end">末地</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row coords-row" id="editor-coords-row">
|
||||
<div class="form-group">
|
||||
<label for="editor-town-x">X 坐标</label>
|
||||
<input type="number" id="editor-town-x" placeholder="0">
|
||||
|
||||
Reference in New Issue
Block a user