feat:map頁面
This commit is contained in:
@@ -1,31 +1,188 @@
|
|||||||
<!-- 成員切換標籤 -->
|
<!DOCTYPE html>
|
||||||
<nav class="member-tabs">
|
<html lang="zh-TW">
|
||||||
<button class="tab-btn active">殷志源 (Eun Ji Won)</button>
|
|
||||||
<button class="tab-btn">高志溶 (Ko Ji Yong)</button>
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>SECHSKIES 台灣行程地圖</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<!-- 備註:本頁一定要是完整 HTML 文件(含 head 與 style.css),
|
||||||
|
否則會變成瀏覽器的「片段模式」,樣式常常吃不到或跑版。 -->
|
||||||
|
<header class="map-archive-header">
|
||||||
|
<div class="header-inner">
|
||||||
|
<h1 class="main-title">台灣行程列表</h1>
|
||||||
|
<div class="subtitle-wrap">
|
||||||
|
<span class="sub-title">SECHSKIES TAIWAN ARCHIVE</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<nav class="member-tabs" aria-label="成員篩選">
|
||||||
|
<button class="tab-btn active" data-member="all" aria-pressed="true">全部行程</button>
|
||||||
|
<button class="tab-btn" data-member="eun" aria-pressed="false">殷志源來台灣</button>
|
||||||
|
<button class="tab-btn" data-member="ko" aria-pressed="false">高志溶來台灣</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<main class="content-container">
|
<main class="content-container map-layout">
|
||||||
<!-- 左側固定地圖 -->
|
<!-- 備註:地圖區固定使用你的 Google My Maps iframe。
|
||||||
|
這裡不改地圖資料來源,右側列表只負責敘事與導覽。 -->
|
||||||
<section class="map-sticky">
|
<section class="map-sticky">
|
||||||
<iframe src="https://www.google.com/maps/d/embed?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw&hl=zh-TW&ehbc=2E312F"
|
<h2 class="map-title">水晶男孩台灣行程地圖</h2>
|
||||||
width="100%" height="450"></iframe>
|
<iframe id="member-map" title="SECHSKIES 踩點地圖" loading="lazy" referrerpolicy="no-referrer-when-downgrade"
|
||||||
|
src="https://www.google.com/maps/d/embed?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw&hl=zh-TW&ehbc=2E312F">
|
||||||
|
</iframe>
|
||||||
|
<a id="open-map-link" class="map-link" target="_blank"
|
||||||
|
href="https://www.google.com/maps/d/u/0/viewer?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw">
|
||||||
|
在 Google My Maps 開啟完整地圖
|
||||||
|
</a>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- 右側拍立得清單 -->
|
|
||||||
<section class="itinerary-list">
|
<section class="itinerary-list">
|
||||||
<!-- 拍立得卡片 -->
|
<!-- 備註:每張卡的 data-* 是「細節面板的資料來源」。
|
||||||
<article class="polaroid-card">
|
你只要改 data-date/title/desc/quote/tag/link 和圖片,就會同步更新下方介紹。 -->
|
||||||
|
<article class="polaroid-card active" data-member="eun" data-date="2024.05.07" data-title="松山文創園區"
|
||||||
|
data-desc="節目中先從文創園區開始散步,邊走邊聊當年活動與舞台記憶,畫面節奏偏溫暖。" data-quote="這種慢慢走的行程,反而最像真正的旅行。" data-tag="#殷志源 #散步 #文創"
|
||||||
|
data-link="https://maps.google.com/?q=25.0441,121.5600">
|
||||||
<div class="photo-frame">
|
<div class="photo-frame">
|
||||||
<img src="節目截圖.jpg" alt="景點名稱">
|
<img src="https://picsum.photos/seed/eun-songshan/640/420" alt="殷志源台灣行程節目截圖-松山文創園區">
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<span class="date">2024.05.07</span>
|
<span class="date">2024.05.07</span>
|
||||||
<h3>景點名稱(如:台北101)</h3>
|
<h3>松山文創園區</h3>
|
||||||
<p class="description">這裡可以放入節目的細節介紹,例如在那裡做了什麼、說了什麼話...</p>
|
<p class="description">台灣行程 Day 1 開場站。</p>
|
||||||
<div class="tag">#踩點成功</div>
|
<div class="tag">#殷志源 #散步</div>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<!-- 更多卡片... -->
|
<article class="polaroid-card" data-member="eun" data-date="2024.05.07" data-title="西門町"
|
||||||
|
data-desc="晚上切到人潮密集區,街訪片段和店家互動比較多,節目情緒從安靜轉為熱鬧。" data-quote="台北晚上真的很有自己的節奏。" data-tag="#殷志源 #西門町 #夜晚"
|
||||||
|
data-link="https://maps.google.com/?q=25.0422,121.5082">
|
||||||
|
<div class="photo-frame">
|
||||||
|
<img src="https://picsum.photos/seed/eun-ximen/640/420" alt="殷志源台灣行程節目截圖-西門町">
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<span class="date">2024.05.08</span>
|
||||||
|
<h3>西門町</h3>
|
||||||
|
<p class="description">台灣行程 Day 1 晚間站。</p>
|
||||||
|
<div class="tag">#殷志源 #街拍</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="polaroid-card" data-member="ko" data-date="2024.05.09" data-title="大稻埕"
|
||||||
|
data-desc="以老街與街屋景觀為主,搭配市場片段,節目內容著重生活感和在地氛圍。" data-quote="這裡很像可以慢慢逛一整天。" data-tag="#高志溶 #老街 #在地"
|
||||||
|
data-link="https://maps.google.com/?q=25.0560,121.5095">
|
||||||
|
<div class="photo-frame">
|
||||||
|
<img src="https://picsum.photos/seed/ko-dadaocheng/640/420" alt="高志溶台灣行程節目截圖-大稻埕">
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<span class="date">2024.05.09</span>
|
||||||
|
<h3>大稻埕</h3>
|
||||||
|
<p class="description">高志溶台灣行程主線起點。</p>
|
||||||
|
<div class="tag">#高志溶 #老街</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="polaroid-card" data-member="ko" data-date="2024.05.10" data-title="信義商圈"
|
||||||
|
data-desc="晚間景觀和商圈路線交錯,補足都市感,和大稻埕形成新舊對比。" data-quote="白天走舊城,晚上看新城,剛剛好。" data-tag="#高志溶 #信義 #都會"
|
||||||
|
data-link="https://maps.google.com/?q=25.0339,121.5654">
|
||||||
|
<div class="photo-frame">
|
||||||
|
<img src="https://picsum.photos/seed/ko-xinyi/640/420" alt="高志溶台灣行程節目截圖-信義商圈">
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<span class="date">2024.05.10</span>
|
||||||
|
<h3>信義商圈</h3>
|
||||||
|
<p class="description">高志溶台灣行程晚間收尾站。</p>
|
||||||
|
<div class="tag">#高志溶 #都會</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<article class="detail-panel" id="detail-panel" aria-live="polite">
|
||||||
|
<div class="detail-photo">
|
||||||
|
<img id="detail-image" src="https://picsum.photos/seed/eun-songshan/900/520" alt="行程節目截圖">
|
||||||
|
</div>
|
||||||
|
<div class="detail-content">
|
||||||
|
<span id="detail-date" class="date">2024.05.07</span>
|
||||||
|
<h3 id="detail-title">松山文創園區</h3>
|
||||||
|
<p id="detail-desc">節目中先從文創園區開始散步,邊走邊聊當年活動與舞台記憶,畫面節奏偏溫暖。</p>
|
||||||
|
<blockquote id="detail-quote">「這種慢慢走的行程,反而最像真正的旅行。」</blockquote>
|
||||||
|
<div id="detail-tag" class="tag">#殷志源 #散步 #文創</div>
|
||||||
|
<a id="detail-link" class="detail-link" target="_blank"
|
||||||
|
href="https://maps.google.com/?q=25.0441,121.5600">查看此地點</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
// 備註:tab 控制「顯示哪些卡片」,card 控制「細節面板顯示哪一筆」。
|
||||||
|
const tabs = Array.from(document.querySelectorAll(".tab-btn"));
|
||||||
|
const cards = Array.from(document.querySelectorAll(".polaroid-card"));
|
||||||
|
const detailDate = document.getElementById("detail-date");
|
||||||
|
const detailTitle = document.getElementById("detail-title");
|
||||||
|
const detailDesc = document.getElementById("detail-desc");
|
||||||
|
const detailQuote = document.getElementById("detail-quote");
|
||||||
|
const detailTag = document.getElementById("detail-tag");
|
||||||
|
const detailLink = document.getElementById("detail-link");
|
||||||
|
const detailImage = document.getElementById("detail-image");
|
||||||
|
|
||||||
|
function setActiveCard(card) {
|
||||||
|
cards.forEach((item) => item.classList.remove("active"));
|
||||||
|
card.classList.add("active");
|
||||||
|
|
||||||
|
// 備註:把卡片 data-* 內容灌到 detail-panel。
|
||||||
|
detailDate.textContent = card.dataset.date || "";
|
||||||
|
detailTitle.textContent = card.dataset.title || "";
|
||||||
|
detailDesc.textContent = card.dataset.desc || "";
|
||||||
|
detailQuote.textContent = "「" + (card.dataset.quote || "") + "」";
|
||||||
|
detailTag.textContent = card.dataset.tag || "";
|
||||||
|
detailLink.href = card.dataset.link || "#";
|
||||||
|
detailImage.src = card.querySelector("img").src;
|
||||||
|
detailImage.alt = "節目截圖 - " + (card.dataset.title || "行程地點");
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyFilter(member) {
|
||||||
|
let firstVisible = null;
|
||||||
|
cards.forEach((card) => {
|
||||||
|
const matched = member === "all" || card.dataset.member === member;
|
||||||
|
card.style.display = matched ? "" : "none";
|
||||||
|
if (matched && !firstVisible) firstVisible = card;
|
||||||
|
});
|
||||||
|
// 備註:切換成員後,自動選中第一張可見卡,避免細節區停留在舊資料。
|
||||||
|
if (firstVisible) setActiveCard(firstVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
tabs.forEach((tab) => {
|
||||||
|
tab.addEventListener("click", () => {
|
||||||
|
tabs.forEach((item) => {
|
||||||
|
item.classList.remove("active");
|
||||||
|
item.setAttribute("aria-pressed", "false");
|
||||||
|
});
|
||||||
|
tab.classList.add("active");
|
||||||
|
tab.setAttribute("aria-pressed", "true");
|
||||||
|
applyFilter(tab.dataset.member);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cards.forEach((card) => {
|
||||||
|
card.addEventListener("click", () => {
|
||||||
|
setActiveCard(card);
|
||||||
|
if (window.innerWidth < 920) {
|
||||||
|
const detail = document.getElementById("detail-panel");
|
||||||
|
detail.scrollIntoView({ behavior: "smooth", block: "start" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstVisibleCard = cards.find((card) => card.style.display !== "none");
|
||||||
|
if (firstVisibleCard) setActiveCard(firstVisibleCard);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -435,3 +435,279 @@ footer {
|
|||||||
color: var(--dark-yellow);
|
color: var(--dark-yellow);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* map.html */
|
||||||
|
.map-archive-header {
|
||||||
|
text-align: center;
|
||||||
|
padding: 90px 20px 38px;
|
||||||
|
background: #fcfaf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-archive-header .main-title {
|
||||||
|
font-size: clamp(2rem, 4.5vw, 3.2rem);
|
||||||
|
font-weight: 900;
|
||||||
|
color: #333;
|
||||||
|
letter-spacing: 8px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-archive-header .subtitle-wrap {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-archive-header .subtitle-wrap::before,
|
||||||
|
.map-archive-header .subtitle-wrap::after {
|
||||||
|
height: 3px;
|
||||||
|
background-color: #ffcc00;
|
||||||
|
max-width: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-archive-header .sub-title {
|
||||||
|
font-size: 0.96rem;
|
||||||
|
letter-spacing: 4px;
|
||||||
|
color: #8a8a8a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-layout {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(320px, 40%) minmax(0, 1fr);
|
||||||
|
gap: 26px;
|
||||||
|
align-items: start;
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-tabs {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin: 0 auto 14px;
|
||||||
|
max-width: 1100px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn {
|
||||||
|
border: 1px solid #e9d99d;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #4a4a4a;
|
||||||
|
border-radius: 999px;
|
||||||
|
padding: 9px 18px;
|
||||||
|
font-size: 0.93rem;
|
||||||
|
font-weight: 700;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn:hover,
|
||||||
|
.tab-btn.active {
|
||||||
|
background: #ffcc00;
|
||||||
|
color: #2f2f2f;
|
||||||
|
border-color: #ffcc00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-sticky {
|
||||||
|
position: sticky;
|
||||||
|
top: 22px;
|
||||||
|
align-self: start;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 18px;
|
||||||
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.07);
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-title {
|
||||||
|
color: #343434;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
margin: 0 0 12px;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#member-map {
|
||||||
|
width: 100%;
|
||||||
|
height: min(66vh, 640px);
|
||||||
|
min-height: 420px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 10px 26px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-link {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #7f6712;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid rgba(127, 103, 18, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.itinerary-list {
|
||||||
|
display: grid;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.polaroid-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 14px;
|
||||||
|
border: 1px solid #f0e9cf;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
background: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease, background 0.18s ease;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.polaroid-card::before {
|
||||||
|
content: "\f111";
|
||||||
|
font-family: "Font Awesome 6 Free";
|
||||||
|
font-weight: 900;
|
||||||
|
position: absolute;
|
||||||
|
right: 12px;
|
||||||
|
top: 10px;
|
||||||
|
color: #ebd37a;
|
||||||
|
font-size: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.polaroid-card:hover,
|
||||||
|
.polaroid-card.active {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
border-color: #f3d56a;
|
||||||
|
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.08);
|
||||||
|
background: #fffdf4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-frame {
|
||||||
|
width: 118px;
|
||||||
|
flex: 0 0 118px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-frame img {
|
||||||
|
width: 100%;
|
||||||
|
height: 86px;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content .date {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.72rem;
|
||||||
|
color: #9a8851;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content h3 {
|
||||||
|
margin: 0 0 3px;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #323232;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content .description {
|
||||||
|
margin: 0 0 6px;
|
||||||
|
font-size: 0.86rem;
|
||||||
|
color: #6a6a6a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content .tag {
|
||||||
|
font-size: 0.76rem;
|
||||||
|
color: #8b7423;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-panel {
|
||||||
|
margin-top: 8px;
|
||||||
|
border: 1px solid #eadfb2;
|
||||||
|
border-radius: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #fffef8;
|
||||||
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-photo img {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 300px;
|
||||||
|
object-fit: cover;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content h3 {
|
||||||
|
margin: 4px 0 10px;
|
||||||
|
color: #2c2c2c;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content p {
|
||||||
|
color: #5a5a5a;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content blockquote {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
background: #fff7da;
|
||||||
|
border-left: 3px solid #f0c02f;
|
||||||
|
color: #65510e;
|
||||||
|
font-size: 0.92rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-link {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #7b6215;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 1px solid rgba(123, 98, 21, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 920px) {
|
||||||
|
.map-archive-header {
|
||||||
|
padding: 76px 16px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-archive-header .main-title {
|
||||||
|
letter-spacing: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-layout {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-sticky {
|
||||||
|
position: static;
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#member-map {
|
||||||
|
height: 320px;
|
||||||
|
min-height: 320px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.polaroid-card {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-frame {
|
||||||
|
width: 100%;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-frame img {
|
||||||
|
height: 170px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
padding: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user