Common.js: Difference between revisions
From Dune Awakening DB
mNo edit summary |
mNo edit summary |
||
| Line 1: | Line 1: | ||
// | // Enhanced Radial Menu with Popout Secondary Menus | ||
$(document).ready(function() { | $(document).ready(function() { | ||
// Remove the "From Dune Awakening DB" tagline | // Remove the "From Dune Awakening DB" tagline | ||
| Line 11: | Line 11: | ||
}); | }); | ||
// Define menu items with | // Define menu items with their subcategories | ||
const menuItems = [ | const menuItems = [ | ||
{ id: "resources", name: "Resources", icon: "/images/ | { | ||
{ id: "crafting", name: "Crafting", icon: "/images/CraftingNavIcon.png", position: "northeast" }, | id: "resources", | ||
{ id: "refining", name: "Refining", icon: "/images/RefiningNavIcon.png", position: "east" }, | name: "Resources", | ||
{ id: "vehicles", name: "Vehicles", icon: "/images/VehiclesNavIcon.png", position: "southeast" }, | shortname: "Resou", | ||
{ id: "armor", name: "Armor", icon: "/images/ArmorNavIcon.png", position: "south" }, | icon: "https://dunedb.com/images/0/08/ResourcesNavIcon.png", | ||
{ id: " | position: "north", | ||
{ id: "skills", name: "Skills", icon: "/images/SkillsNavIcon.png", position: "west" }, | subcategories: [ | ||
{ id: "technology", name: "Technology", icon: "/images/TechnologyNavIcon.png", position: "northwest" } | { name: "Metals", url: "https://dunedb.com/Resources/Metals" }, | ||
{ name: "Chemicals", url: "https://dunedb.com/Resources/Chemicals" } | |||
] | |||
}, | |||
{ | |||
id: "crafting", | |||
name: "Crafting", | |||
shortname: "Craft", | |||
icon: "https://dunedb.com/images/d/d7/CraftingNavIcon.png", | |||
position: "northeast", | |||
subcategories: [ | |||
{ name: "Blueprints", url: "https://dunedb.com/Crafting/Blueprints" }, | |||
{ name: "Stations", url: "https://dunedb.com/Crafting/Stations" } | |||
] | |||
}, | |||
{ | |||
id: "refining", | |||
name: "Refining", | |||
shortname: "Refin", | |||
icon: "https://dunedb.com/images/5/5e/RefiningNavIcon.png", | |||
position: "east", | |||
subcategories: [ | |||
{ name: "Refineries", url: "https://dunedb.com/Refining/Refineries" }, | |||
{ name: "Processes", url: "https://dunedb.com/Refining/Processes" } | |||
] | |||
}, | |||
{ | |||
id: "vehicles", | |||
name: "Vehicles", | |||
shortname: "Vehic", | |||
icon: "https://dunedb.com/images/0/06/VehiclesNavIcon.png", | |||
position: "southeast", | |||
subcategories: [ | |||
{ name: "Land Vehicles", url: "https://dunedb.com/Vehicles/Land" }, | |||
{ name: "Aircraft", url: "https://dunedb.com/Vehicles/Aircraft" } | |||
] | |||
}, | |||
{ | |||
id: "armor", | |||
name: "Armor", | |||
shortname: "Armo", | |||
icon: "https://dunedb.com/images/a/ae/ArmorNavIcon.png", | |||
position: "south", | |||
subcategories: [ | |||
{ name: "Light Armor", url: "https://dunedb.com/Armor/Light" }, | |||
{ name: "Heavy Armor", url: "https://dunedb.com/Armor/Heavy" } | |||
] | |||
}, | |||
{ | |||
id: "building", | |||
name: "Building", | |||
shortname: "Build", | |||
icon: "https://dunedb.com/images/5/58/BuildNavIcon.png", | |||
position: "southwest", | |||
subcategories: [ | |||
{ name: "Bases", url: "https://dunedb.com/Building/Bases" }, | |||
{ name: "Structures", url: "https://dunedb.com/Building/Structures" } | |||
] | |||
}, | |||
{ | |||
id: "skills", | |||
name: "Skills", | |||
shortname: "Skills", | |||
icon: "https://dunedb.com/images/a/a8/SkillsNavIcon.png", | |||
position: "west", | |||
subcategories: [ | |||
{ name: "Combat", url: "https://dunedb.com/Skills/Combat" }, | |||
{ name: "Survival", url: "https://dunedb.com/Skills/Survival" } | |||
] | |||
}, | |||
{ | |||
id: "technology", | |||
name: "Technology", | |||
shortname: "Techn", | |||
icon: "https://dunedb.com/images/0/05/TechnologyNavIcon.png", | |||
position: "northwest", | |||
subcategories: [ | |||
{ name: "Research", url: "https://dunedb.com/Technology/Research" }, | |||
{ name: "Equipment", url: "https://dunedb.com/Technology/Equipment" } | |||
] | |||
} | |||
]; | ]; | ||
// Create the center button HTML | // Create the center button HTML | ||
const centerButtonHTML = ` | const centerButtonHTML = ` | ||
<a href="/Main_Page" class="dune-radial-center"> | <a href="https://dunedb.com/Main_Page" class="dune-radial-center"> | ||
< | <span class="dune-radial-text">Home</span> | ||
<span class="dune-radial-tooltip"> | <span class="dune-radial-tooltip">Main Page</span> | ||
</a> | </a> | ||
`; | `; | ||
// Create the radial menu items HTML | // Create the radial menu items HTML with full URLs and text labels | ||
let radialItemsHTML = ''; | let radialItemsHTML = ''; | ||
menuItems.forEach(item => { | menuItems.forEach(item => { | ||
radialItemsHTML += ` | radialItemsHTML += ` | ||
< | <div class="dune-radial-item-container ${item.position}"> | ||
< | <a data-id="${item.id}" class="dune-radial-item"> | ||
<span class="dune-radial-text">${item.shortname}</span> | |||
</ | <span class="dune-radial-tooltip">${item.name}</span> | ||
</a> | |||
</div> | |||
`; | `; | ||
}); | }); | ||
| Line 45: | Line 127: | ||
const radialMenuHTML = ` | const radialMenuHTML = ` | ||
<div id="duneRadialMenu" class="dune-radial-menu"> | <div id="duneRadialMenu" class="dune-radial-menu"> | ||
<div class="dune-radial-background"> | |||
<div class="dune-radial-circle outer"></div> | |||
<div class="dune-radial-circle middle"></div> | |||
<div class="dune-radial-circle inner"></div> | |||
</div> | |||
${centerButtonHTML} | ${centerButtonHTML} | ||
${radialItemsHTML} | ${radialItemsHTML} | ||
| Line 51: | Line 138: | ||
`; | `; | ||
// Add the menu to the page | // Create subcategory popout HTML | ||
let subcategoryContainerHTML = `<div id="duneSubcategoryContainer" class="dune-subcategory-container"></div>`; | |||
// Add the menu and subcategory container to the page | |||
$('body').append(radialMenuHTML); | $('body').append(radialMenuHTML); | ||
$('body').append(subcategoryContainerHTML); | |||
// Create the logo container and breadcrumb | // Create the logo container and breadcrumb | ||
| Line 60: | Line 151: | ||
<img src="https://dunedb.com/favicon.ico" alt="DuneDB Logo" class="dune-logo"> | <img src="https://dunedb.com/favicon.ico" alt="DuneDB Logo" class="dune-logo"> | ||
</a> | </a> | ||
<a href="/Main_Page">Home</a> | <a href="https://dunedb.com/Main_Page">Home</a> | ||
<span class="dune-breadcrumb-separator">/</span> | <span class="dune-breadcrumb-separator">/</span> | ||
<a href="/Buildings">Buildings</a> | <a href="https://dunedb.com/Buildings">Buildings</a> | ||
<span class="dune-breadcrumb-separator">/</span> | <span class="dune-breadcrumb-separator">/</span> | ||
<a href="/Buildings/Refiners">Refiners</a> | <a href="https://dunedb.com/Buildings/Refiners">Refiners</a> | ||
<span class="dune-breadcrumb-separator">/</span> | <span class="dune-breadcrumb-separator">/</span> | ||
<span>${$('h1.firstHeading').text() || $('.mw-page-title-main').text()}</span> | <span>${$('h1.firstHeading').text() || $('.mw-page-title-main').text()}</span> | ||
| Line 79: | Line 170: | ||
// Add sequential animation to each item | // Add sequential animation to each item | ||
$('.dune-radial-item').each(function(index) { | $('.dune-radial-item-container').each(function(index) { | ||
const $item = $(this); | const $item = $(this); | ||
setTimeout(() => { | setTimeout(() => { | ||
| Line 94: | Line 185: | ||
// Closing animation effect | // Closing animation effect | ||
const closeMenu = () => { | const closeMenu = () => { | ||
$('.dune-radial-item, .dune-radial-center').removeClass('animated'); | // Hide subcategory menu if open | ||
hideSubcategories(); | |||
$('.dune-radial-item-container, .dune-radial-center').removeClass('animated'); | |||
setTimeout(() => { | setTimeout(() => { | ||
| Line 100: | Line 194: | ||
$('#duneRadialOverlay').removeClass('active'); | $('#duneRadialOverlay').removeClass('active'); | ||
}, 300); | }, 300); | ||
}; | |||
// Handle showing subcategories | |||
const showSubcategories = (itemId, event) => { | |||
// Find the clicked item in our data | |||
const item = menuItems.find(i => i.id === itemId); | |||
if (!item || !item.subcategories) return; | |||
// Mark the item as selected | |||
$('.dune-radial-item').removeClass('selected'); | |||
$(`.dune-radial-item[data-id="${itemId}"]`).addClass('selected'); | |||
// Calculate position for subcategory menu | |||
// Get position of clicked item | |||
const $item = $(`.dune-radial-item[data-id="${itemId}"]`); | |||
const itemOffset = $item.offset(); | |||
const itemWidth = $item.outerWidth(); | |||
const itemHeight = $item.outerHeight(); | |||
// Build subcategory HTML | |||
let subcategoryHTML = ` | |||
<div class="dune-subcategory-header">${item.name}</div> | |||
<div class="dune-subcategory-items"> | |||
`; | |||
item.subcategories.forEach(sub => { | |||
subcategoryHTML += ` | |||
<a href="${sub.url}" class="dune-subcategory-item"> | |||
<span class="dune-subcategory-name">${sub.name}</span> | |||
</a> | |||
`; | |||
}); | |||
subcategoryHTML += ` | |||
</div> | |||
<div class="dune-subcategory-footer"> | |||
<a href="https://dunedb.com/${item.id}" class="dune-subcategory-all">View All ${item.name}</a> | |||
</div> | |||
`; | |||
// Update and position the subcategory container | |||
const $subcategoryContainer = $('#duneSubcategoryContainer'); | |||
$subcategoryContainer.html(subcategoryHTML); | |||
// Position based on which quadrant the item is in | |||
let top, left; | |||
switch(item.position) { | |||
case 'north': | |||
case 'northeast': | |||
top = itemOffset.top + itemHeight + 10; | |||
left = itemOffset.left - 100 + (itemWidth / 2); | |||
break; | |||
case 'east': | |||
top = itemOffset.top - 50; | |||
left = itemOffset.left + itemWidth + 10; | |||
break; | |||
case 'southeast': | |||
case 'south': | |||
top = itemOffset.top - 120; | |||
left = itemOffset.left - 100 + (itemWidth / 2); | |||
break; | |||
case 'southwest': | |||
case 'west': | |||
top = itemOffset.top - 50; | |||
left = itemOffset.left - 170; | |||
break; | |||
case 'northwest': | |||
top = itemOffset.top + itemHeight + 10; | |||
left = itemOffset.left - 100; | |||
break; | |||
default: | |||
top = itemOffset.top + itemHeight + 10; | |||
left = itemOffset.left; | |||
} | |||
// Apply position | |||
$subcategoryContainer.css({ | |||
top: top + 'px', | |||
left: left + 'px' | |||
}).addClass('active'); | |||
// Prevent event from closing the main menu | |||
event.stopPropagation(); | |||
}; | |||
// Hide subcategories | |||
const hideSubcategories = () => { | |||
$('#duneSubcategoryContainer').removeClass('active'); | |||
$('.dune-radial-item').removeClass('selected'); | |||
}; | }; | ||
| Line 111: | Line 295: | ||
} else { | } else { | ||
openMenu(); | openMenu(); | ||
} | |||
}); | |||
// Handle item click to show subcategories | |||
$(document).on('click', '.dune-radial-item', function(e) { | |||
e.preventDefault(); | |||
e.stopPropagation(); | |||
const itemId = $(this).data('id'); | |||
// If already selected, hide subcategories | |||
if ($(this).hasClass('selected')) { | |||
hideSubcategories(); | |||
} else { | |||
showSubcategories(itemId, e); | |||
} | |||
}); | |||
// Close subcategories when clicking anywhere else in the radial menu | |||
$(document).on('click', '#duneRadialMenu', function(e) { | |||
if (!$(e.target).closest('.dune-radial-item').length) { | |||
hideSubcategories(); | |||
} | } | ||
}); | }); | ||
| Line 121: | Line 327: | ||
// Close menu with ESC key | // Close menu with ESC key | ||
$(document).on('keydown', function(e) { | $(document).on('keydown', function(e) { | ||
if (e.key === 'Escape' | if (e.key === 'Escape') { | ||
if ($('#duneSubcategoryContainer').hasClass('active')) { | |||
hideSubcategories(); | |||
} else if ($('#duneRadialMenu').hasClass('active')) { | |||
closeMenu(); | |||
} | |||
} | } | ||
}); | }); | ||
}); | }); | ||
Revision as of 01:42, 7 April 2025
// Enhanced Radial Menu with Popout Secondary Menus
$(document).ready(function() {
// Remove the "From Dune Awakening DB" tagline
$('#tagline').remove();
// Reduce spacing above the title
$('h1.title, .mw-page-title-main, h1.firstHeading').css({
'margin-top': '0',
'padding-top': '5px',
'line-height': '1.2'
});
// Define menu items with their subcategories
const menuItems = [
{
id: "resources",
name: "Resources",
shortname: "Resou",
icon: "https://dunedb.com/images/0/08/ResourcesNavIcon.png",
position: "north",
subcategories: [
{ name: "Metals", url: "https://dunedb.com/Resources/Metals" },
{ name: "Chemicals", url: "https://dunedb.com/Resources/Chemicals" }
]
},
{
id: "crafting",
name: "Crafting",
shortname: "Craft",
icon: "https://dunedb.com/images/d/d7/CraftingNavIcon.png",
position: "northeast",
subcategories: [
{ name: "Blueprints", url: "https://dunedb.com/Crafting/Blueprints" },
{ name: "Stations", url: "https://dunedb.com/Crafting/Stations" }
]
},
{
id: "refining",
name: "Refining",
shortname: "Refin",
icon: "https://dunedb.com/images/5/5e/RefiningNavIcon.png",
position: "east",
subcategories: [
{ name: "Refineries", url: "https://dunedb.com/Refining/Refineries" },
{ name: "Processes", url: "https://dunedb.com/Refining/Processes" }
]
},
{
id: "vehicles",
name: "Vehicles",
shortname: "Vehic",
icon: "https://dunedb.com/images/0/06/VehiclesNavIcon.png",
position: "southeast",
subcategories: [
{ name: "Land Vehicles", url: "https://dunedb.com/Vehicles/Land" },
{ name: "Aircraft", url: "https://dunedb.com/Vehicles/Aircraft" }
]
},
{
id: "armor",
name: "Armor",
shortname: "Armo",
icon: "https://dunedb.com/images/a/ae/ArmorNavIcon.png",
position: "south",
subcategories: [
{ name: "Light Armor", url: "https://dunedb.com/Armor/Light" },
{ name: "Heavy Armor", url: "https://dunedb.com/Armor/Heavy" }
]
},
{
id: "building",
name: "Building",
shortname: "Build",
icon: "https://dunedb.com/images/5/58/BuildNavIcon.png",
position: "southwest",
subcategories: [
{ name: "Bases", url: "https://dunedb.com/Building/Bases" },
{ name: "Structures", url: "https://dunedb.com/Building/Structures" }
]
},
{
id: "skills",
name: "Skills",
shortname: "Skills",
icon: "https://dunedb.com/images/a/a8/SkillsNavIcon.png",
position: "west",
subcategories: [
{ name: "Combat", url: "https://dunedb.com/Skills/Combat" },
{ name: "Survival", url: "https://dunedb.com/Skills/Survival" }
]
},
{
id: "technology",
name: "Technology",
shortname: "Techn",
icon: "https://dunedb.com/images/0/05/TechnologyNavIcon.png",
position: "northwest",
subcategories: [
{ name: "Research", url: "https://dunedb.com/Technology/Research" },
{ name: "Equipment", url: "https://dunedb.com/Technology/Equipment" }
]
}
];
// Create the center button HTML
const centerButtonHTML = `
<a href="https://dunedb.com/Main_Page" class="dune-radial-center">
<span class="dune-radial-text">Home</span>
<span class="dune-radial-tooltip">Main Page</span>
</a>
`;
// Create the radial menu items HTML with full URLs and text labels
let radialItemsHTML = '';
menuItems.forEach(item => {
radialItemsHTML += `
<div class="dune-radial-item-container ${item.position}">
<a data-id="${item.id}" class="dune-radial-item">
<span class="dune-radial-text">${item.shortname}</span>
<span class="dune-radial-tooltip">${item.name}</span>
</a>
</div>
`;
});
// Create the complete radial menu structure
const radialMenuHTML = `
<div id="duneRadialMenu" class="dune-radial-menu">
<div class="dune-radial-background">
<div class="dune-radial-circle outer"></div>
<div class="dune-radial-circle middle"></div>
<div class="dune-radial-circle inner"></div>
</div>
${centerButtonHTML}
${radialItemsHTML}
</div>
<div id="duneRadialOverlay" class="dune-radial-overlay"></div>
`;
// Create subcategory popout HTML
let subcategoryContainerHTML = `<div id="duneSubcategoryContainer" class="dune-subcategory-container"></div>`;
// Add the menu and subcategory container to the page
$('body').append(radialMenuHTML);
$('body').append(subcategoryContainerHTML);
// Create the logo container and breadcrumb
const breadcrumbHTML = `
<div class="dune-breadcrumb-nav">
<a id="duneLogoBtn" class="dune-logo-btn">
<img src="https://dunedb.com/favicon.ico" alt="DuneDB Logo" class="dune-logo">
</a>
<a href="https://dunedb.com/Main_Page">Home</a>
<span class="dune-breadcrumb-separator">/</span>
<a href="https://dunedb.com/Buildings">Buildings</a>
<span class="dune-breadcrumb-separator">/</span>
<a href="https://dunedb.com/Buildings/Refiners">Refiners</a>
<span class="dune-breadcrumb-separator">/</span>
<span>${$('h1.firstHeading').text() || $('.mw-page-title-main').text()}</span>
</div>
`;
// Add the breadcrumb after the title
$('h1.firstHeading, .mw-page-title-main').parent().after(breadcrumbHTML);
// Opening animation effect
const openMenu = () => {
$('#duneRadialMenu').addClass('active');
$('#duneRadialOverlay').addClass('active');
// Add sequential animation to each item
$('.dune-radial-item-container').each(function(index) {
const $item = $(this);
setTimeout(() => {
$item.addClass('animated');
}, index * 50);
});
// Animate center button last
setTimeout(() => {
$('.dune-radial-center').addClass('animated');
}, menuItems.length * 50);
};
// Closing animation effect
const closeMenu = () => {
// Hide subcategory menu if open
hideSubcategories();
$('.dune-radial-item-container, .dune-radial-center').removeClass('animated');
setTimeout(() => {
$('#duneRadialMenu').removeClass('active');
$('#duneRadialOverlay').removeClass('active');
}, 300);
};
// Handle showing subcategories
const showSubcategories = (itemId, event) => {
// Find the clicked item in our data
const item = menuItems.find(i => i.id === itemId);
if (!item || !item.subcategories) return;
// Mark the item as selected
$('.dune-radial-item').removeClass('selected');
$(`.dune-radial-item[data-id="${itemId}"]`).addClass('selected');
// Calculate position for subcategory menu
// Get position of clicked item
const $item = $(`.dune-radial-item[data-id="${itemId}"]`);
const itemOffset = $item.offset();
const itemWidth = $item.outerWidth();
const itemHeight = $item.outerHeight();
// Build subcategory HTML
let subcategoryHTML = `
<div class="dune-subcategory-header">${item.name}</div>
<div class="dune-subcategory-items">
`;
item.subcategories.forEach(sub => {
subcategoryHTML += `
<a href="${sub.url}" class="dune-subcategory-item">
<span class="dune-subcategory-name">${sub.name}</span>
</a>
`;
});
subcategoryHTML += `
</div>
<div class="dune-subcategory-footer">
<a href="https://dunedb.com/${item.id}" class="dune-subcategory-all">View All ${item.name}</a>
</div>
`;
// Update and position the subcategory container
const $subcategoryContainer = $('#duneSubcategoryContainer');
$subcategoryContainer.html(subcategoryHTML);
// Position based on which quadrant the item is in
let top, left;
switch(item.position) {
case 'north':
case 'northeast':
top = itemOffset.top + itemHeight + 10;
left = itemOffset.left - 100 + (itemWidth / 2);
break;
case 'east':
top = itemOffset.top - 50;
left = itemOffset.left + itemWidth + 10;
break;
case 'southeast':
case 'south':
top = itemOffset.top - 120;
left = itemOffset.left - 100 + (itemWidth / 2);
break;
case 'southwest':
case 'west':
top = itemOffset.top - 50;
left = itemOffset.left - 170;
break;
case 'northwest':
top = itemOffset.top + itemHeight + 10;
left = itemOffset.left - 100;
break;
default:
top = itemOffset.top + itemHeight + 10;
left = itemOffset.left;
}
// Apply position
$subcategoryContainer.css({
top: top + 'px',
left: left + 'px'
}).addClass('active');
// Prevent event from closing the main menu
event.stopPropagation();
};
// Hide subcategories
const hideSubcategories = () => {
$('#duneSubcategoryContainer').removeClass('active');
$('.dune-radial-item').removeClass('selected');
};
// Toggle menu when clicking the logo button
$(document).on('click', '#duneLogoBtn', function(e) {
e.preventDefault();
e.stopPropagation();
if ($('#duneRadialMenu').hasClass('active')) {
closeMenu();
} else {
openMenu();
}
});
// Handle item click to show subcategories
$(document).on('click', '.dune-radial-item', function(e) {
e.preventDefault();
e.stopPropagation();
const itemId = $(this).data('id');
// If already selected, hide subcategories
if ($(this).hasClass('selected')) {
hideSubcategories();
} else {
showSubcategories(itemId, e);
}
});
// Close subcategories when clicking anywhere else in the radial menu
$(document).on('click', '#duneRadialMenu', function(e) {
if (!$(e.target).closest('.dune-radial-item').length) {
hideSubcategories();
}
});
// Close when clicking overlay
$(document).on('click', '#duneRadialOverlay', function() {
closeMenu();
});
// Close menu with ESC key
$(document).on('keydown', function(e) {
if (e.key === 'Escape') {
if ($('#duneSubcategoryContainer').hasClass('active')) {
hideSubcategories();
} else if ($('#duneRadialMenu').hasClass('active')) {
closeMenu();
}
}
});
});