diff --git a/js/core/pathsController.js b/js/core/pathsController.js
index 88c26e2..8f8c85c 100644
--- a/js/core/pathsController.js
+++ b/js/core/pathsController.js
@@ -2,18 +2,16 @@ window.PathsController = (function () {
function togglePath(characterName) {
const paths = AppState.LIST_PATHS;
+ const currentSeason = SeasonController.getCurrentSeason();
- // ADD (animate)
if (!paths[characterName]) {
const layer = L.layerGroup(
- getPolylinesFromName(characterName),
+ getPolylinesFromName(characterName, currentSeason.id),
{ snakingPause: AppState.PATH_SPEED_ANIMATION }
).addTo(MapController.map);
- layer.snakeIn(); // Animate only on first add
+ layer.snakeIn(); // animate first add
paths[characterName] = layer;
-
- // REMOVE
} else {
paths[characterName].removeFrom(MapController.map);
delete paths[characterName];
@@ -23,32 +21,24 @@ window.PathsController = (function () {
MarkersController.addMarkers();
}
- // INSTANT refresh — NO animation
function refreshTimelinePaths() {
- const season = SeasonController.getCurrentSeason();
+ const currentSeason = SeasonController.getCurrentSeason();
Object.keys(AppState.LIST_PATHS).forEach(characterName => {
AppState.LIST_PATHS[characterName].removeFrom(MapController.map);
- AppState.LIST_PATHS[characterName] =
- L.layerGroup(getPolylinesFromName(characterName, season))
- .addTo(MapController.map);
+ AppState.LIST_PATHS[characterName] = L.layerGroup(
+ getPolylinesFromName(characterName, currentSeason.id)
+ ).addTo(MapController.map);
});
MarkersController.clearMarkers();
MarkersController.addMarkers();
}
- function getPolylinesFromName(characterName, season = SeasonController.getCurrentSeason()) {
+ function getPolylinesFromName(characterName, seasonId) {
const filteredPaths = DATA_PATHS.paths.filter(p =>
p.character === characterName &&
- (
- (p.season === season.id &&
- p.episode >= AppState.CURRENT_RANGE[0] &&
- p.episode <= AppState.CURRENT_RANGE[1])
- ||
- // Movies (season.id >= 100)
- (season.id >= 100 && p.season === season.id)
- )
+ (p.season === seasonId || p.season >= 100) // movies remain included
);
const color = DATA_PATHS.characters.find(c => c.name === characterName).color;
@@ -65,4 +55,4 @@ window.PathsController = (function () {
return { togglePath, refreshTimelinePaths };
-})();
\ No newline at end of file
+})();
diff --git a/js/core/seasonController.js b/js/core/seasonController.js
index ebb1e53..e1fc55f 100644
--- a/js/core/seasonController.js
+++ b/js/core/seasonController.js
@@ -1,34 +1,3 @@
-const DATA_SEASONS = [
- {
- id: 1,
- name: "Rings of Power - Season 1",
- episodes: 8,
- characters: ["Arondir","Elendil","Elrond","Galadriel","Halbrand","Nori"],
- markersRelevant: marker => marker.episodes.some(e => e.season === 1)
- },
- {
- id: 2,
- name: "Rings of Power - Season 2",
- episodes: 8,
- characters: ["Galadriel","Arondir"], // add more for S2
- markersRelevant: marker => marker.episodes.some(e => e.season === 2)
- },
- {
- id: 100,
- name: "The Lord of the Rings (Movies)",
- episodes: 1,
- characters: ["Frodo and Sam"],
- markersRelevant: marker => marker.episodes.some(e => e.season === 100 || e.season === 101)
- },
- {
- id: 104,
- name: "The Hobbit (Movies)",
- episodes: 1,
- characters: ["Bilbo and Thorin"],
- markersRelevant: marker => marker.episodes.some(e => e.season === 100 || e.season === 101)
- }
-];
-
window.SeasonController = (function () {
const seasonSelect = document.getElementById('seasonSelect');
From ea8a1c5a3bc7152ce0398f3e0ee22423574b7efd Mon Sep 17 00:00:00 2001
From: Rhys18751996 <18751996@student.westernsydney.edu.au>
Date: Thu, 18 Dec 2025 12:17:00 +1100
Subject: [PATCH 07/39] extracting season data into data folder and getting
season dropdown to trigger event when selection changing
---
js/core/markersController.js | 4 ++--
js/main.js | 29 +++++++++++++++++++----------
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/js/core/markersController.js b/js/core/markersController.js
index 3e41379..2a0e1b0 100644
--- a/js/core/markersController.js
+++ b/js/core/markersController.js
@@ -39,8 +39,8 @@ window.MarkersController = (function () {
${marker.decription}
Seen in: ${marker.episodes.map(e => {
- if (e.season === 100) return "Lord Of The Rings (Movie)";
- if (e.season === 101) return "The Hobbit (Movie)";
+ if (e.season === 100) return "The Lord of the Rings (Movies)";
+ if (e.season === 104) return "The Hobbit (Movies)";
return `S0${e.season}E0${e.episode}`;
}).join(", ")}
diff --git a/js/main.js b/js/main.js
index 896cd1e..0d86a29 100644
--- a/js/main.js
+++ b/js/main.js
@@ -1,21 +1,30 @@
-// attach handlers globally so HTML inline handlers still work
+// ==============================
+// Global Handlers for Inline HTML
+// ==============================
+
+// These handlers are attached to the global `window` object so that
+// any inline HTML event attributes (e.g., onclick="setPath(this)")
+// can still call these functions directly from the DOM.
+
+// Toggles a character's path on the map when the corresponding button or element is clicked
window.setPath = (element) => PathsController.togglePath(element.name);
+
+// Show or hide UI panels or elements
window.hideshow = UIController.hideshow;
+
+// Display contextual labels or tooltips for interactions
window.interactionLabel = UIController.interactionLabel;
+// Handles season changes from the dropdown select element
+// Converts the selected value to a number and passes it to the SeasonController
window.seasonChange = (seasonId) => {
SeasonController.selectSeason(Number(seasonId));
};
+// Handles timeline range changes (e.g., from a slider control)
+// Updates the current visible episode range in the AppState
+// and refreshes the map paths to only show the paths in that range
window.timelineChange = (range) => {
AppState.CURRENT_RANGE = range;
PathsController.refreshTimelinePaths();
-};
-
-
-
-
-// Initialize SeasonController after DOM ready
-document.addEventListener('DOMContentLoaded', () => {
- SeasonController.initDropdown();
-});
\ No newline at end of file
+};
\ No newline at end of file
From 4409fa97bf4aded0b7edcdafdbadc1dda45a65c7 Mon Sep 17 00:00:00 2001
From: Rhys18751996 <18751996@student.westernsydney.edu.au>
Date: Thu, 18 Dec 2025 12:24:41 +1100
Subject: [PATCH 08/39] markersController commenting generated
---
js/core/markersController.js | 59 ++++++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 12 deletions(-)
diff --git a/js/core/markersController.js b/js/core/markersController.js
index 2a0e1b0..35630b9 100644
--- a/js/core/markersController.js
+++ b/js/core/markersController.js
@@ -1,27 +1,53 @@
+// ==============================
+// MarkersController
+// ==============================
+// Manages the creation, display, and removal of markers on the map.
+// Markers are filtered by the currently selected season and displayed
+// using Leaflet with custom icons and popups.
+
window.MarkersController = (function () {
+ // ------------------------------
+ // clearMarkers()
+ // ------------------------------
+ // Removes all currently displayed markers from the map and
+ // clears the list of markers in AppState.
function clearMarkers() {
+ // Remove each marker from the map
AppState.LIST_MARKERS.forEach(marker => marker.removeFrom(MapController.map));
+
+ // Clear the array holding references to markers
AppState.LIST_MARKERS.length = 0;
}
+ // ------------------------------
+ // addMarkers()
+ // ------------------------------
+ // Adds markers to the map based on the currently selected season.
+ // Only markers relevant to the selected season are displayed.
function addMarkers() {
+ // Get the currently selected season
const currentSeason = SeasonController.getCurrentSeason();
+ // Loop through all markers defined in DATA_MARKERS
DATA_MARKERS.markers.forEach(marker => {
- // Only include markers relevant to current season
+ // Skip markers that are not relevant to the current season
if (!currentSeason.markersRelevant(marker)) return;
+ // Find marker type information (icon, size, anchor points)
const type = DATA_MARKERS.types.find(t => t.name === marker.type);
+
+ // Create a Leaflet marker at the marker's coordinates
const leafletMarker = L.marker(marker.coordinates, {
icon: L.icon({
- iconUrl: `img/markers/${type.icon}`,
- iconSize: type.iconSize,
- iconAnchor: type.iconAnchor,
- popupAnchor: type.popupAnchor
+ iconUrl: `img/markers/${type.icon}`, // path to the icon image
+ iconSize: type.iconSize, // size of the icon
+ iconAnchor: type.iconAnchor, // anchor point for the icon
+ popupAnchor: type.popupAnchor // anchor point for the popup
}),
- title: marker.title
+ title: marker.title // tooltip title when hovering over the marker
}).bindPopup(
+ // HTML content for the popup
`