杜甫的一生行迹
李白的一生行迹

白居易的一生,是文人从理想主义到现实主义的转变史

发布日期:2025-09-22 13:37:00   浏览量 :0
发布日期:2025-09-22 13:37:00  
0

<!DOCTYPE html>

<html lang="zh-CN">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta name="description" content="沉浸式体验白居易一生的行迹与诗歌创作历程">

    <title>诗魔白居易一生行迹 - 沉浸式文化体验</title>

    <!-- 使用本地Leaflet库 -->

    <link rel="stylesheet" href="leaflet.css">

    <style>

        /* 手动添加一些基础的Leaflet控件样式以确保功能完整 */

        .leaflet-control {

            z-index: 800;

        }

        .leaflet-control-zoom {

            background-color: rgba(255, 255, 255, 0.8);

            border-radius: 4px;

            box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);

        }

        .leaflet-control-zoom-in,

        .leaflet-control-zoom-out {

            width: 30px;

            height: 30px;

            text-align: center;

            line-height: 30px;

            color: #333;

            background-color: white;

            border: none;

            cursor: pointer;

        }

    </style>

    <style>

        * {

            margin: 0;

            padding: 0;

            box-sizing: border-box;

        }

        

        body {

            font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;

            background-color: #f5f5f5;

            line-height: 1.6;

            color: #333;

            overflow-x: hidden;

        }

        

        header {

            position: fixed;

            top: 0;

            left: 0;

            right: 0;

            background-color: rgba(255, 255, 255, 0.95);

            padding: 15px;

            text-align: center;

            font-size: 24px;

            font-weight: bold;

            color: #333;

            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

            z-index: 1000;

            backdrop-filter: blur(5px);

        }

        

        #mapLoader {

            position: fixed;

            top: 0;

            left: 0;

            width: 100%;

            height: 100%;

            display: flex;

            flex-direction: column;

            align-items: center;

            justify-content: center;

            background-color: white;

            z-index: 9999;

            transition: opacity 0.5s ease-out;

        }

        

        .loader-spinner {

            width: 50px;

            height: 50px;

            border: 5px solid #f3f3f3;

            border-top: 5px solid #8B4513;

            border-radius: 50%;

            animation: spin 1s linear infinite;

        }

        

        @keyframes spin {

            0% { transform: rotate(0deg); }

            100% { transform: rotate(360deg); }

        }

        

        #map {

            width: 100vw;

            height: 100vh;

            position: relative;

            margin-top: 60px;

        }

        

        /* 信息卡片样式 - 优化透明度和布局以避免遮挡路径 */

        .info-card {

            position: fixed;

            bottom: 40px;

            left: 50%;

            transform: translateX(-50%) translateY(100%);

            width: 80%;

            max-width: 1200px;

            background-color: rgba(255, 255, 255, 0.5); /* 增加透明度到50% */

            backdrop-filter: blur(12px);

            border-radius: 15px;

            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);

            transition: transform 0.5s ease, max-height 0.5s ease, opacity 0.5s ease;

            z-index: 900;

            display: flex;

            flex-direction: row;

            overflow: hidden;

            cursor: pointer;

            opacity: 0;

        }

        

        .info-card.active {

            opacity: 1;

        }

        

        /* 折叠按钮样式 */

        .collapse-btn {

            position: absolute;

            bottom: 10px;

            left: 50%;

            transform: translateX(-50%);

            width: 40px;

            height: 20px;

            background-color: rgba(255, 255, 255, 0.8);

            border: none;

            border-radius: 10px;

            cursor: pointer;

            display: flex;

            align-items: center;

            justify-content: center;

            transition: all 0.3s ease;

            z-index: 10;

        }

        

        .collapse-btn:hover {

            background-color: rgba(255, 255, 255, 1);

        }

        

        .collapse-btn::before {

            content: '⌄';

            transition: transform 0.3s ease;

        }

        

        .info-card.collapsed .collapse-btn::before {

            transform: rotate(180deg);

        }

        

        /* 折叠状态的信息卡片 */

        .info-card.collapsed {

            max-height: 100px;

        }

        

        .info-card.collapsed .info-content {

            max-height: 60px;

        }

        

        /* 马标志样式 */

        .horse-marker {

            font-size: 40px !important; /* 增加马标志的尺寸,使其更加醒目 */

            text-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);

            transform-origin: center center;

            transition: transform 0.3s ease;

            animation: horseFloat 3s ease-in-out infinite;

        }

        

        @keyframes horseFloat {

            0% { transform: translateY(0px); }

            50% { transform: translateY(-5px); }

            100% { transform: translateY(0px); }

        }

        

        .horse-marker:hover {

            transform: scale(1.3) rotate(5deg);

        }

        

        .info-card.active {

            transform: translateX(-50%) translateY(0);

            opacity: 1;

        }

        

        /* 独立的图片区域 */

        .info-image {

            width: 25%;

            min-width: 150px;

            height: 300px; /* 增加图片高度 */

            object-fit: cover;

            position: relative;

            border-radius: 15px 0 0 15px;

            transition: filter 0.3s ease;

        }

        

        .info-image:hover {

            filter: brightness(1.1);

        }

        

        /* 图片加载动画 */

        .image-loading::after {

            content: '';

            position: absolute;

            top: 0;

            left: -100%;

            width: 50%;

            height: 100%;

            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);

            animation: shimmer 1.5s infinite;

        }

        

        @keyframes shimmer {

            to {

                left: 100%;

            }

        }

        

        /* 独立的内容区域 */

        .info-content {

            padding: 20px;

            width: 75%;

            overflow-y: auto;

            max-height: 300px;

            position: relative;

            transition: max-height 0.5s ease;

        }

        

        /* 内容滚动条样式优化 */

        .info-content::-webkit-scrollbar {

            width: 8px;

        }

        

        .info-content::-webkit-scrollbar-track {

            background: rgba(0, 0, 0, 0.05);

            border-radius: 4px;

        }

        

        .info-content::-webkit-scrollbar-thumb {

            background: rgba(0, 0, 0, 0.2);

            border-radius: 4px;

        }

        

        .info-content::-webkit-scrollbar-thumb:hover {

            background: rgba(0, 0, 0, 0.3);

        }

        

        /* 滚动内容容器 */

        .scroll-container {

            height: 100%;

            overflow-y: auto;

        }

        

        /* 滚动控制按钮 */

        .scroll-control {

            position: absolute;

            bottom: 10px;

            right: 10px;

            display: flex;

            gap: 5px;

        }

        

        .scroll-btn {

            width: 30px;

            height: 30px;

            border-radius: 50%;

            border: none;

            background-color: rgba(255, 255, 255, 0.8);

            cursor: pointer;

            display: flex;

            align-items: center;

            justify-content: center;

            font-size: 14px;

            transition: background-color 0.3s;

        }

        

        .scroll-btn:hover {

            background-color: rgba(255, 255, 255, 1);

        }

        

        .info-title {

            font-size: 36px;

            margin-bottom: 12px;

            color: #333;

            text-align: center;

            font-weight: bold;

            text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);

            letter-spacing: 0.5px;

        }

        

        .info-year {

            font-size: 16px;

            color: #666;

            margin-bottom: 15px;

            padding-bottom: 10px;

            border-bottom: 1px solid #eee;

            text-align: center;

            font-style: italic;

        }

        

        .info-description {

            margin-bottom: 20px;

            line-height: 2.0;

            font-size: 25px;

            color: #333;

            text-indent: 2em;

            letter-spacing: 0.8px;

        }

        

        /* 优化诗句样式 */

        .info-poem {

            color: #8B4513;

            margin-bottom: 15px;

            padding: 15px;

            background-color: #FFF8DC;

            border-radius: 10px;

            font-style: italic;

            border-left: 4px solid #8B4513;

            box-shadow: 0 2px 8px rgba(139, 69, 19, 0.1);

        }

        

        /* 双语文字样式优化 */

        .bilingual-text {

            margin-bottom: 10px;

        }

        

        .chinese-text {

            font-family: 'Microsoft YaHei', 'PingFang SC', serif;

            font-size: 25px;

            color: #333;

            line-height: 2.0;

            margin-bottom: 12px;

            letter-spacing: 0.8px;

        }

        

        .english-text {

            font-family: 'Times New Roman', serif;

            font-size: 20px;

            color: #555;

            line-height: 1.8;

            font-style: italic;

            letter-spacing: 0.5px;

        }

        

        .bilingual-item {

            margin-bottom: 15px;

        }

        

        .lang-label {

            font-weight: bold;

            color: #8B4513;

            margin-bottom: 5px;

            font-size: 14px;

        }

        

        /* 标题动画效果 */

        .title-animation {

            animation: fadeInScale 1s ease-out;

        }

        

        @keyframes fadeInScale {

            0% { opacity: 0; transform: scale(0.9); }

            100% { opacity: 1; transform: scale(1); }

        }

        

        /* 高亮诗句样式 */

        .poem-highlight {

            background-color: rgba(139, 69, 19, 0.05);

            padding: 10px;

            border-radius: 8px;

            border-left: 4px solid #8B4513;

        }

        

        /* 诗题样式 */

        .poem-title {

            font-weight: bold;

            font-size: 18px;

            margin-bottom: 10px;

            color: #8B4513;

            text-align: center;

            font-style: normal;

            letter-spacing: 1px;

        }

        

        .info-close {

                position: absolute;

                top: 10px;

                right: 10px;

                width: 30px;

            height: 30px;

            background-color: rgba(0, 0, 0, 0.2);

            color: white;

            border: none;

            border-radius: 50%;

            font-size: 18px;

            cursor: pointer;

            display: flex;

            align-items: center;

            justify-content: center;

            transition: background-color 0.3s;

        }

        

        .info-close:hover {

            background-color: rgba(0, 0, 0, 0.4);

        }

        

        /* 控制按钮 */

        .controls {

            position: fixed;

            top: 100px;

            right: 20px;

            display: flex;

            flex-direction: column;

            gap: 10px;

            z-index: 1050;

            transition: transform 0.3s ease;

        }

        

        /* 控制按钮提示 */

        .control-btn::after {

            content: attr(data-tooltip);

            position: absolute;

            right: 100%;

            margin-right: 10px;

            background-color: rgba(0, 0, 0, 0.8);

            color: white;

            padding: 5px 10px;

            border-radius: 5px;

            font-size: 12px;

            white-space: nowrap;

            opacity: 0;

            visibility: hidden;

            transition: opacity 0.3s, visibility 0.3s;

        }

        

        .control-btn:hover::after {

            opacity: 1;

            visibility: visible;

        }

        

        .control-btn {

            width: 50px;

            height: 50px;

            border-radius: 50%;

            border: none;

            background-color: rgba(255, 255, 255, 0.9);

            color: #333;

            font-size: 20px;

            cursor: pointer;

            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);

            display: flex;

            align-items: center;

            justify-content: center;

            transition: all 0.3s ease;

            position: relative;

            backdrop-filter: blur(5px);

        }

        

        .control-btn:hover {

            background-color: #fff;

            transform: translateY(-3px);

            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);

        }

        

        /* 阶段颜色指示器 */

        .stage-indicator {

            position: fixed;

            top: 100px;

            left: 0;

            right: 0;

            background-color: rgba(255, 255, 255, 0.95);

            padding: 10px 20px;

            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);

            z-index: 800;

            display: flex;

            justify-content: center;

            align-items: center;

            flex-wrap: wrap;

            gap: 15px;

            backdrop-filter: blur(5px);

            transition: transform 0.3s ease;

        }

        

        .stage-title {

            font-weight: bold;

            color: #333;

            margin-right: 15px;

        }

        

        .stage-colors {

            display: flex;

            flex-wrap: wrap;

            gap: 15px;

            justify-content: center;

        }

        

        .stage-item {

            display: flex;

            align-items: center;

            gap: 8px;

            font-size: 14px;

        }

        

        .stage-color {

            width: 20px;

            height: 20px;

            border-radius: 4px;

            border: 1px solid #ddd;

        }

        

        /* 语言显示区域 - 调整为同时显示双语 */

        .lang-label {

            text-align: right;

            font-size: 12px;

            color: #999;

            margin-bottom: 5px;

        }

        

        .bilingual-item {

            margin-bottom: 15px;

        }

        

        .bilingual-text {

            display: flex;

            flex-direction: column;

            gap: 5px;

        }

        

        .chinese-text {

            font-size: 16px;

            color: #333;

        }

        

        .english-text {

            font-size: 14px;

            color: #666;

            font-style: italic;

        }

        

        /* 移除语言切换按钮 */

        .lang-switch {

            display: none;

        }

        

        /* 回到顶部按钮 */

        .back-to-top {

            position: fixed;

            bottom: 20px;

            right: 20px;

            width: 50px;

            height: 50px;

            border-radius: 50%;

            background-color: rgba(255, 255, 255, 0.9);

            color: #333;

            display: flex;

            align-items: center;

            justify-content: center;

            cursor: pointer;

            opacity: 0;

            visibility: hidden;

            transition: opacity 0.3s, visibility 0.3s, transform 0.3s;

            z-index: 950;

            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);

            backdrop-filter: blur(5px);

        }

        

        .back-to-top.visible {

            opacity: 1;

            visibility: visible;

        }

        

        .back-to-top:hover {

            transform: translateY(-3px);

            background-color: white;

        }

        

        /* 加载进度条 */

        .progress-bar {

            position: fixed;

            top: 60px;

            left: 0;

            height: 4px;

            background: linear-gradient(90deg, #E6A641, #83A6ED, #E68C41, #41E6A6, #8341E6, #A641E6);

            width: 0%;

            z-index: 1001;

            transition: width 0.3s ease;

        }

        

        /* 适配移动端 */

        @media(max-width:768px){

            header {

                font-size: 20px;

                padding: 12px;

            }

            

            .info-card {flex-direction:column; left: 5%; right: 5%;}

            .info-image {width:100%;height:200px}

            .info-content {max-height:40vh; width: 100%;}

            .controls {top: auto; bottom: 150px; right: 20px; flex-direction: row;}

            .stage-indicator {top: auto; bottom: 220px; left: 20px; right: 20px;}

            .stage-colors {flex-direction: row; flex-wrap: wrap;}

            

            /* 移动端触摸优化 */

            .control-btn {

                width: 60px;

                height: 60px;

                font-size: 24px;

            }

        }

    </style>

</head>

<body>

<header>

    <div style="font-size: 36px; font-weight: bold; color: #333; margin-bottom: 5px; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);">

        诗魔白居易,乐天知命,笔写民生疾苦讽喻时弊

    </div>

    <div style="font-size: 14px; color: #666; font-style: italic;">

        浏览器搜索'唐诗.中国'中文域名查看完整版

    </div>

</header>

<div class="progress-bar" id="progressBar"></div>

<div id="mapLoader">

  <div class="loader-spinner"></div>

  <span>加载中…</span>

  <div style="margin-top: 10px; font-size: 14px; color: #666;">正在准备白居易的精彩人生旅程</div>

</div>

<div id="map"></div>


<!-- 信息卡片 -->

    <div id="infoCard" class="info-card">

      <img id="infoImage" class="info-image" src="" alt="" loading="lazy">

      <div class="info-content">

        <!-- 语言切换按钮 -->

        <div class="lang-switch">

            <button id="btnZh" class="lang-btn active">中文</button>

            <button id="btnEn" class="lang-btn">English</button>

        </div>

        

        <h3 id="infoTitle" class="info-title"></h3>

        <div id="infoYear" class="info-year"></div>

        <div id="infoDescription" class="info-description"></div>

        <div id="infoPoem" class="info-poem"></div>

        <div id="infoAnecdote" class="info-description"></div>

      </div>

      <button class="info-close" onclick="hideInfoCard()">&times;</button>

      <div class="scroll-control">

        <button id="pauseScrollBtn" class="scroll-btn" onclick="toggleScroll()">&#10074;&#10074;</button>

      </div>

      <!-- 折叠按钮 -->

      <button class="collapse-btn" onclick="toggleCardCollapse()"></button>

    </div>


<!-- 控制按钮 -->

<div class="controls">

  <button class="control-btn" id="playBtn" onclick="toggleAnimation()" data-tooltip="自动播放/暂停">▶</button>

  <button class="control-btn" id="prevBtn" onclick="prevPoint()" data-tooltip="上一个地点">◀</button>

  <button class="control-btn" id="nextBtn" onclick="nextPoint()" data-tooltip="下一个地点">▶</button>

</div>


<!-- 回到顶部按钮 -->

<div class="back-to-top" id="backToTop" onclick="scrollToTop()">

  <i class="fas fa-arrow-up"></i>

</div>


<!-- 阶段颜色指示器 -->

<div class="stage-indicator">

  <div class="stage-title">人生阶段</div>

  <div class="stage-colors" id="stageColors"></div>

</div>


<!-- 使用本地Leaflet库 -->

<script src="leaflet.js"></script>

<!-- 暂时移除其他依赖,专注于地图基础功能 -->

<script>

// 全局变量定义

let map;

let allPoints = [];

let currentPointIndex = 0;

let markers = [];

let pathLines = [];

let horseMarker = null;

let isAnimating = false;

let animationInterval = null;

let isEn = false;

let isScrolling = true;

let scrollAnimationId = null;

let lastScrollY = 0;

const scrollSpeed = 0.05; // 滚动速度(像素/毫秒)- 调慢四倍,让游客有更充足时间阅读

const animationDelay = 30000; // 动画延迟(毫秒)- 延长至30秒,让用户有更多时间欣赏内容


// 定义白居易人生阶段名称和对应的古典风颜色

const stageNames = [

    { stage: 1, name: "出生与童年", color: "#E6A641" }, // 琥珀色

    { stage: 2, name: "求仕与初入仕途", color: "#83A6ED" }, // 浅蓝色

    { stage: 3, name: "贬谪江州", color: "#E68C41" }, // 橙色

    { stage: 4, name: "杭州刺史任上", color: "#41E6A6" }, // 青色

    { stage: 5, name: "苏州刺史任上", color: "#8341E6" }, // 紫色

    { stage: 6, name: "晚年退居洛阳", color: "#A641E6" }  // 深紫色

];


const stageNamesEn = [

    { stage: 1, name: "Birth & Childhood", color: "#E6A641" },

    { stage: 2, name: "Seeking Office & Early Career", color: "#83A6ED" },

    { stage: 3, name: "Exile in Jiangzhou", color: "#E68C41" },

    { stage: 4, name: "Governor of Hangzhou", color: "#41E6A6" },

    { stage: 5, name: "Governor of Suzhou", color: "#8341E6" },

    { stage: 6, name: "Later Years in Luoyang", color: "#A641E6" }

];


/* 白居易足迹数据 */

allPoints = [

    {

        "name": "新郑",

        "nameEn": "Xinzheng",

        "year": 772,

        "stage": 1,

        "coord": [34.4, 113.7],

        "event": "出生于河南新郑",

        "eventEn": "Born in Xinzheng, Henan",

        "poem": "离离原上草,一岁一枯荣",

        "poemEn": "Wild grass on the plain, withering and flourishing each year",

        "image": "./images/xinzheng.jpg",

        "fallbackImage": "https://picsum.photos/id/1015/800/600",

        "culture": {

            "title": "赋得古原草送别",

            "titleEn": "Grass on the Ancient Plain",

            "lines": ["离离原上草,一岁一枯荣", "野火烧不尽,春风吹又生", "远芳侵古道,晴翠接荒城", "又送王孙去,萋萋满别情"],

            "linesEn": ["Wild grass on the plain, withering and flourishing each year", "Wildfire can't burn it out, spring wind blows it back to life", "Fragrant grass spreads over ancient roads, green extends to deserted cities", "Farewell to the noble youth again, luxuriant grass fills with parting sorrow"],

            "anecdote": "白居易出生于官宦世家,字乐天,号香山居士。据史书记载,他自幼聪慧,五六岁便开始学诗,九岁能通声韵,展现出非凡的文学天赋。新郑是白居易的出生地,这里的中原文化底蕴深厚,对他的诗歌创作产生了深远影响。",

            "anecdoteEn": "Bai Juyi was born into an official family, styled himself Letian, and later took the literary name Xiangshan Jushi (Recluse of Xiangshan). According to historical records, he was intelligent from a young age, starting to learn poetry at five or six, and mastering rhyme at nine, showing extraordinary literary talent. Xinzheng was Bai Juyi's birthplace, and the profound Central Plains culture here had a far-reaching impact on his poetic creation."

        }

    },

    {

        "name": "符离",

        "nameEn": "Fuli",

        "year": 780,

        "stage": 1,

        "coord": [34.2, 117.0],

        "event": "随父移居徐州符离",

        "eventEn": "Moved to Fuli, Xuzhou with his father",

        "poem": "江南好,风景旧曾谙",

        "poemEn": "South of the Yangtze is good, the scenery is as I knew it",

        "image": "./images/fuli.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "忆江南·江南好",

            "titleEn": "Remembering South of the Yangtze·South of the Yangtze is Good",

            "lines": ["江南好,风景旧曾谙", "日出江花红胜火,春来江水绿如蓝", "能不忆江南?"],

            "linesEn": ["South of the Yangtze is good, the scenery is as I knew it", "Sunrise dyes river flowers redder than fire, spring turns river waters green as blue", "How can I not remember south of the Yangtze?"],

            "anecdote": "白居易八岁时,父亲白季庚任徐州别驾,举家移居符离。在符离的这段童年时光,白居易结交了许多好友,其中包括后来成为他终生伴侣的杨氏。符离的山水风光和人文环境,对白居易日后的诗歌创作产生了重要影响。",

            "anecdoteEn": "When Bai Juyi was eight years old, his father Bai Jigeng was appointed as the deputy governor of Xuzhou, and the family moved to Fuli. During his childhood in Fuli, Bai Juyi made many friends, including Yang, who later became his lifelong companion. The landscape and cultural environment of Fuli had an important impact on Bai Juyi's poetic creation in later years."

        }

    },

    {

        "name": "长安",

        "nameEn": "Chang'an",

        "year": 799,

        "stage": 2,

        "coord": [34.3, 108.8],

        "event": "赴长安应试,名动京华",

        "eventEn": "Traveled to Chang'an to take the imperial examination, becoming famous in the capital",

        "poem": "野火烧不尽,春风吹又生",

        "poemEn": "Wildfire can't burn it out, spring wind blows it back to life",

        "image": "./images/changan.jpg",

        "fallbackImage": "https://picsum.photos/id/1043/800/600",

        "culture": {

            "title": "赋得古原草送别",

            "titleEn": "Grass on the Ancient Plain",

            "lines": ["离离原上草,一岁一枯荣", "野火烧不尽,春风吹又生", "远芳侵古道,晴翠接荒城", "又送王孙去,萋萋满别情"],

            "linesEn": ["Wild grass on the plain, withering and flourishing each year", "Wildfire can't burn it out, spring wind blows it back to life", "Fragrant grass spreads over ancient roads, green extends to deserted cities", "Farewell to the noble youth again, luxuriant grass fills with parting sorrow"],

            "anecdote": "贞元十六年(800年),白居易在长安参加进士科考试,以第四名的优异成绩及第。他的应试诗《赋得古原草送别》得到了主考官顾况的高度赞赏,顾况甚至赞叹:'道得个语,居亦易矣!'(能写出这样的诗句,在长安居住也容易了!)从此,白居易名动京华。",

            "anecdoteEn": "In the 16th year of Zhenyuan (800 AD), Bai Juyi participated in the imperial examination in Chang'an and passed with excellent results, ranking fourth. His examination poem 'Grass on the Ancient Plain' was highly praised by the chief examiner Gu Kuang, who even exclaimed: 'With such poetry, living here will be easy!' From then on, Bai Juyi became famous in the capital."

        }

    },

    {

        "name": "长安",

        "nameEn": "Chang'an",

        "year": 806,

        "stage": 2,

        "coord": [34.3, 108.8],

        "event": "授校书郎,开始仕途生涯",

        "eventEn": "Appointed as a copyeditor, starting his official career",

        "poem": "同是天涯沦落人,相逢何必曾相识",

        "poemEn": "We are both fallen people at the ends of the earth, why must we have known each other before meeting",

        "image": "./images/changan.jpg",

        "fallbackImage": "https://picsum.photos/id/1043/800/600",

        "culture": {

            "title": "琵琶行",

            "titleEn": "Song of the Pipa Player",

            "lines": ["浔阳江头夜送客,枫叶荻花秋瑟瑟", "主人下马客在船,举酒欲饮无管弦", "醉不成欢惨将别,别时茫茫江浸月", "忽闻水上琵琶声,主人忘归客不发", "同是天涯沦落人,相逢何必曾相识"],

            "linesEn": ["Seeing off a guest at night by Xunyang River, maple leaves and reeds sough in autumn", "The host dismounted, the guest stayed on the boat; raising wine to drink, but no music", "Drunk without joy, sadly about to part; at parting, the vast river immerses the moon", "Suddenly hearing pipa sounds on the water, the host forgets to return, the guest won't depart", "We are both fallen people at the ends of the earth, why must we have known each other before meeting"],

            "anecdote": "元和元年(806年),白居易参加制举考试,以优异成绩被授予校书郎一职,正式开始了他的仕途生涯。在长安期间,他与元稹结为莫逆之交,共同倡导新乐府运动,主张诗歌应当反映社会现实,关心民生疾苦。",

            "anecdoteEn": "In the first year of Yuanhe (806 AD), Bai Juyi participated in the special imperial examination and was appointed as a copyeditor with excellent results, officially starting his official career. During his stay in Chang'an, he formed a close friendship with Yuan Zhen and together they advocated for the New Yuefu Movement,主张ing that poetry should reflect social reality and care about the sufferings of the people."

        }

    },

    {

        "name": "长安",

        "nameEn": "Chang'an",

        "year": 809,

        "stage": 2,

        "coord": [34.3, 108.8],

        "event": "任左拾遗,创作新乐府诗",

        "eventEn": "Appointed as Zuo Shiyi, creating new yuefu poems",

        "poem": "可怜身上衣正单,心忧炭贱愿天寒",

        "poemEn": "Pitifully, his clothes are thin, yet he worries about cheap charcoal and wishes for cold weather",

        "image": "./images/changan.jpg",

        "fallbackImage": "https://picsum.photos/id/1043/800/600",

        "culture": [{

            "title": "卖炭翁",

            "titleEn": "The Old Charcoal Seller",

            "lines": ["卖炭翁,伐薪烧炭南山中", "满面尘灰烟火色,两鬓苍苍十指黑", "卖炭得钱何所营?身上衣裳口中食", "可怜身上衣正单,心忧炭贱愿天寒", "夜来城外一尺雪,晓驾炭车辗冰辙", "牛困人饥日已高,市南门外泥中歇", "翩翩两骑来是谁?黄衣使者白衫儿", "手把文书口称敕,回车叱牛牵向北", "一车炭,千余斤,宫使驱将惜不得", "半匹红纱一丈绫,系向牛头充炭直" ],

            "linesEn": ["The old charcoal seller, cuts firewood and burns charcoal in the southern mountains", "His face is covered with dust and smoke, his temples are gray and his fingers are black", "What does he do with the money from selling charcoal? Buy clothes for his body and food for his mouth", "Pitifully, his clothes are thin, yet he worries about cheap charcoal and wishes for cold weather", "Last night there was a foot of snow outside the city, at dawn he drove the charcoal cart over icy ruts", "The ox is tired, the man is hungry, the sun is high, resting in the mud outside the south city gate", "Graceful two riders, who are they? Yellow-clad messengers and white-robed attendants", "Holding documents, they say it's an imperial order, turning the cart, shouting at the ox, leading north", "A cart of charcoal, over a thousand catties, palace messengers drive it away, reluctant but unable to keep", "Half a bolt of red silk and a zhang of damask, tied to the ox's head as payment for the charcoal" ],

            "anecdote": "元和四年(809年),白居易任左拾遗期间,创作了《卖炭翁》等新乐府诗,通过描写一个卖炭老人的艰辛生活,揭露了中唐时期'宫市'制度对劳动人民的残酷剥削。这些诗歌语言质朴,感情真挚,具有深刻的社会意义。",

            "anecdoteEn": "In the fourth year of Yuanhe (809 AD), during his tenure as Zuo Shiyi, Bai Juyi created new yuefu poems such as 'The Old Charcoal Seller'. It reveals the cruel exploitation of working people by the 'palace market' system in the mid-Tang Dynasty through the description of an old charcoal seller's hard life. These poems have simple language, sincere feelings, and profound social significance."

        },

        {

            "title": "观刈麦",

            "titleEn": "Watching Farmers Reap Wheat",

            "lines": ["田家少闲月,五月人倍忙", "夜来南风起,小麦覆陇黄", "妇姑荷箪食,童稚携壶浆", "相随饷田去,丁壮在南冈", "足蒸暑土气,背灼炎天光", "力尽不知热,但惜夏日长"],

            "linesEn": ["Farmers have few leisure months, in May people are twice as busy", "Last night a south wind blew, wheat covers the ridges, yellow", "Women and girls carry bamboo baskets with food, children bring pots of drink", "They go together to the fields to deliver food, strong men work on the southern ridge", "Feet steamed by the summer earth's heat, backs scorched by the blazing sun", "Exhausted but not feeling the heat, only cherishing the long summer days"],

            "anecdote": "《观刈麦》是白居易任左拾遗期间创作的新乐府诗,通过描写农民在麦收时节的辛勤劳作,对比自己的舒适生活,表达了诗人对劳动人民的深切同情。",

            "anecdoteEn": "'Watching Farmers Reap Wheat' is a new yuefu poem written by Bai Juyi during his tenure as Zuo Shiyi. It describes the hard work of farmers during wheat harvest season and contrasts it with his own comfortable life, expressing the poet's deep sympathy for working people."

        }]

    },

    {

        "name": "江州",

        "nameEn": "Jiangzhou",

        "year": 815,

        "stage": 3,

        "coord": [29.4, 115.9],

        "event": "因上书言事被贬为江州司马",

        "eventEn": "Banished to Jiangzhou as Sima due to submitting a memorial criticizing the government",

        "poem": "浔阳江头夜送客,枫叶荻花秋瑟瑟",

        "poemEn": "Seeing off a guest at night by Xunyang River, maple leaves and reeds sough in autumn",

        "image": "./images/jiangzhou.jpg",

        "fallbackImage": "https://picsum.photos/id/1057/800/600",

        "culture": {

            "title": "琵琶行",

            "titleEn": "Song of the Pipa Player",

            "lines": ["浔阳江头夜送客,枫叶荻花秋瑟瑟", "主人下马客在船,举酒欲饮无管弦", "醉不成欢惨将别,别时茫茫江浸月", "忽闻水上琵琶声,主人忘归客不发", "同是天涯沦落人,相逢何必曾相识"],

            "linesEn": ["Seeing off a guest at night by Xunyang River, maple leaves and reeds sough in autumn", "The host dismounted, the guest stayed on the boat; raising wine to drink, but no music", "Drunk without joy, sadly about to part; at parting, the vast river immerses the moon", "Suddenly hearing pipa sounds on the water, the host forgets to return, the guest won't depart", "We are both fallen people at the ends of the earth, why must we have known each other before meeting"],

            "anecdote": "元和十年(815年),白居易因上书请求严缉刺杀宰相武元衡的凶手,触怒了当权者,被贬为江州司马。在江州期间,他写下了著名的《琵琶行》和《长恨歌》,这两首诗成为他诗歌创作的巅峰之作,也是中国文学史上的经典名篇。",

            "anecdoteEn": "In the 10th year of Yuanhe (815 AD), Bai Juyi was banished to Jiangzhou as Sima because he submitted a memorial requesting strict pursuit of the assassin who killed Prime Minister Wu Yuanheng, angering those in power. During his stay in Jiangzhou, he wrote the famous poems 'Song of the Pipa Player' and 'Song of Everlasting Sorrow', which became the peak of his poetic creation and classic masterpieces in Chinese literary history."

        }

    },

    {

        "name": "杭州",

        "nameEn": "Hangzhou",

        "year": 822,

        "stage": 4,

        "coord": [30.2, 120.1],

        "event": "任杭州刺史,兴修水利,深受百姓爱戴",

        "eventEn": "Appointed as Governor of Hangzhou, built water conservancy projects, deeply loved by the people",

        "poem": "最爱湖东行不足,绿杨阴里白沙堤",

        "poemEn": "I love walking east of the lake most, along the white sand embankment shaded by green willows",

        "image": "./images/hangzhou.jpg",

        "fallbackImage": "https://picsum.photos/id/1018/800/600",

        "culture": {

            "title": "钱塘湖春行",

            "titleEn": "Spring Walk by Qiantang Lake",

            "lines": ["孤山寺北贾亭西,水面初平云脚低", "几处早莺争暖树,谁家新燕啄春泥", "乱花渐欲迷人眼,浅草才能没马蹄", "最爱湖东行不足,绿杨阴里白沙堤"],

            "linesEn": ["North of Gushan Temple and west of Jiat亭, the water surface is just level, clouds low over the lake", "Several early orioles compete for warm trees, whose new swallows peck spring mud", "Colorful flowers gradually dazzle the eyes, shallow grass can just cover the horse's hooves", "I love walking east of the lake most, along the white sand embankment shaded by green willows"],

            "anecdote": "长庆二年(822年),白居易被任命为杭州刺史。在杭州任上,他主持疏浚六井,解决了杭州城的饮水问题;又修筑西湖白堤,既便利了交通,又美化了环境。这些政绩使他深受杭州百姓的爱戴,至今杭州仍保留着许多与他相关的历史遗迹和传说。",

            "anecdoteEn": "In the second year of Changqing (822 AD), Bai Juyi was appointed as the Governor of Hangzhou. During his tenure in Hangzhou, he presided over the dredging of six wells, solving the drinking water problem of Hangzhou city; he also built the West Lake Bai Causeway, which not only facilitated transportation but also beautified the environment. These political achievements made him deeply loved by the people of Hangzhou, and many historical sites and legends related to him are still preserved in Hangzhou today."

        }

    },

    {

        "name": "苏州",

        "nameEn": "Suzhou",

        "year": 825,

        "stage": 5,

        "coord": [31.3, 120.6],

        "event": "任苏州刺史,勤政爱民,兴修水利",

        "eventEn": "Appointed as Governor of Suzhou, diligent and caring for the people, built water conservancy projects",

        "poem": "江南忆,最忆是杭州",

        "poemEn": "When I remember the south of the Yangtze, I remember Hangzhou most",

        "image": "./images/suzhou.jpg",

        "fallbackImage": "https://picsum.photos/id/1019/800/600",

        "culture": {

            "title": "忆江南·江南忆",

            "titleEn": "Remembering South of the Yangtze·Remembering South of the Yangtze",

            "lines": ["江南忆,最忆是杭州", "山寺月中寻桂子,郡亭枕上看潮头", "何日更重游?"],

            "linesEn": ["When I remember the south of the Yangtze, I remember Hangzhou most", "Searching for osmanthus seeds under the moon in mountain temples, watching the tide from the prefectural pavilion pillow", "When will I revisit?"],

            "anecdote": "宝历元年(825年),白居易改任苏州刺史。在苏州任上,他同样勤政爱民,兴修水利,为百姓做了许多实事。由于过度劳累,他的眼疾加重,但仍然坚持处理政务。苏州百姓为了纪念他,将他在任时修筑的堤坝称为'白公堤'。",

            "anecdoteEn": "In the first year of Baoli (825 AD), Bai Juyi was transferred to be the Governor of Suzhou. During his tenure in Suzhou, he was also diligent and caring for the people, built water conservancy projects, and did many practical things for the people. Due to overwork, his eye disease worsened, but he still insisted on handling government affairs. To commemorate him, the people of Suzhou called the embankment he built during his tenure 'Bai Gong Di' (Bai's Embankment)."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 827,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "回到洛阳,开始晚年退隐生活",

        "eventEn": "Returned to Luoyang, starting his late retirement life",

        "poem": "人间四月芳菲尽,山寺桃花始盛开",

        "poemEn": "All flowers in the human world have faded by April, but peach blossoms in mountain temples are just beginning to bloom",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "大林寺桃花",

            "titleEn": "Peach Blossoms in Dalin Temple",

            "lines": ["人间四月芳菲尽,山寺桃花始盛开", "长恨春归无觅处,不知转入此中来"],

            "linesEn": ["All flowers in the human world have faded by April, but peach blossoms in mountain temples are just beginning to bloom", "I always regret not finding where spring has gone, not knowing it has come here"],

            "anecdote": "太和元年(827年),白居易回到洛阳,开始了他的晚年退隐生活。在洛阳期间,他与刘禹锡等友人诗酒唱和,过着悠闲自在的生活。他还在洛阳香山寺附近修筑了'白氏庄',并自号'香山居士'。这一时期,他的诗歌创作更加成熟,多反映闲适的生活和人生哲理。",

            "anecdoteEn": "In the first year of Taihe (827 AD), Bai Juyi returned to Luoyang and began his late retirement life. During his stay in Luoyang, he exchanged poems and drank wine with friends like Liu Yuxi, living a leisurely and comfortable life. He also built 'Bai's Manor' near Xiangshan Temple in Luoyang and took the literary name 'Xiangshan Jushi' (Recluse of Xiangshan). During this period, his poetic creation became more mature, mostly reflecting leisurely life and philosophy of life."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 830,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "洛阳闲居,创作山水诗",

        "eventEn": "Living in leisure in Luoyang, creating landscape poems",

        "poem": "一道残阳铺水中,半江瑟瑟半江红",

        "poemEn": "A streak of setting sun spreads over the water, half the river is emerald, half is red",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "暮江吟",

            "titleEn": "Chanting at Dusk by the River",

            "lines": ["一道残阳铺水中,半江瑟瑟半江红", "可怜九月初三夜,露似真珠月似弓"],

            "linesEn": ["A streak of setting sun spreads over the water, half the river is emerald, half is red", "What a lovely night on the third day of the ninth month, dewdrops like pearls, moon like a bow"],

            "anecdote": "太和四年(830年),白居易在洛阳闲居期间,创作了《暮江吟》这首脍炙人口的七言绝句。诗中描绘了秋日傍晚江面上的美丽景色,语言清新自然,意境优美,是白居易山水诗的代表作之一。",

            "anecdoteEn": "In the fourth year of Taihe (830 AD), during his leisure time in Luoyang, Bai Juyi created the famous seven-character quatrain 'Chanting at Dusk by the River'. The poem depicts the beautiful scenery on the river at dusk in autumn, with fresh and natural language and beautiful artistic conception, which is one of the representative works of Bai Juyi's landscape poetry."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 835,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "与友人唱和,创作生活小诗",

        "eventEn": "Exchanging poems with friends, creating small life poems",

        "poem": "小娃撑小艇,偷采白莲回",

        "poemEn": "A little child rows a small boat, stealthily picking white lotus seeds to return",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "池上",

            "titleEn": "On the Pool",

            "lines": ["小娃撑小艇,偷采白莲回", "不解藏踪迹,浮萍一道开"],

            "linesEn": ["A little child rows a small boat, stealthily picking white lotus seeds to return", "Not knowing how to hide his tracks, a path opens through the duckweed"],

            "anecdote": "大和九年(835年),白居易在洛阳创作了《池上》这首充满童趣的小诗。诗中通过描绘一个小孩偷采白莲的情景,表现了儿童的天真无邪和纯真可爱,语言简洁明快,意境清新自然,是白居易描写儿童生活的佳作。",

            "anecdoteEn": "In the ninth year of Taihe (835 AD), Bai Juyi created the childlike poem 'On the Pool' in Luoyang. Through depicting a scene of a child stealing white lotus seeds, the poem shows the innocence and purity of children, with concise and lively language and fresh and natural artistic conception, which is a masterpiece of Bai Juyi's description of children's life."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 837,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "冬夜赏雪,创作咏物诗",

        "eventEn": "Appreciating snow on a winter night, creating object-chanting poems",

        "poem": "已讶衾枕冷,复见窗户明",

        "poemEn": "Already surprised by the cold quilt and pillow, then seeing the windows bright",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "夜雪",

            "titleEn": "Night Snow",

            "lines": ["已讶衾枕冷,复见窗户明", "夜深知雪重,时闻折竹声"],

            "linesEn": ["Already surprised by the cold quilt and pillow, then seeing the windows bright", "Knowing the snow is heavy deep in the night, hearing the sound of breaking bamboo from time to time"],

            "anecdote": "开成二年(837年)冬夜,白居易在洛阳住所感受到了一场大雪。他通过触觉、视觉和听觉三个角度描写了夜雪的特点,构思巧妙,语言凝练,是中国古典诗歌中描写夜雪的名篇。",

            "anecdoteEn": "On a winter night in the second year of Kaicheng (837 AD), Bai Juyi felt a heavy snowfall at his residence in Luoyang. He described the characteristics of night snow from three perspectives: touch, sight, and hearing, with ingenious conception and concise language, which is a famous poem describing night snow in classical Chinese poetry."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 840,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "冬夜邀友,创作生活小诗",

        "eventEn": "Inviting friends on a winter night, creating small life poems",

        "poem": "绿蚁新醅酒,红泥小火炉",

        "poemEn": "Green ants in newly brewed wine, a small red clay stove",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "问刘十九",

            "titleEn": "Asking Liu Shijiu",

            "lines": ["绿蚁新醅酒,红泥小火炉", "晚来天欲雪,能饮一杯无?"],

            "linesEn": ["Green ants in newly brewed wine, a small red clay stove", "The sky is about to snow in the evening, can you come for a drink?"],

            "anecdote": "会昌元年(841年)冬,白居易在洛阳邀请友人刘十九前来共饮。他以简洁温馨的语言描绘了冬日饮酒的场景,表达了对友人的真挚情谊,是白居易描写日常生活的代表作之一。",

            "anecdoteEn": "In the winter of the first year of Huichang (841 AD), Bai Juyi invited his friend Liu Shijiu to drink together in Luoyang. He described the scene of drinking in winter with concise and warm language, expressing his sincere friendship to his friend, which is one of the representative works of Bai Juyi's description of daily life."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 846,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "病逝于洛阳,享年75岁",

        "eventEn": "Passed away in Luoyang at the age of 75",

        "poem": "试玉要烧三日满,辨材须待七年期",

        "poemEn": "To test jade, you need to burn it for three full days; to distinguish good wood, you have to wait seven years",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "放言五首·其三",

            "titleEn": "Five Poems on Free Expression·Third",

            "lines": ["试玉要烧三日满,辨材须待七年期", "周公恐惧流言日,王莽谦恭未篡时"],

            "linesEn": ["To test jade, you need to burn it for three full days; to distinguish good wood, you have to wait seven years", "When Zhou Gong feared rumors, when Wang Mang was humble before he usurped"],

            "anecdote": "会昌六年(846年),白居易在洛阳病逝,享年75岁。他一生创作了近三千首诗歌,题材广泛,形式多样,语言通俗易懂,深受人民群众喜爱。他的诗歌对后世产生了深远影响,被称为'诗魔'、'诗王'。他的墓位于洛阳香山寺附近,至今仍有许多人前往凭吊这位伟大的诗人。",

            "anecdoteEn": "In the sixth year of Huichang (846 AD), Bai Juyi passed away in Luoyang at the age of 75. He created nearly 3,000 poems in his lifetime, with a wide range of subjects, diverse forms, and easy-to-understand language, deeply loved by the people. His poems had a profound impact on later generations and he was called 'Poetry Demon' and 'Poetry King'. His tomb is located near Xiangshan Temple in Luoyang, and many people still visit to pay tribute to this great poet."

        }

    }

];


/* 初始化地图 */

function initMap() {

    console.log('初始化地图开始');

    

    // 检查地图容器是否存在

    const mapContainer = document.getElementById('map');

    console.log('地图容器存在:', !!mapContainer);

    if (mapContainer) {

        console.log('地图容器尺寸:', mapContainer.offsetWidth, 'x', mapContainer.offsetHeight);

    }

    

    // 创建地图实例,设置中心点和缩放级别

    map = L.map('map').setView([34.0, 110.0], 5);

    

    console.log('地图实例创建成功:', !!map);

    

    // 添加瓦片图层 - 使用高德地图瓦片服务作为替代

    const tileLayer = L.tileLayer('https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {

        subdomains: "1234",

        attribution: '© <a href="https://ditu.amap.com/">高德地图</a>',

        maxZoom: 19

    }).addTo(map);

    

    console.log('瓦片图层添加成功:', !!tileLayer);

    

    // 添加缩放控件

    L.control.zoom({position: 'bottomright'}).addTo(map);

    

    // 绘制阶段颜色指示器

    initStageIndicators();

    

    // 绘制路线和点位

    drawPathSegments();

    createPointMarkers();

    

    // 创建骑马标记

    createHorseMarker();

    

    // 隐藏加载器

    setTimeout(() => {

        document.getElementById('mapLoader').style.opacity = '0';

        document.getElementById('mapLoader').style.pointerEvents = 'none';

        setTimeout(() => {

            document.getElementById('mapLoader').style.display = 'none';

        }, 500);

    }, 1000);

    

    // 添加一些简单的地图标记和文字,以测试地图是否可见

    setTimeout(() => {

        // 在地图中心添加一个标记

        L.marker([34.0, 110.0]).addTo(map)

            .bindPopup("地图中心点")

            .openPopup();

        

        // 在地图上添加一些文字,以确认地图容器可见

        console.log('地图测试标记已添加');

    }, 2000);

}


/* 绘制路线分段 */

function drawPathSegments() {

    // 清除已有路线

    pathLines.forEach(line => map.removeLayer(line));

    pathLines = [];

    

    // 绘制每段路线(直接连接相邻两点)

    for (let i = 0; i < allPoints.length - 1; i++) {

        const startPoint = allPoints[i];

        const endPoint = allPoints[i + 1];

        

        // 使用起点的阶段颜色

        const stageInfo = stageNames.find(s => s.stage === startPoint.stage);

        const color = stageInfo ? stageInfo.color : '#000000';

        

        // 使用简单的线段代替蚂蚁线,因为我们移除了antPath库

        const line = L.polyline(

            [startPoint.coord, endPoint.coord],

            {

                "weight": 3,

                "color": color,

                "opacity": 0.7

            }

        ).addTo(map);

        

        pathLines.push(line);

    }

}


/* 创建点位标记 */

function createPointMarkers() {

    // 初始化加载进度

    const progressBar = document.getElementById('progressBar');

    

    allPoints.forEach((point, index) => {

        // 更新加载进度

        progressBar.style.width = `${(index / allPoints.length) * 100}%`;

        

        // 获取阶段对应的颜色

        const stageInfo = stageNames.find(s => s.stage === point.stage);

        const color = stageInfo ? stageInfo.color : '#000000';

        

        // 创建圆形标记

        const marker = L.circleMarker(point.coord, {

            radius: 10,

            fillColor: color,

            color: '#ffffff',

            weight: 2,

            opacity: 1,

            fillOpacity: 0.8

        }).addTo(map);

        

        // 存储原始样式,用于后续加亮效果

        marker.originalStyle = {

            radius: 10,

            fillColor: color,

            color: '#ffffff',

            weight: 2,

            opacity: 1,

            fillOpacity: 0.8

        };

        

        // 加亮样式 - 颜色加深、尺寸更大

        // 生成深色版本的颜色

        const darkenColor = (color) => {

            // 简单的颜色加深方法:移除透明度并稍微加深颜色值

            let hex = color.replace('#', '');

            // 转换为RGB

            let r = parseInt(hex.substring(0, 2), 16);

            let g = parseInt(hex.substring(2, 4), 16);

            let b = parseInt(hex.substring(4, 6), 16);

            // 深色处理(减少亮度20%)

            r = Math.max(0, Math.floor(r * 0.8));

            g = Math.max(0, Math.floor(g * 0.8));

            b = Math.max(0, Math.floor(b * 0.8));

            // 转回十六进制

            return '#' + [r, g, b].map(x => {

                const hex = x.toString(16);

                return hex.length === 1 ? '0' + hex : hex;

            }).join('');

        };

        

        const darkColor = darkenColor(color);

        

        marker.highlightStyle = {

            radius: 18,  // 更大的半径

            fillColor: darkColor,  // 使用加深后的颜色

            color: '#ffd700',  // 金色边框

            weight: 4,  // 更粗的边框

            opacity: 1,

            fillOpacity: 1,

            className: 'highlight-marker'  // 添加类名用于可能的CSS动画

        };

        

        // 添加点击事件

        marker.on('click', () => {

            currentPointIndex = index;

            showPointInfo(point);

            moveHorseToPoint(index);

        });

        

        // 添加悬停效果

        marker.on('mouseover', () => {

            marker.setStyle(marker.highlightStyle);

        });

        

        marker.on('mouseout', () => {

            // 只有当不是当前选中的点时才恢复样式

            if (index !== currentPointIndex) {

                marker.setStyle(marker.originalStyle);

            }

        });

        

        // 添加弹出信息 - 中英文并行显示

        marker.bindPopup(`<div class="bilingual-text">

                            <div><b>${point.name}</b></div>

                            <div style="font-size: 14px;">${point.year}年 | ${point.event}</div>

                            <div><b>${point.nameEn}</b></div>

                            <div style="font-size: 12px;">${point.year} A.D. | ${point.eventEn}</div>

                        </div>`, {

            className: 'custom-popup',

            closeButton: true,

            minWidth: 200

        });

        

        markers.push(marker);

    });

}


/* 创建骑马标记 */

function createHorseMarker() {

    // 创建自定义图标

    const horseIcon = L.divIcon({

        html: '🐎',

        className: 'horse-marker',

        iconSize: [30, 30],

        iconAnchor: [15, 15]

    });

    

    // 创建标记

    horseMarker = L.marker(allPoints[0].coord, {

        icon: horseIcon,

        zIndexOffset: 1000

    }).addTo(map);

    

    // 添加轻微的上下浮动动画

    const markerElement = horseMarker.getElement();

    markerElement.style.animation = 'horseFloat 3s ease-in-out infinite';

}


/* 移动骑马标记到指定点位 */

function moveHorseToPoint(index) {

    const point = allPoints[index];

    

    // 平滑移动效果

    if (horseMarker) {

        // 获取当前位置和目标位置

        const currentLatLng = horseMarker.getLatLng();

        const targetLatLng = L.latLng(point.coord);

        

        // 创建路径线段数组,使马能够沿着路径移动

        const pathPoints = [];

        const numSteps = 50; // 路径上的点数量,越多路径越平滑

        

        // 计算两点之间的路径点

        for (let i = 0; i <= numSteps; i++) {

            const progress = i / numSteps;

            // 增加一些随机性,使路径看起来更自然

            const randomFactor = 0.1 * (Math.sin(progress * Math.PI * 4) + Math.random() * 0.5);

            const easedProgress = easeInOutCubic(progress);

            

            // 计算中间位置,添加一些曲线效果

            const lat = currentLatLng.lat + 

                      (targetLatLng.lat - currentLatLng.lat) * easedProgress + 

                      randomFactor * 0.1;

            const lng = currentLatLng.lng + 

                      (targetLatLng.lng - currentLatLng.lng) * easedProgress + 

                      randomFactor * 0.1;

            

            pathPoints.push({ lat, lng, progress });

        }

        

        // 创建马蹄印动画效果

        createHorseTracks(currentLatLng, targetLatLng, numSteps);

        

        // 移动到新位置 - 平滑过渡

        const duration = 3000; // 动画持续时间,增加到3秒使移动更自然

        const startTime = performance.now();

        

        function moveHorse(timestamp) {

            const elapsed = timestamp - startTime;

            const progress = Math.min(elapsed / duration, 1);

            

            // 使用缓动函数使动画更自然

            const easedProgress = easeInOutCubic(progress);

            

            // 找到当前进度对应的路径点

            let currentPathPoint;

            for (let i = 0; i < pathPoints.length; i++) {

                if (pathPoints[i].progress >= easedProgress) {

                    currentPathPoint = pathPoints[i];

                    break;

                }

            }

            

            if (currentPathPoint) {

                // 更新骑马标记的位置

                horseMarker.setLatLng(L.latLng(currentPathPoint.lat, currentPathPoint.lng));

                

                if (progress < 1) {

                    requestAnimationFrame(moveHorse);

                } else {

                    // 动画完成后更新点位状态

                    updateMarkerStates();

                }

            }

        }

        

        // 开始动画

        requestAnimationFrame(moveHorse);

    }

}


/* 创建马蹄印效果 */

function createHorseTracks(startPoint, endPoint, numSteps) {

    // 计算每步之间的距离

    const latStep = (endPoint.lat - startPoint.lat) / numSteps;

    const lngStep = (endPoint.lng - startPoint.lng) / numSteps;

    

    // 创建马蹄印标记

    for (let i = 0; i < numSteps; i += 5) { // 每隔5步创建一个马蹄印

        const lat = startPoint.lat + latStep * i;

        const lng = startPoint.lng + lngStep * i;

        

        // 随机偏移,使马蹄印看起来更自然

        const randomLat = lat + (Math.random() - 0.5) * 0.01;

        const randomLng = lng + (Math.random() - 0.5) * 0.01;

        

        // 创建临时的马蹄印标记

        const trackIcon = L.divIcon({

            html: '👣',

            className: 'horse-track',

            iconSize: [30, 30],

            iconAnchor: [15, 15]

        });

        

        const trackMarker = L.marker([randomLat, randomLng], {

            icon: trackIcon,

            zIndexOffset: 500

        }).addTo(map);

        

        // 设置淡出动画

        setTimeout(() => {

            let opacity = 1;

            const fadeInterval = setInterval(() => {

                opacity -= 0.1;

                trackMarker.setOpacity(opacity);

                

                if (opacity <= 0) {

                    clearInterval(fadeInterval);

                    map.removeLayer(trackMarker);

                }

            }, 100);

        }, 1000);

    }

}


/* 缓动函数 - 使动画更自然 */

function easeInOutCubic(t) {

    return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

}


/* 显示点位信息 */

function showPointInfo(point) {

    const card = document.getElementById('infoCard');

    const title = document.getElementById('infoTitle');

    const year = document.getElementById('infoYear');

    const description = document.getElementById('infoDescription');

    const poem = document.getElementById('infoPoem');

    const anecdote = document.getElementById('infoAnecdote');

    const image = document.getElementById('infoImage');

    

    // 设置内容 - 中英文并行显示

    title.innerHTML = `<div class="bilingual-text">

                            <div class="chinese-text">${point.name}</div>

                            <div class="english-text">${point.nameEn}</div>

                        </div>`;

    

    year.innerHTML = `<div class="bilingual-text">

                        <div class="chinese-text">${point.year}年 | ${point.event}</div>

                        <div class="english-text">${point.year} A.D. | ${point.eventEn}</div>

                    </div>`;

    

    // 检查是否有文化信息

    if (point.culture && point.culture.lines) {

        // 显示诗句题目和内容,中英文并行显示

        const poemTitle = point.culture.title || '诗句'; // 默认题目

        const poemTitleEn = point.culture.titleEn || 'Verse'; // 默认英文题目

        const poemHtml = `

            <div class="bilingual-text poem-title">

                <div class="chinese-text">${poemTitle}</div>

                <div class="english-text">${poemTitleEn}</div>

            </div>

            <div class="bilingual-text">

                <div class="chinese-text poem-highlight">${point.culture.lines.join('<br>')}</div>

                <div class="english-text">${point.culture.linesEn.join('<br>')}</div>

            </div>`;

        

        poem.innerHTML = poemHtml;

        

        // 显示文化轶事,中英文并行显示

        if (point.culture.anecdote) {

            anecdote.innerHTML = `<div class="bilingual-text">

                                    <div class="chinese-text">${point.culture.anecdote}</div>

                                    <div class="english-text">${point.culture.anecdoteEn}</div>

                                </div>`;

            anecdote.style.display = 'block';

        } else {

            anecdote.style.display = 'none';

        }

    } else {

        // 没有文化信息的情况下,也显示诗题

        const poemTitle = '诗句'; // 默认题目

        const poemTitleEn = 'Verse'; // 默认英文题目

        poem.innerHTML = `<div class="bilingual-text poem-title">

                            <div class="chinese-text">${poemTitle}</div>

                            <div class="english-text">${poemTitleEn}</div>

                        </div>

                        <div class="bilingual-text">

                            <div class="chinese-text poem-highlight">${point.poem}</div>

                            <div class="english-text">${point.poemEn}</div>

                        </div>`;

        anecdote.style.display = 'none';

    }

    

    // 设置图片

    image.onload = function() {

        image.classList.remove('image-loading');

    };

    

    image.onerror = function() {

        // 如果加载失败,使用备用图片

        image.src = point.fallbackImage || 'https://picsum.photos/id/1000/800/600';

        image.classList.remove('image-loading');

    };

    

    // 开始加载图片

    image.classList.add('image-loading');

    image.src = point.image;

    

    // 显示卡片

    setTimeout(() => {

        card.classList.add('active');

    }, 100);

    

    // 滚动到顶部

    card.querySelector('.info-content').scrollTop = 0;

    

    // 启动自动滚动

    startAutoScroll();

}


/* 初始化阶段颜色指示器 - 中英文并行显示 */

function initStageIndicators() {

    const container = document.getElementById('stageColors');

    container.innerHTML = '';

    

    // 同时显示中文和英文的阶段名称

    stageNames.forEach((stage, index) => {

        const item = document.createElement('div');

        item.className = 'stage-item';

        

        const colorBox = document.createElement('div');

        colorBox.className = 'stage-color';

        colorBox.style.backgroundColor = stage.color;

        

        const nameContainer = document.createElement('div');

        nameContainer.className = 'bilingual-text';

        

        const nameZhSpan = document.createElement('div');

        nameZhSpan.className = 'chinese-text';

        nameZhSpan.textContent = stage.name;

        

        const nameEnSpan = document.createElement('div');

        nameEnSpan.className = 'english-text';

        nameEnSpan.textContent = stageNamesEn[index]?.name || '';

        

        nameContainer.appendChild(nameZhSpan);

        nameContainer.appendChild(nameEnSpan);

        

        item.appendChild(colorBox);

        item.appendChild(nameContainer);

        container.appendChild(item);

    });

}


/* 更新标记状态 */

function updateMarkerStates() {

    markers.forEach((marker, index) => {

        if (index === currentPointIndex) {

            // 当前点使用高亮样式

            marker.setStyle(marker.highlightStyle);

            marker.openPopup(); // 打开当前点的弹出信息

        } else {

            // 其他点使用原始样式

            marker.setStyle(marker.originalStyle);

            marker.closePopup(); // 关闭其他点的弹出信息

        }

    });

}


/* 显示前一个点位 */

function prevPoint() {

    currentPointIndex = (currentPointIndex - 1 + allPoints.length) % allPoints.length;

    const point = allPoints[currentPointIndex];

    showPointInfo(point);

    moveHorseToPoint(currentPointIndex);

}


/* 显示下一个点位 */

function nextPoint() {

    currentPointIndex = (currentPointIndex + 1) % allPoints.length;

    const point = allPoints[currentPointIndex];

    showPointInfo(point);

    moveHorseToPoint(currentPointIndex);

}


/* 切换自动播放 */

function toggleAnimation() {

    const playBtn = document.getElementById('playBtn');

    

    if (isAnimating) {

        // 停止动画

        clearInterval(animationInterval);

        playBtn.textContent = '▶';

        playBtn.setAttribute('data-tooltip', '自动播放');

    } else {

        // 开始动画

        animationInterval = setInterval(nextPoint, animationDelay);

        playBtn.textContent = '⏸';

        playBtn.setAttribute('data-tooltip', '暂停自动播放');

    }

    

    isAnimating = !isAnimating;

}


/* 隐藏信息卡片 */

function hideInfoCard() {

    const card = document.getElementById('infoCard');

    card.classList.remove('active');

    

    // 停止自动滚动

    stopAutoScroll();

}


/* 切换卡片折叠状态 */

function toggleCardCollapse() {

    const card = document.getElementById('infoCard');

    card.classList.toggle('collapsed');

}


/* 启动自动滚动 */

function startAutoScroll() {

    if (!isScrolling) return;

    

    const content = document.getElementById('infoCard').querySelector('.info-content');

    const maxScroll = content.scrollHeight - content.clientHeight;

    

    if (maxScroll <= 0) return; // 如果没有可滚动的内容,则不启动自动滚动

    

    // 清除现有的动画

    if (scrollAnimationId) {

        cancelAnimationFrame(scrollAnimationId);

    }

    

    let lastTime = 0;

    

    function scrollContent(timestamp) {

        if (!lastTime) lastTime = timestamp;

        const elapsed = timestamp - lastTime;

        

        // 根据时间计算滚动距离

        const scrollDistance = (elapsed / 1000) * scrollSpeed;

        

        // 更新滚动位置

        const currentScroll = content.scrollTop;

        const newScroll = Math.min(currentScroll + scrollDistance, maxScroll);

        content.scrollTop = newScroll;

        

        // 记录当前滚动位置,用于后续恢复

        lastScrollY = newScroll;

        

        // 检查是否需要继续滚动

        if (newScroll < maxScroll && isScrolling) {

            scrollAnimationId = requestAnimationFrame(scrollContent);

        }

    }

    

    // 开始滚动动画

    scrollAnimationId = requestAnimationFrame(scrollContent);

}


/* 停止自动滚动 */

function stopAutoScroll() {

    if (scrollAnimationId) {

        cancelAnimationFrame(scrollAnimationId);

        scrollAnimationId = null;

    }

}


/* 切换自动滚动状态 */

function toggleScroll() {

    isScrolling = !isScrolling;

    const pauseBtn = document.getElementById('pauseScrollBtn');

    

    if (isScrolling) {

        pauseBtn.textContent = '⏸';

        startAutoScroll();

    } else {

        pauseBtn.textContent = '▶';

        stopAutoScroll();

    }

}


/* 切换语言 - 保留按钮但实际是中英文同时显示 */

function toggleLanguage() {

    isEn = !isEn;

    const btnZh = document.getElementById('btnZh');

    const btnEn = document.getElementById('btnEn');

    

    if (isEn) {

        btnZh.classList.remove('active');

        btnEn.classList.add('active');

    } else {

        btnZh.classList.add('active');

        btnEn.classList.remove('active');

    }

}


/* 回到顶部 */

function scrollToTop() {

    window.scrollTo({

        top: 0,

        behavior: 'smooth'

    });

}


/* 处理滚动事件 */

function handleScroll() {

    const backToTop = document.getElementById('backToTop');

    const scrollY = window.scrollY;

    

    // 显示/隐藏回到顶部按钮

    if (scrollY > 300) {

        backToTop.classList.add('visible');

    } else {

        backToTop.classList.remove('visible');

    }

}


/* 页面加载完成后初始化 */

window.onload = function() {

    // 初始化地图

    initMap();

    

    // 显示第一个点的信息

    setTimeout(() => {

        showPointInfo(allPoints[0]);

        updateMarkerStates();

    }, 1500);

    

    // 添加滚动事件监听

    window.addEventListener('scroll', handleScroll);

    

    // 为信息卡片添加点击事件

    document.getElementById('infoCard').addEventListener('click', function(e) {

        // 如果点击的不是关闭按钮或折叠按钮,则切换卡片的显示状态

        if (!e.target.closest('.info-close') && !e.target.closest('.collapse-btn') && !e.target.closest('.scroll-control')) {

            this.classList.toggle('active');

        }

    });

    

    // 添加键盘事件监听

    document.addEventListener('keydown', function(e) {

        if (e.key === 'ArrowLeft') {

            prevPoint();

        } else if (e.key === 'ArrowRight') {

            nextPoint();

        } else if (e.key === ' ') {

            // 空格控制播放/暂停

            e.preventDefault(); // 阻止页面滚动

            toggleAnimation();

        }

    });

    

    // 为窗口调整事件添加监听,重置地图大小

    window.addEventListener('resize', function() {

        setTimeout(() => {

            map.invalidateSize();

        }, 100);

    });

    

    // 添加触摸滑动支持

    let touchStartX = 0;

    let touchEndX = 0;

    

    document.addEventListener('touchstart', function(e) {

        touchStartX = e.changedTouches[0].screenX;

    }, false);

    

    document.addEventListener('touchend', function(e) {

        touchEndX = e.changedTouches[0].screenX;

        handleSwipe();

    }, false);

    

    function handleSwipe() {

        const swipeThreshold = 50;

        if (touchEndX < touchStartX - swipeThreshold) {

            // 向左滑动,显示下一个点

            nextPoint();

        } else if (touchEndX > touchStartX + swipeThreshold) {

            // 向右滑动,显示上一个点

            prevPoint();

        }

    }

}

</script>

</body>

</html>

<!DOCTYPE html>

<html lang="zh-CN">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta name="description" content="沉浸式体验白居易一生的行迹与诗歌创作历程">

    <title>诗魔白居易一生行迹 - 沉浸式文化体验</title>

    <!-- 使用本地Leaflet库 -->

    <link rel="stylesheet" href="leaflet.css">

    <style>

        /* 手动添加一些基础的Leaflet控件样式以确保功能完整 */

        .leaflet-control {

            z-index: 800;

        }

        .leaflet-control-zoom {

            background-color: rgba(255, 255, 255, 0.8);

            border-radius: 4px;

            box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);

        }

        .leaflet-control-zoom-in,

        .leaflet-control-zoom-out {

            width: 30px;

            height: 30px;

            text-align: center;

            line-height: 30px;

            color: #333;

            background-color: white;

            border: none;

            cursor: pointer;

        }

    </style>

    <style>

        * {

            margin: 0;

            padding: 0;

            box-sizing: border-box;

        }

        

        body {

            font-family: 'Microsoft YaHei', 'PingFang SC', sans-serif;

            background-color: #f5f5f5;

            line-height: 1.6;

            color: #333;

            overflow-x: hidden;

        }

        

        header {

            position: fixed;

            top: 0;

            left: 0;

            right: 0;

            background-color: rgba(255, 255, 255, 0.95);

            padding: 15px;

            text-align: center;

            font-size: 24px;

            font-weight: bold;

            color: #333;

            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

            z-index: 1000;

            backdrop-filter: blur(5px);

        }

        

        #mapLoader {

            position: fixed;

            top: 0;

            left: 0;

            width: 100%;

            height: 100%;

            display: flex;

            flex-direction: column;

            align-items: center;

            justify-content: center;

            background-color: white;

            z-index: 9999;

            transition: opacity 0.5s ease-out;

        }

        

        .loader-spinner {

            width: 50px;

            height: 50px;

            border: 5px solid #f3f3f3;

            border-top: 5px solid #8B4513;

            border-radius: 50%;

            animation: spin 1s linear infinite;

        }

        

        @keyframes spin {

            0% { transform: rotate(0deg); }

            100% { transform: rotate(360deg); }

        }

        

        #map {

            width: 100vw;

            height: 100vh;

            position: relative;

            margin-top: 60px;

        }

        

        /* 信息卡片样式 - 优化透明度和布局以避免遮挡路径 */

        .info-card {

            position: fixed;

            bottom: 40px;

            left: 50%;

            transform: translateX(-50%) translateY(100%);

            width: 80%;

            max-width: 1200px;

            background-color: rgba(255, 255, 255, 0.5); /* 增加透明度到50% */

            backdrop-filter: blur(12px);

            border-radius: 15px;

            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);

            transition: transform 0.5s ease, max-height 0.5s ease, opacity 0.5s ease;

            z-index: 900;

            display: flex;

            flex-direction: row;

            overflow: hidden;

            cursor: pointer;

            opacity: 0;

        }

        

        .info-card.active {

            opacity: 1;

        }

        

        /* 折叠按钮样式 */

        .collapse-btn {

            position: absolute;

            bottom: 10px;

            left: 50%;

            transform: translateX(-50%);

            width: 40px;

            height: 20px;

            background-color: rgba(255, 255, 255, 0.8);

            border: none;

            border-radius: 10px;

            cursor: pointer;

            display: flex;

            align-items: center;

            justify-content: center;

            transition: all 0.3s ease;

            z-index: 10;

        }

        

        .collapse-btn:hover {

            background-color: rgba(255, 255, 255, 1);

        }

        

        .collapse-btn::before {

            content: '⌄';

            transition: transform 0.3s ease;

        }

        

        .info-card.collapsed .collapse-btn::before {

            transform: rotate(180deg);

        }

        

        /* 折叠状态的信息卡片 */

        .info-card.collapsed {

            max-height: 100px;

        }

        

        .info-card.collapsed .info-content {

            max-height: 60px;

        }

        

        /* 马标志样式 */

        .horse-marker {

            font-size: 40px !important; /* 增加马标志的尺寸,使其更加醒目 */

            text-shadow: 0 3px 6px rgba(0, 0, 0, 0.4);

            transform-origin: center center;

            transition: transform 0.3s ease;

            animation: horseFloat 3s ease-in-out infinite;

        }

        

        @keyframes horseFloat {

            0% { transform: translateY(0px); }

            50% { transform: translateY(-5px); }

            100% { transform: translateY(0px); }

        }

        

        .horse-marker:hover {

            transform: scale(1.3) rotate(5deg);

        }

        

        .info-card.active {

            transform: translateX(-50%) translateY(0);

            opacity: 1;

        }

        

        /* 独立的图片区域 */

        .info-image {

            width: 25%;

            min-width: 150px;

            height: 300px; /* 增加图片高度 */

            object-fit: cover;

            position: relative;

            border-radius: 15px 0 0 15px;

            transition: filter 0.3s ease;

        }

        

        .info-image:hover {

            filter: brightness(1.1);

        }

        

        /* 图片加载动画 */

        .image-loading::after {

            content: '';

            position: absolute;

            top: 0;

            left: -100%;

            width: 50%;

            height: 100%;

            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);

            animation: shimmer 1.5s infinite;

        }

        

        @keyframes shimmer {

            to {

                left: 100%;

            }

        }

        

        /* 独立的内容区域 */

        .info-content {

            padding: 20px;

            width: 75%;

            overflow-y: auto;

            max-height: 300px;

            position: relative;

            transition: max-height 0.5s ease;

        }

        

        /* 内容滚动条样式优化 */

        .info-content::-webkit-scrollbar {

            width: 8px;

        }

        

        .info-content::-webkit-scrollbar-track {

            background: rgba(0, 0, 0, 0.05);

            border-radius: 4px;

        }

        

        .info-content::-webkit-scrollbar-thumb {

            background: rgba(0, 0, 0, 0.2);

            border-radius: 4px;

        }

        

        .info-content::-webkit-scrollbar-thumb:hover {

            background: rgba(0, 0, 0, 0.3);

        }

        

        /* 滚动内容容器 */

        .scroll-container {

            height: 100%;

            overflow-y: auto;

        }

        

        /* 滚动控制按钮 */

        .scroll-control {

            position: absolute;

            bottom: 10px;

            right: 10px;

            display: flex;

            gap: 5px;

        }

        

        .scroll-btn {

            width: 30px;

            height: 30px;

            border-radius: 50%;

            border: none;

            background-color: rgba(255, 255, 255, 0.8);

            cursor: pointer;

            display: flex;

            align-items: center;

            justify-content: center;

            font-size: 14px;

            transition: background-color 0.3s;

        }

        

        .scroll-btn:hover {

            background-color: rgba(255, 255, 255, 1);

        }

        

        .info-title {

            font-size: 36px;

            margin-bottom: 12px;

            color: #333;

            text-align: center;

            font-weight: bold;

            text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);

            letter-spacing: 0.5px;

        }

        

        .info-year {

            font-size: 16px;

            color: #666;

            margin-bottom: 15px;

            padding-bottom: 10px;

            border-bottom: 1px solid #eee;

            text-align: center;

            font-style: italic;

        }

        

        .info-description {

            margin-bottom: 20px;

            line-height: 2.0;

            font-size: 25px;

            color: #333;

            text-indent: 2em;

            letter-spacing: 0.8px;

        }

        

        /* 优化诗句样式 */

        .info-poem {

            color: #8B4513;

            margin-bottom: 15px;

            padding: 15px;

            background-color: #FFF8DC;

            border-radius: 10px;

            font-style: italic;

            border-left: 4px solid #8B4513;

            box-shadow: 0 2px 8px rgba(139, 69, 19, 0.1);

        }

        

        /* 双语文字样式优化 */

        .bilingual-text {

            margin-bottom: 10px;

        }

        

        .chinese-text {

            font-family: 'Microsoft YaHei', 'PingFang SC', serif;

            font-size: 25px;

            color: #333;

            line-height: 2.0;

            margin-bottom: 12px;

            letter-spacing: 0.8px;

        }

        

        .english-text {

            font-family: 'Times New Roman', serif;

            font-size: 20px;

            color: #555;

            line-height: 1.8;

            font-style: italic;

            letter-spacing: 0.5px;

        }

        

        .bilingual-item {

            margin-bottom: 15px;

        }

        

        .lang-label {

            font-weight: bold;

            color: #8B4513;

            margin-bottom: 5px;

            font-size: 14px;

        }

        

        /* 标题动画效果 */

        .title-animation {

            animation: fadeInScale 1s ease-out;

        }

        

        @keyframes fadeInScale {

            0% { opacity: 0; transform: scale(0.9); }

            100% { opacity: 1; transform: scale(1); }

        }

        

        /* 高亮诗句样式 */

        .poem-highlight {

            background-color: rgba(139, 69, 19, 0.05);

            padding: 10px;

            border-radius: 8px;

            border-left: 4px solid #8B4513;

        }

        

        /* 诗题样式 */

        .poem-title {

            font-weight: bold;

            font-size: 18px;

            margin-bottom: 10px;

            color: #8B4513;

            text-align: center;

            font-style: normal;

            letter-spacing: 1px;

        }

        

        .info-close {

                position: absolute;

                top: 10px;

                right: 10px;

                width: 30px;

            height: 30px;

            background-color: rgba(0, 0, 0, 0.2);

            color: white;

            border: none;

            border-radius: 50%;

            font-size: 18px;

            cursor: pointer;

            display: flex;

            align-items: center;

            justify-content: center;

            transition: background-color 0.3s;

        }

        

        .info-close:hover {

            background-color: rgba(0, 0, 0, 0.4);

        }

        

        /* 控制按钮 */

        .controls {

            position: fixed;

            top: 100px;

            right: 20px;

            display: flex;

            flex-direction: column;

            gap: 10px;

            z-index: 1050;

            transition: transform 0.3s ease;

        }

        

        /* 控制按钮提示 */

        .control-btn::after {

            content: attr(data-tooltip);

            position: absolute;

            right: 100%;

            margin-right: 10px;

            background-color: rgba(0, 0, 0, 0.8);

            color: white;

            padding: 5px 10px;

            border-radius: 5px;

            font-size: 12px;

            white-space: nowrap;

            opacity: 0;

            visibility: hidden;

            transition: opacity 0.3s, visibility 0.3s;

        }

        

        .control-btn:hover::after {

            opacity: 1;

            visibility: visible;

        }

        

        .control-btn {

            width: 50px;

            height: 50px;

            border-radius: 50%;

            border: none;

            background-color: rgba(255, 255, 255, 0.9);

            color: #333;

            font-size: 20px;

            cursor: pointer;

            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);

            display: flex;

            align-items: center;

            justify-content: center;

            transition: all 0.3s ease;

            position: relative;

            backdrop-filter: blur(5px);

        }

        

        .control-btn:hover {

            background-color: #fff;

            transform: translateY(-3px);

            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);

        }

        

        /* 阶段颜色指示器 */

        .stage-indicator {

            position: fixed;

            top: 100px;

            left: 0;

            right: 0;

            background-color: rgba(255, 255, 255, 0.95);

            padding: 10px 20px;

            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);

            z-index: 800;

            display: flex;

            justify-content: center;

            align-items: center;

            flex-wrap: wrap;

            gap: 15px;

            backdrop-filter: blur(5px);

            transition: transform 0.3s ease;

        }

        

        .stage-title {

            font-weight: bold;

            color: #333;

            margin-right: 15px;

        }

        

        .stage-colors {

            display: flex;

            flex-wrap: wrap;

            gap: 15px;

            justify-content: center;

        }

        

        .stage-item {

            display: flex;

            align-items: center;

            gap: 8px;

            font-size: 14px;

        }

        

        .stage-color {

            width: 20px;

            height: 20px;

            border-radius: 4px;

            border: 1px solid #ddd;

        }

        

        /* 语言显示区域 - 调整为同时显示双语 */

        .lang-label {

            text-align: right;

            font-size: 12px;

            color: #999;

            margin-bottom: 5px;

        }

        

        .bilingual-item {

            margin-bottom: 15px;

        }

        

        .bilingual-text {

            display: flex;

            flex-direction: column;

            gap: 5px;

        }

        

        .chinese-text {

            font-size: 16px;

            color: #333;

        }

        

        .english-text {

            font-size: 14px;

            color: #666;

            font-style: italic;

        }

        

        /* 移除语言切换按钮 */

        .lang-switch {

            display: none;

        }

        

        /* 回到顶部按钮 */

        .back-to-top {

            position: fixed;

            bottom: 20px;

            right: 20px;

            width: 50px;

            height: 50px;

            border-radius: 50%;

            background-color: rgba(255, 255, 255, 0.9);

            color: #333;

            display: flex;

            align-items: center;

            justify-content: center;

            cursor: pointer;

            opacity: 0;

            visibility: hidden;

            transition: opacity 0.3s, visibility 0.3s, transform 0.3s;

            z-index: 950;

            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);

            backdrop-filter: blur(5px);

        }

        

        .back-to-top.visible {

            opacity: 1;

            visibility: visible;

        }

        

        .back-to-top:hover {

            transform: translateY(-3px);

            background-color: white;

        }

        

        /* 加载进度条 */

        .progress-bar {

            position: fixed;

            top: 60px;

            left: 0;

            height: 4px;

            background: linear-gradient(90deg, #E6A641, #83A6ED, #E68C41, #41E6A6, #8341E6, #A641E6);

            width: 0%;

            z-index: 1001;

            transition: width 0.3s ease;

        }

        

        /* 适配移动端 */

        @media(max-width:768px){

            header {

                font-size: 20px;

                padding: 12px;

            }

            

            .info-card {flex-direction:column; left: 5%; right: 5%;}

            .info-image {width:100%;height:200px}

            .info-content {max-height:40vh; width: 100%;}

            .controls {top: auto; bottom: 150px; right: 20px; flex-direction: row;}

            .stage-indicator {top: auto; bottom: 220px; left: 20px; right: 20px;}

            .stage-colors {flex-direction: row; flex-wrap: wrap;}

            

            /* 移动端触摸优化 */

            .control-btn {

                width: 60px;

                height: 60px;

                font-size: 24px;

            }

        }

    </style>

</head>

<body>

<header>

    <div style="font-size: 36px; font-weight: bold; color: #333; margin-bottom: 5px; text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);">

        诗魔白居易,乐天知命,笔写民生疾苦讽喻时弊

    </div>

    <div style="font-size: 14px; color: #666; font-style: italic;">

        浏览器搜索'唐诗.中国'中文域名查看完整版

    </div>

</header>

<div class="progress-bar" id="progressBar"></div>

<div id="mapLoader">

  <div class="loader-spinner"></div>

  <span>加载中…</span>

  <div style="margin-top: 10px; font-size: 14px; color: #666;">正在准备白居易的精彩人生旅程</div>

</div>

<div id="map"></div>


<!-- 信息卡片 -->

    <div id="infoCard" class="info-card">

      <img id="infoImage" class="info-image" src="" alt="" loading="lazy">

      <div class="info-content">

        <!-- 语言切换按钮 -->

        <div class="lang-switch">

            <button id="btnZh" class="lang-btn active">中文</button>

            <button id="btnEn" class="lang-btn">English</button>

        </div>

        

        <h3 id="infoTitle" class="info-title"></h3>

        <div id="infoYear" class="info-year"></div>

        <div id="infoDescription" class="info-description"></div>

        <div id="infoPoem" class="info-poem"></div>

        <div id="infoAnecdote" class="info-description"></div>

      </div>

      <button class="info-close" onclick="hideInfoCard()">&times;</button>

      <div class="scroll-control">

        <button id="pauseScrollBtn" class="scroll-btn" onclick="toggleScroll()">&#10074;&#10074;</button>

      </div>

      <!-- 折叠按钮 -->

      <button class="collapse-btn" onclick="toggleCardCollapse()"></button>

    </div>


<!-- 控制按钮 -->

<div class="controls">

  <button class="control-btn" id="playBtn" onclick="toggleAnimation()" data-tooltip="自动播放/暂停">▶</button>

  <button class="control-btn" id="prevBtn" onclick="prevPoint()" data-tooltip="上一个地点">◀</button>

  <button class="control-btn" id="nextBtn" onclick="nextPoint()" data-tooltip="下一个地点">▶</button>

</div>


<!-- 回到顶部按钮 -->

<div class="back-to-top" id="backToTop" onclick="scrollToTop()">

  <i class="fas fa-arrow-up"></i>

</div>


<!-- 阶段颜色指示器 -->

<div class="stage-indicator">

  <div class="stage-title">人生阶段</div>

  <div class="stage-colors" id="stageColors"></div>

</div>


<!-- 使用本地Leaflet库 -->

<script src="leaflet.js"></script>

<!-- 暂时移除其他依赖,专注于地图基础功能 -->

<script>

// 全局变量定义

let map;

let allPoints = [];

let currentPointIndex = 0;

let markers = [];

let pathLines = [];

let horseMarker = null;

let isAnimating = false;

let animationInterval = null;

let isEn = false;

let isScrolling = true;

let scrollAnimationId = null;

let lastScrollY = 0;

const scrollSpeed = 0.05; // 滚动速度(像素/毫秒)- 调慢四倍,让游客有更充足时间阅读

const animationDelay = 30000; // 动画延迟(毫秒)- 延长至30秒,让用户有更多时间欣赏内容


// 定义白居易人生阶段名称和对应的古典风颜色

const stageNames = [

    { stage: 1, name: "出生与童年", color: "#E6A641" }, // 琥珀色

    { stage: 2, name: "求仕与初入仕途", color: "#83A6ED" }, // 浅蓝色

    { stage: 3, name: "贬谪江州", color: "#E68C41" }, // 橙色

    { stage: 4, name: "杭州刺史任上", color: "#41E6A6" }, // 青色

    { stage: 5, name: "苏州刺史任上", color: "#8341E6" }, // 紫色

    { stage: 6, name: "晚年退居洛阳", color: "#A641E6" }  // 深紫色

];


const stageNamesEn = [

    { stage: 1, name: "Birth & Childhood", color: "#E6A641" },

    { stage: 2, name: "Seeking Office & Early Career", color: "#83A6ED" },

    { stage: 3, name: "Exile in Jiangzhou", color: "#E68C41" },

    { stage: 4, name: "Governor of Hangzhou", color: "#41E6A6" },

    { stage: 5, name: "Governor of Suzhou", color: "#8341E6" },

    { stage: 6, name: "Later Years in Luoyang", color: "#A641E6" }

];


/* 白居易足迹数据 */

allPoints = [

    {

        "name": "新郑",

        "nameEn": "Xinzheng",

        "year": 772,

        "stage": 1,

        "coord": [34.4, 113.7],

        "event": "出生于河南新郑",

        "eventEn": "Born in Xinzheng, Henan",

        "poem": "离离原上草,一岁一枯荣",

        "poemEn": "Wild grass on the plain, withering and flourishing each year",

        "image": "./images/xinzheng.jpg",

        "fallbackImage": "https://picsum.photos/id/1015/800/600",

        "culture": {

            "title": "赋得古原草送别",

            "titleEn": "Grass on the Ancient Plain",

            "lines": ["离离原上草,一岁一枯荣", "野火烧不尽,春风吹又生", "远芳侵古道,晴翠接荒城", "又送王孙去,萋萋满别情"],

            "linesEn": ["Wild grass on the plain, withering and flourishing each year", "Wildfire can't burn it out, spring wind blows it back to life", "Fragrant grass spreads over ancient roads, green extends to deserted cities", "Farewell to the noble youth again, luxuriant grass fills with parting sorrow"],

            "anecdote": "白居易出生于官宦世家,字乐天,号香山居士。据史书记载,他自幼聪慧,五六岁便开始学诗,九岁能通声韵,展现出非凡的文学天赋。新郑是白居易的出生地,这里的中原文化底蕴深厚,对他的诗歌创作产生了深远影响。",

            "anecdoteEn": "Bai Juyi was born into an official family, styled himself Letian, and later took the literary name Xiangshan Jushi (Recluse of Xiangshan). According to historical records, he was intelligent from a young age, starting to learn poetry at five or six, and mastering rhyme at nine, showing extraordinary literary talent. Xinzheng was Bai Juyi's birthplace, and the profound Central Plains culture here had a far-reaching impact on his poetic creation."

        }

    },

    {

        "name": "符离",

        "nameEn": "Fuli",

        "year": 780,

        "stage": 1,

        "coord": [34.2, 117.0],

        "event": "随父移居徐州符离",

        "eventEn": "Moved to Fuli, Xuzhou with his father",

        "poem": "江南好,风景旧曾谙",

        "poemEn": "South of the Yangtze is good, the scenery is as I knew it",

        "image": "./images/fuli.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "忆江南·江南好",

            "titleEn": "Remembering South of the Yangtze·South of the Yangtze is Good",

            "lines": ["江南好,风景旧曾谙", "日出江花红胜火,春来江水绿如蓝", "能不忆江南?"],

            "linesEn": ["South of the Yangtze is good, the scenery is as I knew it", "Sunrise dyes river flowers redder than fire, spring turns river waters green as blue", "How can I not remember south of the Yangtze?"],

            "anecdote": "白居易八岁时,父亲白季庚任徐州别驾,举家移居符离。在符离的这段童年时光,白居易结交了许多好友,其中包括后来成为他终生伴侣的杨氏。符离的山水风光和人文环境,对白居易日后的诗歌创作产生了重要影响。",

            "anecdoteEn": "When Bai Juyi was eight years old, his father Bai Jigeng was appointed as the deputy governor of Xuzhou, and the family moved to Fuli. During his childhood in Fuli, Bai Juyi made many friends, including Yang, who later became his lifelong companion. The landscape and cultural environment of Fuli had an important impact on Bai Juyi's poetic creation in later years."

        }

    },

    {

        "name": "长安",

        "nameEn": "Chang'an",

        "year": 799,

        "stage": 2,

        "coord": [34.3, 108.8],

        "event": "赴长安应试,名动京华",

        "eventEn": "Traveled to Chang'an to take the imperial examination, becoming famous in the capital",

        "poem": "野火烧不尽,春风吹又生",

        "poemEn": "Wildfire can't burn it out, spring wind blows it back to life",

        "image": "./images/changan.jpg",

        "fallbackImage": "https://picsum.photos/id/1043/800/600",

        "culture": {

            "title": "赋得古原草送别",

            "titleEn": "Grass on the Ancient Plain",

            "lines": ["离离原上草,一岁一枯荣", "野火烧不尽,春风吹又生", "远芳侵古道,晴翠接荒城", "又送王孙去,萋萋满别情"],

            "linesEn": ["Wild grass on the plain, withering and flourishing each year", "Wildfire can't burn it out, spring wind blows it back to life", "Fragrant grass spreads over ancient roads, green extends to deserted cities", "Farewell to the noble youth again, luxuriant grass fills with parting sorrow"],

            "anecdote": "贞元十六年(800年),白居易在长安参加进士科考试,以第四名的优异成绩及第。他的应试诗《赋得古原草送别》得到了主考官顾况的高度赞赏,顾况甚至赞叹:'道得个语,居亦易矣!'(能写出这样的诗句,在长安居住也容易了!)从此,白居易名动京华。",

            "anecdoteEn": "In the 16th year of Zhenyuan (800 AD), Bai Juyi participated in the imperial examination in Chang'an and passed with excellent results, ranking fourth. His examination poem 'Grass on the Ancient Plain' was highly praised by the chief examiner Gu Kuang, who even exclaimed: 'With such poetry, living here will be easy!' From then on, Bai Juyi became famous in the capital."

        }

    },

    {

        "name": "长安",

        "nameEn": "Chang'an",

        "year": 806,

        "stage": 2,

        "coord": [34.3, 108.8],

        "event": "授校书郎,开始仕途生涯",

        "eventEn": "Appointed as a copyeditor, starting his official career",

        "poem": "同是天涯沦落人,相逢何必曾相识",

        "poemEn": "We are both fallen people at the ends of the earth, why must we have known each other before meeting",

        "image": "./images/changan.jpg",

        "fallbackImage": "https://picsum.photos/id/1043/800/600",

        "culture": {

            "title": "琵琶行",

            "titleEn": "Song of the Pipa Player",

            "lines": ["浔阳江头夜送客,枫叶荻花秋瑟瑟", "主人下马客在船,举酒欲饮无管弦", "醉不成欢惨将别,别时茫茫江浸月", "忽闻水上琵琶声,主人忘归客不发", "同是天涯沦落人,相逢何必曾相识"],

            "linesEn": ["Seeing off a guest at night by Xunyang River, maple leaves and reeds sough in autumn", "The host dismounted, the guest stayed on the boat; raising wine to drink, but no music", "Drunk without joy, sadly about to part; at parting, the vast river immerses the moon", "Suddenly hearing pipa sounds on the water, the host forgets to return, the guest won't depart", "We are both fallen people at the ends of the earth, why must we have known each other before meeting"],

            "anecdote": "元和元年(806年),白居易参加制举考试,以优异成绩被授予校书郎一职,正式开始了他的仕途生涯。在长安期间,他与元稹结为莫逆之交,共同倡导新乐府运动,主张诗歌应当反映社会现实,关心民生疾苦。",

            "anecdoteEn": "In the first year of Yuanhe (806 AD), Bai Juyi participated in the special imperial examination and was appointed as a copyeditor with excellent results, officially starting his official career. During his stay in Chang'an, he formed a close friendship with Yuan Zhen and together they advocated for the New Yuefu Movement,主张ing that poetry should reflect social reality and care about the sufferings of the people."

        }

    },

    {

        "name": "长安",

        "nameEn": "Chang'an",

        "year": 809,

        "stage": 2,

        "coord": [34.3, 108.8],

        "event": "任左拾遗,创作新乐府诗",

        "eventEn": "Appointed as Zuo Shiyi, creating new yuefu poems",

        "poem": "可怜身上衣正单,心忧炭贱愿天寒",

        "poemEn": "Pitifully, his clothes are thin, yet he worries about cheap charcoal and wishes for cold weather",

        "image": "./images/changan.jpg",

        "fallbackImage": "https://picsum.photos/id/1043/800/600",

        "culture": [{

            "title": "卖炭翁",

            "titleEn": "The Old Charcoal Seller",

            "lines": ["卖炭翁,伐薪烧炭南山中", "满面尘灰烟火色,两鬓苍苍十指黑", "卖炭得钱何所营?身上衣裳口中食", "可怜身上衣正单,心忧炭贱愿天寒", "夜来城外一尺雪,晓驾炭车辗冰辙", "牛困人饥日已高,市南门外泥中歇", "翩翩两骑来是谁?黄衣使者白衫儿", "手把文书口称敕,回车叱牛牵向北", "一车炭,千余斤,宫使驱将惜不得", "半匹红纱一丈绫,系向牛头充炭直" ],

            "linesEn": ["The old charcoal seller, cuts firewood and burns charcoal in the southern mountains", "His face is covered with dust and smoke, his temples are gray and his fingers are black", "What does he do with the money from selling charcoal? Buy clothes for his body and food for his mouth", "Pitifully, his clothes are thin, yet he worries about cheap charcoal and wishes for cold weather", "Last night there was a foot of snow outside the city, at dawn he drove the charcoal cart over icy ruts", "The ox is tired, the man is hungry, the sun is high, resting in the mud outside the south city gate", "Graceful two riders, who are they? Yellow-clad messengers and white-robed attendants", "Holding documents, they say it's an imperial order, turning the cart, shouting at the ox, leading north", "A cart of charcoal, over a thousand catties, palace messengers drive it away, reluctant but unable to keep", "Half a bolt of red silk and a zhang of damask, tied to the ox's head as payment for the charcoal" ],

            "anecdote": "元和四年(809年),白居易任左拾遗期间,创作了《卖炭翁》等新乐府诗,通过描写一个卖炭老人的艰辛生活,揭露了中唐时期'宫市'制度对劳动人民的残酷剥削。这些诗歌语言质朴,感情真挚,具有深刻的社会意义。",

            "anecdoteEn": "In the fourth year of Yuanhe (809 AD), during his tenure as Zuo Shiyi, Bai Juyi created new yuefu poems such as 'The Old Charcoal Seller'. It reveals the cruel exploitation of working people by the 'palace market' system in the mid-Tang Dynasty through the description of an old charcoal seller's hard life. These poems have simple language, sincere feelings, and profound social significance."

        },

        {

            "title": "观刈麦",

            "titleEn": "Watching Farmers Reap Wheat",

            "lines": ["田家少闲月,五月人倍忙", "夜来南风起,小麦覆陇黄", "妇姑荷箪食,童稚携壶浆", "相随饷田去,丁壮在南冈", "足蒸暑土气,背灼炎天光", "力尽不知热,但惜夏日长"],

            "linesEn": ["Farmers have few leisure months, in May people are twice as busy", "Last night a south wind blew, wheat covers the ridges, yellow", "Women and girls carry bamboo baskets with food, children bring pots of drink", "They go together to the fields to deliver food, strong men work on the southern ridge", "Feet steamed by the summer earth's heat, backs scorched by the blazing sun", "Exhausted but not feeling the heat, only cherishing the long summer days"],

            "anecdote": "《观刈麦》是白居易任左拾遗期间创作的新乐府诗,通过描写农民在麦收时节的辛勤劳作,对比自己的舒适生活,表达了诗人对劳动人民的深切同情。",

            "anecdoteEn": "'Watching Farmers Reap Wheat' is a new yuefu poem written by Bai Juyi during his tenure as Zuo Shiyi. It describes the hard work of farmers during wheat harvest season and contrasts it with his own comfortable life, expressing the poet's deep sympathy for working people."

        }]

    },

    {

        "name": "江州",

        "nameEn": "Jiangzhou",

        "year": 815,

        "stage": 3,

        "coord": [29.4, 115.9],

        "event": "因上书言事被贬为江州司马",

        "eventEn": "Banished to Jiangzhou as Sima due to submitting a memorial criticizing the government",

        "poem": "浔阳江头夜送客,枫叶荻花秋瑟瑟",

        "poemEn": "Seeing off a guest at night by Xunyang River, maple leaves and reeds sough in autumn",

        "image": "./images/jiangzhou.jpg",

        "fallbackImage": "https://picsum.photos/id/1057/800/600",

        "culture": {

            "title": "琵琶行",

            "titleEn": "Song of the Pipa Player",

            "lines": ["浔阳江头夜送客,枫叶荻花秋瑟瑟", "主人下马客在船,举酒欲饮无管弦", "醉不成欢惨将别,别时茫茫江浸月", "忽闻水上琵琶声,主人忘归客不发", "同是天涯沦落人,相逢何必曾相识"],

            "linesEn": ["Seeing off a guest at night by Xunyang River, maple leaves and reeds sough in autumn", "The host dismounted, the guest stayed on the boat; raising wine to drink, but no music", "Drunk without joy, sadly about to part; at parting, the vast river immerses the moon", "Suddenly hearing pipa sounds on the water, the host forgets to return, the guest won't depart", "We are both fallen people at the ends of the earth, why must we have known each other before meeting"],

            "anecdote": "元和十年(815年),白居易因上书请求严缉刺杀宰相武元衡的凶手,触怒了当权者,被贬为江州司马。在江州期间,他写下了著名的《琵琶行》和《长恨歌》,这两首诗成为他诗歌创作的巅峰之作,也是中国文学史上的经典名篇。",

            "anecdoteEn": "In the 10th year of Yuanhe (815 AD), Bai Juyi was banished to Jiangzhou as Sima because he submitted a memorial requesting strict pursuit of the assassin who killed Prime Minister Wu Yuanheng, angering those in power. During his stay in Jiangzhou, he wrote the famous poems 'Song of the Pipa Player' and 'Song of Everlasting Sorrow', which became the peak of his poetic creation and classic masterpieces in Chinese literary history."

        }

    },

    {

        "name": "杭州",

        "nameEn": "Hangzhou",

        "year": 822,

        "stage": 4,

        "coord": [30.2, 120.1],

        "event": "任杭州刺史,兴修水利,深受百姓爱戴",

        "eventEn": "Appointed as Governor of Hangzhou, built water conservancy projects, deeply loved by the people",

        "poem": "最爱湖东行不足,绿杨阴里白沙堤",

        "poemEn": "I love walking east of the lake most, along the white sand embankment shaded by green willows",

        "image": "./images/hangzhou.jpg",

        "fallbackImage": "https://picsum.photos/id/1018/800/600",

        "culture": {

            "title": "钱塘湖春行",

            "titleEn": "Spring Walk by Qiantang Lake",

            "lines": ["孤山寺北贾亭西,水面初平云脚低", "几处早莺争暖树,谁家新燕啄春泥", "乱花渐欲迷人眼,浅草才能没马蹄", "最爱湖东行不足,绿杨阴里白沙堤"],

            "linesEn": ["North of Gushan Temple and west of Jiat亭, the water surface is just level, clouds low over the lake", "Several early orioles compete for warm trees, whose new swallows peck spring mud", "Colorful flowers gradually dazzle the eyes, shallow grass can just cover the horse's hooves", "I love walking east of the lake most, along the white sand embankment shaded by green willows"],

            "anecdote": "长庆二年(822年),白居易被任命为杭州刺史。在杭州任上,他主持疏浚六井,解决了杭州城的饮水问题;又修筑西湖白堤,既便利了交通,又美化了环境。这些政绩使他深受杭州百姓的爱戴,至今杭州仍保留着许多与他相关的历史遗迹和传说。",

            "anecdoteEn": "In the second year of Changqing (822 AD), Bai Juyi was appointed as the Governor of Hangzhou. During his tenure in Hangzhou, he presided over the dredging of six wells, solving the drinking water problem of Hangzhou city; he also built the West Lake Bai Causeway, which not only facilitated transportation but also beautified the environment. These political achievements made him deeply loved by the people of Hangzhou, and many historical sites and legends related to him are still preserved in Hangzhou today."

        }

    },

    {

        "name": "苏州",

        "nameEn": "Suzhou",

        "year": 825,

        "stage": 5,

        "coord": [31.3, 120.6],

        "event": "任苏州刺史,勤政爱民,兴修水利",

        "eventEn": "Appointed as Governor of Suzhou, diligent and caring for the people, built water conservancy projects",

        "poem": "江南忆,最忆是杭州",

        "poemEn": "When I remember the south of the Yangtze, I remember Hangzhou most",

        "image": "./images/suzhou.jpg",

        "fallbackImage": "https://picsum.photos/id/1019/800/600",

        "culture": {

            "title": "忆江南·江南忆",

            "titleEn": "Remembering South of the Yangtze·Remembering South of the Yangtze",

            "lines": ["江南忆,最忆是杭州", "山寺月中寻桂子,郡亭枕上看潮头", "何日更重游?"],

            "linesEn": ["When I remember the south of the Yangtze, I remember Hangzhou most", "Searching for osmanthus seeds under the moon in mountain temples, watching the tide from the prefectural pavilion pillow", "When will I revisit?"],

            "anecdote": "宝历元年(825年),白居易改任苏州刺史。在苏州任上,他同样勤政爱民,兴修水利,为百姓做了许多实事。由于过度劳累,他的眼疾加重,但仍然坚持处理政务。苏州百姓为了纪念他,将他在任时修筑的堤坝称为'白公堤'。",

            "anecdoteEn": "In the first year of Baoli (825 AD), Bai Juyi was transferred to be the Governor of Suzhou. During his tenure in Suzhou, he was also diligent and caring for the people, built water conservancy projects, and did many practical things for the people. Due to overwork, his eye disease worsened, but he still insisted on handling government affairs. To commemorate him, the people of Suzhou called the embankment he built during his tenure 'Bai Gong Di' (Bai's Embankment)."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 827,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "回到洛阳,开始晚年退隐生活",

        "eventEn": "Returned to Luoyang, starting his late retirement life",

        "poem": "人间四月芳菲尽,山寺桃花始盛开",

        "poemEn": "All flowers in the human world have faded by April, but peach blossoms in mountain temples are just beginning to bloom",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "大林寺桃花",

            "titleEn": "Peach Blossoms in Dalin Temple",

            "lines": ["人间四月芳菲尽,山寺桃花始盛开", "长恨春归无觅处,不知转入此中来"],

            "linesEn": ["All flowers in the human world have faded by April, but peach blossoms in mountain temples are just beginning to bloom", "I always regret not finding where spring has gone, not knowing it has come here"],

            "anecdote": "太和元年(827年),白居易回到洛阳,开始了他的晚年退隐生活。在洛阳期间,他与刘禹锡等友人诗酒唱和,过着悠闲自在的生活。他还在洛阳香山寺附近修筑了'白氏庄',并自号'香山居士'。这一时期,他的诗歌创作更加成熟,多反映闲适的生活和人生哲理。",

            "anecdoteEn": "In the first year of Taihe (827 AD), Bai Juyi returned to Luoyang and began his late retirement life. During his stay in Luoyang, he exchanged poems and drank wine with friends like Liu Yuxi, living a leisurely and comfortable life. He also built 'Bai's Manor' near Xiangshan Temple in Luoyang and took the literary name 'Xiangshan Jushi' (Recluse of Xiangshan). During this period, his poetic creation became more mature, mostly reflecting leisurely life and philosophy of life."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 830,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "洛阳闲居,创作山水诗",

        "eventEn": "Living in leisure in Luoyang, creating landscape poems",

        "poem": "一道残阳铺水中,半江瑟瑟半江红",

        "poemEn": "A streak of setting sun spreads over the water, half the river is emerald, half is red",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "暮江吟",

            "titleEn": "Chanting at Dusk by the River",

            "lines": ["一道残阳铺水中,半江瑟瑟半江红", "可怜九月初三夜,露似真珠月似弓"],

            "linesEn": ["A streak of setting sun spreads over the water, half the river is emerald, half is red", "What a lovely night on the third day of the ninth month, dewdrops like pearls, moon like a bow"],

            "anecdote": "太和四年(830年),白居易在洛阳闲居期间,创作了《暮江吟》这首脍炙人口的七言绝句。诗中描绘了秋日傍晚江面上的美丽景色,语言清新自然,意境优美,是白居易山水诗的代表作之一。",

            "anecdoteEn": "In the fourth year of Taihe (830 AD), during his leisure time in Luoyang, Bai Juyi created the famous seven-character quatrain 'Chanting at Dusk by the River'. The poem depicts the beautiful scenery on the river at dusk in autumn, with fresh and natural language and beautiful artistic conception, which is one of the representative works of Bai Juyi's landscape poetry."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 835,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "与友人唱和,创作生活小诗",

        "eventEn": "Exchanging poems with friends, creating small life poems",

        "poem": "小娃撑小艇,偷采白莲回",

        "poemEn": "A little child rows a small boat, stealthily picking white lotus seeds to return",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "池上",

            "titleEn": "On the Pool",

            "lines": ["小娃撑小艇,偷采白莲回", "不解藏踪迹,浮萍一道开"],

            "linesEn": ["A little child rows a small boat, stealthily picking white lotus seeds to return", "Not knowing how to hide his tracks, a path opens through the duckweed"],

            "anecdote": "大和九年(835年),白居易在洛阳创作了《池上》这首充满童趣的小诗。诗中通过描绘一个小孩偷采白莲的情景,表现了儿童的天真无邪和纯真可爱,语言简洁明快,意境清新自然,是白居易描写儿童生活的佳作。",

            "anecdoteEn": "In the ninth year of Taihe (835 AD), Bai Juyi created the childlike poem 'On the Pool' in Luoyang. Through depicting a scene of a child stealing white lotus seeds, the poem shows the innocence and purity of children, with concise and lively language and fresh and natural artistic conception, which is a masterpiece of Bai Juyi's description of children's life."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 837,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "冬夜赏雪,创作咏物诗",

        "eventEn": "Appreciating snow on a winter night, creating object-chanting poems",

        "poem": "已讶衾枕冷,复见窗户明",

        "poemEn": "Already surprised by the cold quilt and pillow, then seeing the windows bright",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "夜雪",

            "titleEn": "Night Snow",

            "lines": ["已讶衾枕冷,复见窗户明", "夜深知雪重,时闻折竹声"],

            "linesEn": ["Already surprised by the cold quilt and pillow, then seeing the windows bright", "Knowing the snow is heavy deep in the night, hearing the sound of breaking bamboo from time to time"],

            "anecdote": "开成二年(837年)冬夜,白居易在洛阳住所感受到了一场大雪。他通过触觉、视觉和听觉三个角度描写了夜雪的特点,构思巧妙,语言凝练,是中国古典诗歌中描写夜雪的名篇。",

            "anecdoteEn": "On a winter night in the second year of Kaicheng (837 AD), Bai Juyi felt a heavy snowfall at his residence in Luoyang. He described the characteristics of night snow from three perspectives: touch, sight, and hearing, with ingenious conception and concise language, which is a famous poem describing night snow in classical Chinese poetry."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 840,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "冬夜邀友,创作生活小诗",

        "eventEn": "Inviting friends on a winter night, creating small life poems",

        "poem": "绿蚁新醅酒,红泥小火炉",

        "poemEn": "Green ants in newly brewed wine, a small red clay stove",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "问刘十九",

            "titleEn": "Asking Liu Shijiu",

            "lines": ["绿蚁新醅酒,红泥小火炉", "晚来天欲雪,能饮一杯无?"],

            "linesEn": ["Green ants in newly brewed wine, a small red clay stove", "The sky is about to snow in the evening, can you come for a drink?"],

            "anecdote": "会昌元年(841年)冬,白居易在洛阳邀请友人刘十九前来共饮。他以简洁温馨的语言描绘了冬日饮酒的场景,表达了对友人的真挚情谊,是白居易描写日常生活的代表作之一。",

            "anecdoteEn": "In the winter of the first year of Huichang (841 AD), Bai Juyi invited his friend Liu Shijiu to drink together in Luoyang. He described the scene of drinking in winter with concise and warm language, expressing his sincere friendship to his friend, which is one of the representative works of Bai Juyi's description of daily life."

        }

    },

    {

        "name": "洛阳",

        "nameEn": "Luoyang",

        "year": 846,

        "stage": 6,

        "coord": [34.6, 112.4],

        "event": "病逝于洛阳,享年75岁",

        "eventEn": "Passed away in Luoyang at the age of 75",

        "poem": "试玉要烧三日满,辨材须待七年期",

        "poemEn": "To test jade, you need to burn it for three full days; to distinguish good wood, you have to wait seven years",

        "image": "./images/luoyang.jpg",

        "fallbackImage": "https://picsum.photos/id/1036/800/600",

        "culture": {

            "title": "放言五首·其三",

            "titleEn": "Five Poems on Free Expression·Third",

            "lines": ["试玉要烧三日满,辨材须待七年期", "周公恐惧流言日,王莽谦恭未篡时"],

            "linesEn": ["To test jade, you need to burn it for three full days; to distinguish good wood, you have to wait seven years", "When Zhou Gong feared rumors, when Wang Mang was humble before he usurped"],

            "anecdote": "会昌六年(846年),白居易在洛阳病逝,享年75岁。他一生创作了近三千首诗歌,题材广泛,形式多样,语言通俗易懂,深受人民群众喜爱。他的诗歌对后世产生了深远影响,被称为'诗魔'、'诗王'。他的墓位于洛阳香山寺附近,至今仍有许多人前往凭吊这位伟大的诗人。",

            "anecdoteEn": "In the sixth year of Huichang (846 AD), Bai Juyi passed away in Luoyang at the age of 75. He created nearly 3,000 poems in his lifetime, with a wide range of subjects, diverse forms, and easy-to-understand language, deeply loved by the people. His poems had a profound impact on later generations and he was called 'Poetry Demon' and 'Poetry King'. His tomb is located near Xiangshan Temple in Luoyang, and many people still visit to pay tribute to this great poet."

        }

    }

];


/* 初始化地图 */

function initMap() {

    console.log('初始化地图开始');

    

    // 检查地图容器是否存在

    const mapContainer = document.getElementById('map');

    console.log('地图容器存在:', !!mapContainer);

    if (mapContainer) {

        console.log('地图容器尺寸:', mapContainer.offsetWidth, 'x', mapContainer.offsetHeight);

    }

    

    // 创建地图实例,设置中心点和缩放级别

    map = L.map('map').setView([34.0, 110.0], 5);

    

    console.log('地图实例创建成功:', !!map);

    

    // 添加瓦片图层 - 使用高德地图瓦片服务作为替代

    const tileLayer = L.tileLayer('https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {

        subdomains: "1234",

        attribution: '© <a href="https://ditu.amap.com/">高德地图</a>',

        maxZoom: 19

    }).addTo(map);

    

    console.log('瓦片图层添加成功:', !!tileLayer);

    

    // 添加缩放控件

    L.control.zoom({position: 'bottomright'}).addTo(map);

    

    // 绘制阶段颜色指示器

    initStageIndicators();

    

    // 绘制路线和点位

    drawPathSegments();

    createPointMarkers();

    

    // 创建骑马标记

    createHorseMarker();

    

    // 隐藏加载器

    setTimeout(() => {

        document.getElementById('mapLoader').style.opacity = '0';

        document.getElementById('mapLoader').style.pointerEvents = 'none';

        setTimeout(() => {

            document.getElementById('mapLoader').style.display = 'none';

        }, 500);

    }, 1000);

    

    // 添加一些简单的地图标记和文字,以测试地图是否可见

    setTimeout(() => {

        // 在地图中心添加一个标记

        L.marker([34.0, 110.0]).addTo(map)

            .bindPopup("地图中心点")

            .openPopup();

        

        // 在地图上添加一些文字,以确认地图容器可见

        console.log('地图测试标记已添加');

    }, 2000);

}


/* 绘制路线分段 */

function drawPathSegments() {

    // 清除已有路线

    pathLines.forEach(line => map.removeLayer(line));

    pathLines = [];

    

    // 绘制每段路线(直接连接相邻两点)

    for (let i = 0; i < allPoints.length - 1; i++) {

        const startPoint = allPoints[i];

        const endPoint = allPoints[i + 1];

        

        // 使用起点的阶段颜色

        const stageInfo = stageNames.find(s => s.stage === startPoint.stage);

        const color = stageInfo ? stageInfo.color : '#000000';

        

        // 使用简单的线段代替蚂蚁线,因为我们移除了antPath库

        const line = L.polyline(

            [startPoint.coord, endPoint.coord],

            {

                "weight": 3,

                "color": color,

                "opacity": 0.7

            }

        ).addTo(map);

        

        pathLines.push(line);

    }

}


/* 创建点位标记 */

function createPointMarkers() {

    // 初始化加载进度

    const progressBar = document.getElementById('progressBar');

    

    allPoints.forEach((point, index) => {

        // 更新加载进度

        progressBar.style.width = `${(index / allPoints.length) * 100}%`;

        

        // 获取阶段对应的颜色

        const stageInfo = stageNames.find(s => s.stage === point.stage);

        const color = stageInfo ? stageInfo.color : '#000000';

        

        // 创建圆形标记

        const marker = L.circleMarker(point.coord, {

            radius: 10,

            fillColor: color,

            color: '#ffffff',

            weight: 2,

            opacity: 1,

            fillOpacity: 0.8

        }).addTo(map);

        

        // 存储原始样式,用于后续加亮效果

        marker.originalStyle = {

            radius: 10,

            fillColor: color,

            color: '#ffffff',

            weight: 2,

            opacity: 1,

            fillOpacity: 0.8

        };

        

        // 加亮样式 - 颜色加深、尺寸更大

        // 生成深色版本的颜色

        const darkenColor = (color) => {

            // 简单的颜色加深方法:移除透明度并稍微加深颜色值

            let hex = color.replace('#', '');

            // 转换为RGB

            let r = parseInt(hex.substring(0, 2), 16);

            let g = parseInt(hex.substring(2, 4), 16);

            let b = parseInt(hex.substring(4, 6), 16);

            // 深色处理(减少亮度20%)

            r = Math.max(0, Math.floor(r * 0.8));

            g = Math.max(0, Math.floor(g * 0.8));

            b = Math.max(0, Math.floor(b * 0.8));

            // 转回十六进制

            return '#' + [r, g, b].map(x => {

                const hex = x.toString(16);

                return hex.length === 1 ? '0' + hex : hex;

            }).join('');

        };

        

        const darkColor = darkenColor(color);

        

        marker.highlightStyle = {

            radius: 18,  // 更大的半径

            fillColor: darkColor,  // 使用加深后的颜色

            color: '#ffd700',  // 金色边框

            weight: 4,  // 更粗的边框

            opacity: 1,

            fillOpacity: 1,

            className: 'highlight-marker'  // 添加类名用于可能的CSS动画

        };

        

        // 添加点击事件

        marker.on('click', () => {

            currentPointIndex = index;

            showPointInfo(point);

            moveHorseToPoint(index);

        });

        

        // 添加悬停效果

        marker.on('mouseover', () => {

            marker.setStyle(marker.highlightStyle);

        });

        

        marker.on('mouseout', () => {

            // 只有当不是当前选中的点时才恢复样式

            if (index !== currentPointIndex) {

                marker.setStyle(marker.originalStyle);

            }

        });

        

        // 添加弹出信息 - 中英文并行显示

        marker.bindPopup(`<div class="bilingual-text">

                            <div><b>${point.name}</b></div>

                            <div style="font-size: 14px;">${point.year}年 | ${point.event}</div>

                            <div><b>${point.nameEn}</b></div>

                            <div style="font-size: 12px;">${point.year} A.D. | ${point.eventEn}</div>

                        </div>`, {

            className: 'custom-popup',

            closeButton: true,

            minWidth: 200

        });

        

        markers.push(marker);

    });

}


/* 创建骑马标记 */

function createHorseMarker() {

    // 创建自定义图标

    const horseIcon = L.divIcon({

        html: '🐎',

        className: 'horse-marker',

        iconSize: [30, 30],

        iconAnchor: [15, 15]

    });

    

    // 创建标记

    horseMarker = L.marker(allPoints[0].coord, {

        icon: horseIcon,

        zIndexOffset: 1000

    }).addTo(map);

    

    // 添加轻微的上下浮动动画

    const markerElement = horseMarker.getElement();

    markerElement.style.animation = 'horseFloat 3s ease-in-out infinite';

}


/* 移动骑马标记到指定点位 */

function moveHorseToPoint(index) {

    const point = allPoints[index];

    

    // 平滑移动效果

    if (horseMarker) {

        // 获取当前位置和目标位置

        const currentLatLng = horseMarker.getLatLng();

        const targetLatLng = L.latLng(point.coord);

        

        // 创建路径线段数组,使马能够沿着路径移动

        const pathPoints = [];

        const numSteps = 50; // 路径上的点数量,越多路径越平滑

        

        // 计算两点之间的路径点

        for (let i = 0; i <= numSteps; i++) {

            const progress = i / numSteps;

            // 增加一些随机性,使路径看起来更自然

            const randomFactor = 0.1 * (Math.sin(progress * Math.PI * 4) + Math.random() * 0.5);

            const easedProgress = easeInOutCubic(progress);

            

            // 计算中间位置,添加一些曲线效果

            const lat = currentLatLng.lat + 

                      (targetLatLng.lat - currentLatLng.lat) * easedProgress + 

                      randomFactor * 0.1;

            const lng = currentLatLng.lng + 

                      (targetLatLng.lng - currentLatLng.lng) * easedProgress + 

                      randomFactor * 0.1;

            

            pathPoints.push({ lat, lng, progress });

        }

        

        // 创建马蹄印动画效果

        createHorseTracks(currentLatLng, targetLatLng, numSteps);

        

        // 移动到新位置 - 平滑过渡

        const duration = 3000; // 动画持续时间,增加到3秒使移动更自然

        const startTime = performance.now();

        

        function moveHorse(timestamp) {

            const elapsed = timestamp - startTime;

            const progress = Math.min(elapsed / duration, 1);

            

            // 使用缓动函数使动画更自然

            const easedProgress = easeInOutCubic(progress);

            

            // 找到当前进度对应的路径点

            let currentPathPoint;

            for (let i = 0; i < pathPoints.length; i++) {

                if (pathPoints[i].progress >= easedProgress) {

                    currentPathPoint = pathPoints[i];

                    break;

                }

            }

            

            if (currentPathPoint) {

                // 更新骑马标记的位置

                horseMarker.setLatLng(L.latLng(currentPathPoint.lat, currentPathPoint.lng));

                

                if (progress < 1) {

                    requestAnimationFrame(moveHorse);

                } else {

                    // 动画完成后更新点位状态

                    updateMarkerStates();

                }

            }

        }

        

        // 开始动画

        requestAnimationFrame(moveHorse);

    }

}


/* 创建马蹄印效果 */

function createHorseTracks(startPoint, endPoint, numSteps) {

    // 计算每步之间的距离

    const latStep = (endPoint.lat - startPoint.lat) / numSteps;

    const lngStep = (endPoint.lng - startPoint.lng) / numSteps;

    

    // 创建马蹄印标记

    for (let i = 0; i < numSteps; i += 5) { // 每隔5步创建一个马蹄印

        const lat = startPoint.lat + latStep * i;

        const lng = startPoint.lng + lngStep * i;

        

        // 随机偏移,使马蹄印看起来更自然

        const randomLat = lat + (Math.random() - 0.5) * 0.01;

        const randomLng = lng + (Math.random() - 0.5) * 0.01;

        

        // 创建临时的马蹄印标记

        const trackIcon = L.divIcon({

            html: '👣',

            className: 'horse-track',

            iconSize: [30, 30],

            iconAnchor: [15, 15]

        });

        

        const trackMarker = L.marker([randomLat, randomLng], {

            icon: trackIcon,

            zIndexOffset: 500

        }).addTo(map);

        

        // 设置淡出动画

        setTimeout(() => {

            let opacity = 1;

            const fadeInterval = setInterval(() => {

                opacity -= 0.1;

                trackMarker.setOpacity(opacity);

                

                if (opacity <= 0) {

                    clearInterval(fadeInterval);

                    map.removeLayer(trackMarker);

                }

            }, 100);

        }, 1000);

    }

}


/* 缓动函数 - 使动画更自然 */

function easeInOutCubic(t) {

    return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

}


/* 显示点位信息 */

function showPointInfo(point) {

    const card = document.getElementById('infoCard');

    const title = document.getElementById('infoTitle');

    const year = document.getElementById('infoYear');

    const description = document.getElementById('infoDescription');

    const poem = document.getElementById('infoPoem');

    const anecdote = document.getElementById('infoAnecdote');

    const image = document.getElementById('infoImage');

    

    // 设置内容 - 中英文并行显示

    title.innerHTML = `<div class="bilingual-text">

                            <div class="chinese-text">${point.name}</div>

                            <div class="english-text">${point.nameEn}</div>

                        </div>`;

    

    year.innerHTML = `<div class="bilingual-text">

                        <div class="chinese-text">${point.year}年 | ${point.event}</div>

                        <div class="english-text">${point.year} A.D. | ${point.eventEn}</div>

                    </div>`;

    

    // 检查是否有文化信息

    if (point.culture && point.culture.lines) {

        // 显示诗句题目和内容,中英文并行显示

        const poemTitle = point.culture.title || '诗句'; // 默认题目

        const poemTitleEn = point.culture.titleEn || 'Verse'; // 默认英文题目

        const poemHtml = `

            <div class="bilingual-text poem-title">

                <div class="chinese-text">${poemTitle}</div>

                <div class="english-text">${poemTitleEn}</div>

            </div>

            <div class="bilingual-text">

                <div class="chinese-text poem-highlight">${point.culture.lines.join('<br>')}</div>

                <div class="english-text">${point.culture.linesEn.join('<br>')}</div>

            </div>`;

        

        poem.innerHTML = poemHtml;

        

        // 显示文化轶事,中英文并行显示

        if (point.culture.anecdote) {

            anecdote.innerHTML = `<div class="bilingual-text">

                                    <div class="chinese-text">${point.culture.anecdote}</div>

                                    <div class="english-text">${point.culture.anecdoteEn}</div>

                                </div>`;

            anecdote.style.display = 'block';

        } else {

            anecdote.style.display = 'none';

        }

    } else {

        // 没有文化信息的情况下,也显示诗题

        const poemTitle = '诗句'; // 默认题目

        const poemTitleEn = 'Verse'; // 默认英文题目

        poem.innerHTML = `<div class="bilingual-text poem-title">

                            <div class="chinese-text">${poemTitle}</div>

                            <div class="english-text">${poemTitleEn}</div>

                        </div>

                        <div class="bilingual-text">

                            <div class="chinese-text poem-highlight">${point.poem}</div>

                            <div class="english-text">${point.poemEn}</div>

                        </div>`;

        anecdote.style.display = 'none';

    }

    

    // 设置图片

    image.onload = function() {

        image.classList.remove('image-loading');

    };

    

    image.onerror = function() {

        // 如果加载失败,使用备用图片

        image.src = point.fallbackImage || 'https://picsum.photos/id/1000/800/600';

        image.classList.remove('image-loading');

    };

    

    // 开始加载图片

    image.classList.add('image-loading');

    image.src = point.image;

    

    // 显示卡片

    setTimeout(() => {

        card.classList.add('active');

    }, 100);

    

    // 滚动到顶部

    card.querySelector('.info-content').scrollTop = 0;

    

    // 启动自动滚动

    startAutoScroll();

}


/* 初始化阶段颜色指示器 - 中英文并行显示 */

function initStageIndicators() {

    const container = document.getElementById('stageColors');

    container.innerHTML = '';

    

    // 同时显示中文和英文的阶段名称

    stageNames.forEach((stage, index) => {

        const item = document.createElement('div');

        item.className = 'stage-item';

        

        const colorBox = document.createElement('div');

        colorBox.className = 'stage-color';

        colorBox.style.backgroundColor = stage.color;

        

        const nameContainer = document.createElement('div');

        nameContainer.className = 'bilingual-text';

        

        const nameZhSpan = document.createElement('div');

        nameZhSpan.className = 'chinese-text';

        nameZhSpan.textContent = stage.name;

        

        const nameEnSpan = document.createElement('div');

        nameEnSpan.className = 'english-text';

        nameEnSpan.textContent = stageNamesEn[index]?.name || '';

        

        nameContainer.appendChild(nameZhSpan);

        nameContainer.appendChild(nameEnSpan);

        

        item.appendChild(colorBox);

        item.appendChild(nameContainer);

        container.appendChild(item);

    });

}


/* 更新标记状态 */

function updateMarkerStates() {

    markers.forEach((marker, index) => {

        if (index === currentPointIndex) {

            // 当前点使用高亮样式

            marker.setStyle(marker.highlightStyle);

            marker.openPopup(); // 打开当前点的弹出信息

        } else {

            // 其他点使用原始样式

            marker.setStyle(marker.originalStyle);

            marker.closePopup(); // 关闭其他点的弹出信息

        }

    });

}


/* 显示前一个点位 */

function prevPoint() {

    currentPointIndex = (currentPointIndex - 1 + allPoints.length) % allPoints.length;

    const point = allPoints[currentPointIndex];

    showPointInfo(point);

    moveHorseToPoint(currentPointIndex);

}


/* 显示下一个点位 */

function nextPoint() {

    currentPointIndex = (currentPointIndex + 1) % allPoints.length;

    const point = allPoints[currentPointIndex];

    showPointInfo(point);

    moveHorseToPoint(currentPointIndex);

}


/* 切换自动播放 */

function toggleAnimation() {

    const playBtn = document.getElementById('playBtn');

    

    if (isAnimating) {

        // 停止动画

        clearInterval(animationInterval);

        playBtn.textContent = '▶';

        playBtn.setAttribute('data-tooltip', '自动播放');

    } else {

        // 开始动画

        animationInterval = setInterval(nextPoint, animationDelay);

        playBtn.textContent = '⏸';

        playBtn.setAttribute('data-tooltip', '暂停自动播放');

    }

    

    isAnimating = !isAnimating;

}


/* 隐藏信息卡片 */

function hideInfoCard() {

    const card = document.getElementById('infoCard');

    card.classList.remove('active');

    

    // 停止自动滚动

    stopAutoScroll();

}


/* 切换卡片折叠状态 */

function toggleCardCollapse() {

    const card = document.getElementById('infoCard');

    card.classList.toggle('collapsed');

}


/* 启动自动滚动 */

function startAutoScroll() {

    if (!isScrolling) return;

    

    const content = document.getElementById('infoCard').querySelector('.info-content');

    const maxScroll = content.scrollHeight - content.clientHeight;

    

    if (maxScroll <= 0) return; // 如果没有可滚动的内容,则不启动自动滚动

    

    // 清除现有的动画

    if (scrollAnimationId) {

        cancelAnimationFrame(scrollAnimationId);

    }

    

    let lastTime = 0;

    

    function scrollContent(timestamp) {

        if (!lastTime) lastTime = timestamp;

        const elapsed = timestamp - lastTime;

        

        // 根据时间计算滚动距离

        const scrollDistance = (elapsed / 1000) * scrollSpeed;

        

        // 更新滚动位置

        const currentScroll = content.scrollTop;

        const newScroll = Math.min(currentScroll + scrollDistance, maxScroll);

        content.scrollTop = newScroll;

        

        // 记录当前滚动位置,用于后续恢复

        lastScrollY = newScroll;

        

        // 检查是否需要继续滚动

        if (newScroll < maxScroll && isScrolling) {

            scrollAnimationId = requestAnimationFrame(scrollContent);

        }

    }

    

    // 开始滚动动画

    scrollAnimationId = requestAnimationFrame(scrollContent);

}


/* 停止自动滚动 */

function stopAutoScroll() {

    if (scrollAnimationId) {

        cancelAnimationFrame(scrollAnimationId);

        scrollAnimationId = null;

    }

}


/* 切换自动滚动状态 */

function toggleScroll() {

    isScrolling = !isScrolling;

    const pauseBtn = document.getElementById('pauseScrollBtn');

    

    if (isScrolling) {

        pauseBtn.textContent = '⏸';

        startAutoScroll();

    } else {

        pauseBtn.textContent = '▶';

        stopAutoScroll();

    }

}


/* 切换语言 - 保留按钮但实际是中英文同时显示 */

function toggleLanguage() {

    isEn = !isEn;

    const btnZh = document.getElementById('btnZh');

    const btnEn = document.getElementById('btnEn');

    

    if (isEn) {

        btnZh.classList.remove('active');

        btnEn.classList.add('active');

    } else {

        btnZh.classList.add('active');

        btnEn.classList.remove('active');

    }

}


/* 回到顶部 */

function scrollToTop() {

    window.scrollTo({

        top: 0,

        behavior: 'smooth'

    });

}


/* 处理滚动事件 */

function handleScroll() {

    const backToTop = document.getElementById('backToTop');

    const scrollY = window.scrollY;

    

    // 显示/隐藏回到顶部按钮

    if (scrollY > 300) {

        backToTop.classList.add('visible');

    } else {

        backToTop.classList.remove('visible');

    }

}


/* 页面加载完成后初始化 */

window.onload = function() {

    // 初始化地图

    initMap();

    

    // 显示第一个点的信息

    setTimeout(() => {

        showPointInfo(allPoints[0]);

        updateMarkerStates();

    }, 1500);

    

    // 添加滚动事件监听

    window.addEventListener('scroll', handleScroll);

    

    // 为信息卡片添加点击事件

    document.getElementById('infoCard').addEventListener('click', function(e) {

        // 如果点击的不是关闭按钮或折叠按钮,则切换卡片的显示状态

        if (!e.target.closest('.info-close') && !e.target.closest('.collapse-btn') && !e.target.closest('.scroll-control')) {

            this.classList.toggle('active');

        }

    });

    

    // 添加键盘事件监听

    document.addEventListener('keydown', function(e) {

        if (e.key === 'ArrowLeft') {

            prevPoint();

        } else if (e.key === 'ArrowRight') {

            nextPoint();

        } else if (e.key === ' ') {

            // 空格控制播放/暂停

            e.preventDefault(); // 阻止页面滚动

            toggleAnimation();

        }

    });

    

    // 为窗口调整事件添加监听,重置地图大小

    window.addEventListener('resize', function() {

        setTimeout(() => {

            map.invalidateSize();

        }, 100);

    });

    

    // 添加触摸滑动支持

    let touchStartX = 0;

    let touchEndX = 0;

    

    document.addEventListener('touchstart', function(e) {

        touchStartX = e.changedTouches[0].screenX;

    }, false);

    

    document.addEventListener('touchend', function(e) {

        touchEndX = e.changedTouches[0].screenX;

        handleSwipe();

    }, false);

    

    function handleSwipe() {

        const swipeThreshold = 50;

        if (touchEndX < touchStartX - swipeThreshold) {

            // 向左滑动,显示下一个点

            nextPoint();

        } else if (touchEndX > touchStartX + swipeThreshold) {

            // 向右滑动,显示上一个点

            prevPoint();

        }

    }

}

</script>

</body>

</html>

云计算支持 反馈 枢纽云管理
回到顶部