const menuData = [
{ text: "TOP", link: "index.html" },
{ text: "MESSAGE", link: "#Message" },
{ text: "MOVIE", link: "#Movie" },
//{ text: "NEWS", link: "#News" },
{ text: "TVPROGRAM", link: "tvprogram.html" },
{ text: "EVENT", link: "event.html" },
{ text: "HISTORY", link: "history.html" },
{ text: "CAMPAIGN", link: "#Campaign" }
];
Vue.createApp({
components: {
"header-component": {
template: `
`,
data() {
return {
isOpen: false,
menuItems: menuData,
isTopPage: window.location.pathname.endsWith("index.html") || window.location.pathname === "/"
};
},
computed: {
computedMenuItems() {
return this.menuItems.map(item => {
if (item.link.startsWith("#")) {
return {
...item,
link: this.isTopPage ? item.link : "index.html" + item.link
};
}
return item;
});
}
},
methods: {
toggleMenu() {
this.isOpen = !this.isOpen;
},
closeMenu() {
this.isOpen = false;
},
handleClick(link) {
if (this.isTopPage && link.startsWith("#")) {
const target = document.querySelector(link);
if (target) {
window.scrollTo({ top: target.offsetTop, behavior: "smooth" });
this.closeMenu(); // ページ内リンククリック時にメニューを閉じる
}
} else {
window.location.href = link;
}
}
}
},
"footer-component": {
template: `
`,
data() {
return {
menuItems: menuData,
isTopPage: window.location.pathname.endsWith("index.html") || window.location.pathname === "/"
};
},
computed: {
computedMenuItems() {
return this.menuItems.map(item => {
if (item.link.startsWith("#")) {
return {
...item,
link: this.isTopPage ? item.link : "index.html" + item.link
};
}
return item;
});
}
},
methods: {
handleClick(link) {
if (this.isTopPage && link.startsWith("#")) {
const target = document.querySelector(link);
if (target) {
window.scrollTo({ top: target.offsetTop, behavior: "smooth" });
}
} else {
window.location.href = link;
}
}
}
},
"subpage-header": {
props: ["title", "bgImage"],
template: `
`
}
},
data() {
return {
eventArticles: [], // JSON から読み込む
programArticles: [], // JSON から読み込む
historyData: [], // JSON から読み込む
currentIndexes: {}, // 各年のスライド用インデックス
currentYear: null, // 現在のアクティブな年代
observer: null, // IntersectionObserver
manuallySelected: false, // クリック時の制御
lastYear: null // 直前のアクティブ状態を保持
};
},
methods: {
async loadHistoryData() {
try {
const response = await fetch('./data/historyData.json');
const data = await response.json();
this.historyData = data;
this.initImageIndexes();
this.$nextTick(() => {
this.initScrollAnimation();
this.startSlideshow();
});
} catch (error) {
console.error("historyData の取得に失敗しました:", error);
}
},
async loadArticleData() {
try {
const [eventRes, programRes] = await Promise.all([
fetch('./data/eventArticles.json'),
fetch('./data/programArticles.json')
]);
const eventData = await eventRes.json();
const programData = await programRes.json();
const today = new Date();
let filteredEvents = [];
eventData.forEach(monthData => {
let validEvents = monthData.events.filter(event => event.timelimit && new Date(event.timelimit) >= today);
if (validEvents.length) {
filteredEvents.push({
month: monthData.month, // 月情報を保持
events: validEvents.sort((a, b) => new Date(a.timelimit) - new Date(b.timelimit))
});
}
});
this.eventArticles = filteredEvents;
this.programArticles = programData;
} catch (error) {
console.error("イベント・番組データの取得に失敗しました:", error);
}
},
initImageIndexes() {
// 各年ごとに、events の数だけ画像スライド用インデックスを初期化
this.currentIndexes = {};
this.historyData.forEach(yearData => {
// yearData.events は複数の出来事の配列
this.currentIndexes[yearData.year] = yearData.events.map(() => 0);
});
},
startSlideshow() {
setInterval(() => {
this.historyData.forEach(yearData => {
const year = yearData.year;
yearData.events.forEach((event, idx) => {
if (event.images && event.images.length > 1) {
this.currentIndexes[year][idx] = (this.currentIndexes[year][idx] + 1) % event.images.length;
}
});
});
}, 2000); // 2秒ごとに画像を切り替え
},
initScrollAnimation() {
let elements = document.querySelectorAll(".js-historybox_animation");
if (elements.length === 0) return;
let showTiming = window.innerHeight > 768 ? 100 : 40;
function showElementAnimation() {
let scrollY = window.scrollY;
let windowH = window.innerHeight;
elements.forEach(el => {
let elemY = el.getBoundingClientRect().top + scrollY;
if (scrollY + windowH - showTiming > elemY) {
el.classList.add("is-show");
} else if (scrollY + windowH < elemY) {
el.classList.remove("is-show");
}
});
}
showElementAnimation();
window.addEventListener("scroll", showElementAnimation);
},
handleScroll() {
this.initScrollAnimation();
},
updateCurrentYear() {
if (this.manuallySelected) return; // クリック時はスクロールの影響を防ぐ
let scrollY = window.scrollY;
let closestYear = null;
let minDiff = Infinity;
document.querySelectorAll('[id^="y_"]').forEach(el => {
const year = parseInt(el.id.replace("y_", ""), 10);
const top = el.getBoundingClientRect().top + window.scrollY; // 要素のY座標取得
const diff = Math.abs(scrollY - top + 100); // +100pxの余裕をもたせる
if (diff < minDiff) {
closestYear = year;
minDiff = diff;
}
});
if (closestYear !== null) {
this.currentYear = closestYear;
}
}
},
computed: {
// groupedHistoryData は、historyData をそのままオブジェクト化する
groupedHistoryData() {
let grouped = {};
this.historyData.forEach(item => {
grouped[item.year] = item;
});
return grouped;
},
latestProgramArticles() {
return this.programArticles.slice(0, 3); // 最新の3つだけ取得
},
latestEventArticles() {
let allEvents = [];
this.eventArticles.forEach(monthData => {
allEvents = allEvents.concat(monthData.events);
});
return allEvents.slice(0, 3); // 最新3件のみ取得
}
},
mounted() {
window.addEventListener("scroll", this.handleScroll);
window.addEventListener("scroll", this.updateCurrentYear, { passive: true });
this.loadHistoryData();
this.loadArticleData();
this.$nextTick(() => {
this.initScrollAnimation();
});
},
beforeUnmount() {
window.removeEventListener("scroll", this.updateCurrentYear);
}
}).mount("#app");