script.js

23.47 KB
09/08/2025 03:33
JS
script.js
// Modern Kanchanaburi Travel Guide JavaScript

// Global variables
let currentSlideIndex = 0;
let slideInterval;

// DOM Content Loaded
document.addEventListener('DOMContentLoaded', function() {
  initializeApp();
});

// Initialize all functionality
function initializeApp() {
  setupNavigation();
  setupSlideshow();
  setupScrollAnimations();
  setupSmoothScrolling();
  lazyLoadImages();
}

// Navigation functionality
function setupNavigation() {
  const navbar = document.getElementById('navbar');
  const navLinks = document.querySelectorAll('nav a');

  // Sticky navbar on scroll
  window.addEventListener('scroll', () => {
    if (window.scrollY > 100) {
      navbar.style.background = 'rgba(255,255,255,0.98)';
      navbar.style.boxShadow = '0 5px 20px rgba(0,0,0,0.1)';
    } else {
      navbar.style.background = 'rgba(255,255,255,0.95)';
      navbar.style.boxShadow = '0 2px 10px rgba(0,0,0,0.05)';
    }
  });

  // Active navigation highlighting
  window.addEventListener('scroll', () => {
    let current = '';
    const sections = document.querySelectorAll('section');

    sections.forEach(section => {
      const sectionTop = section.offsetTop;
      const sectionHeight = section.clientHeight;
      if (window.scrollY >= (sectionTop - 200)) {
        current = section.getAttribute('id');
      }
    });

    navLinks.forEach(link => {
      link.classList.remove('active');
      if (link.getAttribute('href') === '#' + current) {
        link.classList.add('active');
      }
    });
  });
}

// Slideshow functionality
function setupSlideshow() {
  const slides = document.querySelectorAll('.slide');
  const indicators = document.querySelectorAll('.indicator');

  if (slides.length === 0) return;

  startSlideshow();

  // Auto-play slideshow
  function startSlideshow() {
    slideInterval = setInterval(() => {
      changeSlide(1);
    }, 6000); // เพิ่มเวลาเป็น 6 วินาทีเพื่อให้ชมได้นานขึ้น
  }

  // Pause on hover
  const slideshowContainer = document.querySelector('.slideshow-container');
  if (slideshowContainer) {
    slideshowContainer.addEventListener('mouseenter', () => {
      clearInterval(slideInterval);
    });

    slideshowContainer.addEventListener('mouseleave', () => {
      startSlideshow();
    });
  }
}

// Change slide function with fade transition
function changeSlide(direction) {
  const slides = document.querySelectorAll('.slide');
  const indicators = document.querySelectorAll('.indicator');
  const currentSlide = slides[currentSlideIndex];

  // Add fade-out effect to current slide
  currentSlide.classList.add('fade-out');
  indicators[currentSlideIndex].classList.remove('active');

  // Update slide index
  currentSlideIndex += direction;

  if (currentSlideIndex >= slides.length) {
    currentSlideIndex = 0;
  } else if (currentSlideIndex < 0) {
    currentSlideIndex = slides.length - 1;
  }

  // Add fade-in effect to new slide with delay
  setTimeout(() => {
    // Remove all transition classes
    slides.forEach(slide => {
      slide.classList.remove('active', 'fade-out');
    });

    // Add active class to new slide
    slides[currentSlideIndex].classList.add('active');
    indicators[currentSlideIndex].classList.add('active');
  }, 400);
}

// Go to specific slide with fade transition
function goToSlide(n) {
  const slides = document.querySelectorAll('.slide');
  const indicators = document.querySelectorAll('.indicator');
  const targetIndex = n - 1;

  if (targetIndex === currentSlideIndex) return;

  const currentSlide = slides[currentSlideIndex];

  // Add fade-out effect
  currentSlide.classList.add('fade-out');
  indicators[currentSlideIndex].classList.remove('active');

  // Set new slide index
  currentSlideIndex = targetIndex;

  // Add fade-in effect to new slide with delay
  setTimeout(() => {
    // Remove all transition classes
    slides.forEach(slide => {
      slide.classList.remove('active', 'fade-out');
    });

    // Add active class to new slide
    slides[currentSlideIndex].classList.add('active');
    indicators[currentSlideIndex].classList.add('active');
  }, 400);

  // Restart slideshow
  clearInterval(slideInterval);
  setTimeout(() => {
    slideInterval = setInterval(() => {
      changeSlide(1);
    }, 6000);
  }, 1000);
}

// Scroll animations
function setupScrollAnimations() {
  const observerOptions = {
    threshold: 0.1,
    rootMargin: '0px 0px -50px 0px'
  };

  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        const delay = entry.target.getAttribute('data-delay') || 0;
        setTimeout(() => {
          entry.target.classList.add('show');
        }, delay);
      }
    });
  }, observerOptions);

  // Observe all fade-in-up elements
  document.querySelectorAll('.fade-in-up').forEach(el => {
    observer.observe(el);
  });

  // Observe content cards
  document.querySelectorAll('.content-card').forEach(el => {
    observer.observe(el);
  });
}

// Smooth scrolling for navigation links
function setupSmoothScrolling() {
  document.querySelectorAll('.nav-container a').forEach(anchor => {
    anchor.addEventListener('click', function(e) {
      e.preventDefault();
      const target = document.querySelector(this.getAttribute('href'));
      if (target) {
        const offsetTop = target.offsetTop - 80; // Account for fixed navbar
        window.scrollTo({
          top: offsetTop,
          behavior: 'smooth'
        });
      }
    });
  });
}

// Lazy loading images
function lazyLoadImages() {
  if ('IntersectionObserver' in window) {
    const imageObserver = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = entry.target;
          img.classList.add('loaded');
          observer.unobserve(img);
        }
      });
    });

    document.querySelectorAll('img').forEach(img => {
      img.setAttribute('loading', 'lazy');
      imageObserver.observe(img);
    });
  }
}

// Utility functions for Excel processing (keeping from original)
var gk_isXlsx = false;
var gk_xlsxFileLookup = {};
var gk_fileData = {};

function filledCell(cell) {
  return cell !== '' && cell != null;
}

function loadFileData(filename) {
  if (gk_isXlsx && gk_xlsxFileLookup[filename]) {
    try {
      var workbook = XLSX.read(gk_fileData[filename], {type: 'base64'});
      var firstSheetName = workbook.SheetNames[0];
      var worksheet = workbook.Sheets[firstSheetName];

      var jsonData = XLSX.utils.sheet_to_json(worksheet, {header: 1, blankrows: false, defval: ''});
      var filteredData = jsonData.filter(row => row.some(filledCell));

      var headerRowIndex = filteredData.findIndex((row, index) =>
        row.filter(filledCell).length >= filteredData[index + 1]?.filter(filledCell).length
      );

      if (headerRowIndex === -1 || headerRowIndex > 25) {
        headerRowIndex = 0;
      }

      var csv = XLSX.utils.aoa_to_sheet(filteredData.slice(headerRowIndex));
      csv = XLSX.utils.sheet_to_csv(csv, {header: 1});
      return csv;
    } catch (e) {
      console.error(e);
      return "";
    }
  }
  return gk_fileData[filename] || "";
}

// Modal functionality
const attractionData = {
  bridge: {
    title: 'สะพานข้ามแม่น้ำแคว',
    image: 'images/bridge.webp',
    description: `
            <p>สะพานข้ามแม่น้ำแควเป็นหนึ่งในแลนด์มาร์กที่มีชื่อเสียงที่สุดของไทย ตั้งอยู่ในจังหวัดกาญจนบุรี สะพานนี้ถูกสร้างขึ้นในระหว่างสงครามโลกครั้งที่ 2 โดยเชลยศึกสัมพันธมิตรและแรงงานเอเชีย เป็นส่วนหนึ่งของทางรถไฟสายมรณะที่เชื่อมระหว่างไทยและพม่า</p>

            <p>สะพานเหล็กข้ามแม่น้ำแควนี้มีความยาว 300 เมตร สูง 17 เมตร เป็นสะพานเหล็กโครงสร้างเหลี่ยม ปัจจุบันยังคงใช้งานเป็นทางรถไฟเส้นทางกรุงเทพ-น่าน โดยรถไฟจะผ่านวันละ 2-3 ขบวน</p>

            <p>บริเวณสะพานมีตลาดนัดและร้านค้าขายของที่ระลึก มีเรือสำราญให้นักท่องเที่ยวชมสะพานจากมุมมองในแม่น้ำ และมีพิพิธภัณฑ์สงครามโลกครั้งที่ 2 อยู่ใกล้เคียง</p>
        `,
    info: [
      {icon: 'fas fa-map-marker-alt', label: 'ที่ตั้ง', value: 'ต.ท่ามะขาม อ.เมืองกาญจนบุรี จ.กาญจนบุรี'},
      {icon: 'fas fa-clock', label: 'เวลาเปิด', value: '24 ชั่วโมง (สามารถเข้าชมได้ตลอด)'},
      {icon: 'fas fa-car', label: 'การเดินทาง', value: 'จากตัวเมืองกาญจนบุรี 4.8 กม. (ประมาณ 10 นาที)'},
      {icon: 'fas fa-ticket-alt', label: 'ค่าเข้าชม', value: 'ฟรี (เดินบนสะพาน)'},
      {icon: 'fas fa-train', label: 'รถไฟผ่าน', value: 'วันละ 2-3 ขบวน (ระวังขณะเดิน)'},
      {icon: 'fas fa-ship', label: 'ล่องเรือ', value: 'ประมาณ 100-200 บาท/คน'}
    ],
    highlights: [
      'เดินข้ามสะพานเหล็กประวัติศาสตร์ยาว 300 เมตร',
      'ถ่ายรูปกับสะพานที่มีชื่อเสียงระดับโลก',
      'ชมพิพิธภัณฑ์สงครามโลกครั้งที่ 2',
      'ล่องเรือชมสะพานจากแม่น้ำแคว',
      'เยือนสุสานทหารสัมพันธมิตรกาญจนบุรี',
      'ช้อปปิ้งของที่ระลึกที่ตลาดริมสะพาน'
    ],
    tips: [
      'หลีกเลี่ยงการเดินบนสะพานในช่วง 11.00-14.00 น. เพราะแดดแรง',
      'ระวังรถไฟที่วิ่งผ่านสะพาน ให้เดินไปยังจุดหลบที่จัดไว้',
      'แนะนำมาช่วงเช้าหรือเย็นเพื่อแสงสวยสำหรับถ่ายรูป',
      'ควรใส่รองเท้าที่กันลื่นเพราะพื้นสะพานเป็นเหล็ก',
      'สามารถซื้อตั้วรถไฟเล่นเป็นของฝากได้',
      'มีห้องน้ำและที่จอดรถบริเวณใกล้สะพาน'
    ]
  },

  erawan: {
    title: 'น้ำตกเอราวัณ',
    image: 'images/erawan.webp',
    description: `
            <p>น้ำตกเอราวัณเป็นน้ำตกที่สวยที่สุดแห่งหนึ่งในประเทศไทย ตั้งอยู่ในอุทยานแห่งชาติเอราวัณ อำเภอศรีสวัสดิ์ จังหวัดกาญจนบุรี มีลักษณะเป็นน้ำตกหินปูน 7 ชั้น น้ำใสสีฟ้าอมเขียวสวยงาม</p>

            <p>น้ำตกแต่ละชั้นมีความสวยงามและลักษณะแตกต่างกัน ชั้นที่ 1-3 เหมาะสำหรับครอบครัวและผู้สูงอายุ ชั้นที่ 4-7 ต้องเดินป่าขึ้นเขาค่อนข้างชัน เหมาะสำหรับผู้ที่ชอบผจญภัย</p>

            <p>น้ำตกเอราวัณมีปลาขนาดเล็กที่ไม่เป็นอันตราย จะมากินเซลล์ผิวหนังที่เท้า ทำให้เกิดประสบการณ์ที่น่าสนใจ และมีบริการ Fish Spa ธรรมชาติ</p>
        `,
    info: [
      {icon: 'fas fa-map-marker-alt', label: 'ที่ตั้ง', value: 'ต.ท่ากระดาน อ.ศรีสวัสดิ์ จ.กาญจนบุรี'},
      {icon: 'fas fa-clock', label: 'เวลาเปิด', value: '07:00-17:00 น. (ปิดวันจันทร์)'},
      {icon: 'fas fa-ticket-alt', label: 'ค่าเข้าอุทยาน', value: 'ผู้ใหญ่ 100 บาท, เด็ก 50 บาท'},
      {icon: 'fas fa-hiking', label: 'เวลาเดิน', value: 'ชั้น 1-3: 1 ชม. | ชั้น 4-7: 3-4 ชม.'},
      {icon: 'fas fa-car', label: 'ระยะทาง', value: 'จากกาญจนบุรี 65 กม. (1.5 ชม.)'},
      {icon: 'fas fa-swimming-pool', label: 'เล่นน้ำ', value: 'อนุญาตในบริเวณที่กำหนด'}
    ],
    highlights: [
      'ชมน้ำตก 7 ชั้นที่สวยงามระดับโลก',
      'เล่นน้ำใสสีฟ้ามรกตในบ่อธรรมชาติ',
      'สัมผัส Fish Spa ธรรมชาติจากปลาป่า',
      'ถ่ายรูปกับหินปูนและถ้ำเล็กๆ',
      'เดินป่าชมธรรมชาติในอุทยาน',
      'ชั้นที่ 7 มีสระว่ายน้ำธรรมชาติสวยที่สุด'
    ],
    tips: [
      'ควรออกเดินทางแต่เช้าเพื่อหลีกเลี่ยงนักท่องเที่ยวเยอะ',
      'ใส่รองเท้าเดินป่าหรือรองเท้ากันลื่น',
      'เตรียมชุดว่ายน้ำและผ้าเช็ดตัว',
      'ห้ามใช้ครีมกันแดดหรือสบู่ในน้ำ (เพื่อรักษาสิ่งแวดล้อม)',
      'เก็บขยะกลับมาด้วยเสมอ',
      'ระวังลิงที่อาจมาแย่งอาหาร',
      'มีที่จอดรถและร้านอาหารในอุทยาน'
    ]
  },

  tree: {
    title: 'ต้นจามจุรียักษ์',
    image: 'images/tree.webp',
    description: `
            <p>ต้นจามจุรียักษ์เป็นต้นไม้โบราณที่มีอายุมากกว่า 100 ปี ตั้งอยู่ในเขตสถานีวิจัยป่าไผ่ กรมป่าไผ่และหวาย ในพื้นที่ตำบลเกาะสำโรง อำเภอเมือง จังหวัดกาญจนบุรี</p>

            <p>ต้นจามจุรียักษ์นี้มีขนาดโอ่โถง เส้นรอบวงลำต้นประมาณ 31 เมตร ต้องใช้คนประมาณ 10 คน จึงจะอ้อมรอบได้ ทรงพุ่มกว้างประมาณ 50 เมตร ความสูงประมาณ 30 เมตร เป็นต้นไม้ที่ให้ร่มเงาแก่ผู้คน</p>

            <p>บริเวณต้นไม้มีการจัดสวนและบางส่วนเป็นสวนป่าธรรมชาติ มีเส้นทางเดินชมรอบต้นไม้ และมีป้ายบอกข้อมูlเกี่ยวกับต้นไม้นี้</p>
        `,
    info: [
      {icon: 'fas fa-map-marker-alt', label: 'ที่ตั้ง', value: 'ต.เกาะสำโรง อ.เมืองกาญจนบุรี จ.กาญจนบุรี'},
      {icon: 'fas fa-clock', label: 'เวลาเปิด', value: '08:30-16:30 น.'},
      {icon: 'fas fa-ticket-alt', label: 'ค่าเข้าชม', value: 'ฟรี (ไม่เสียค่าใช้จ่าย)'},
      {icon: 'fas fa-birthday-cake', label: 'อายุ', value: 'มากกว่า 100 ปี'},
      {icon: 'fas fa-ruler', label: 'เส้นรอบวง', value: '31 เมตร (10 คนอ้อม)'},
      {icon: 'fas fa-tree', label: 'ทรงพุ่ม', value: 'กว้าง 50 เมตร สูง 30 เมตร'}
    ],
    highlights: [
      'ชมต้นจามจุรียักษ์อายุกว่า 100 ปี',
      'ถ่ายรูปกับต้นไม้ใหญ่สวยงาม',
      'เดินชมสวนป่าธรรมชาติรอบๆ',
      'เรียนรู้เรื่องราวของต้นไม้โบราณ',
      'สัมผัสร่มเงาจากต้นไม้ยักษ์',
      'สำรวจพันธุ์ไม้อื่นๆ ในบริเวณ'
    ],
    tips: [
      'เหมาะสำหรับถ่ายรูปครอบครัว',
      'ควรมาช่วงเช้าหรือบ่าย แสงสวยและอากาศเย็น',
      'มีที่นั่งพักผ่อนใต้ร่มไม้',
      'เส้นทางเดินไม่ยาก เหมาะสำหรับทุกวัย',
      'ระยะทางจากตัวเมืองไม่ไกล',
      'สามารถผนวกกับสถานที่อื่นในวันเดียวกัน'
    ]
  },

  skywalk: {
    title: 'สกายวอล์คเมืองกาญจนบุรี',
    image: 'images/skywalk.webp',
    description: `
            <p>สกายวอล์คเมืองกาญจนบุรีเป็นสะพานกระจกใสที่สร้างขึ้นใหม่ เป็นจุดชมวิวแม่น้ำแควที่สวยงาม ตั้งอยู่บริเวณบ้านใต้ ริมแม่น้ำแคว ใกล้กับวัดถ้ำมังคลธรรม</p>

            <p>สกายวอล์คมีความยาว 150 เมตร สูงจากระดับน้ำประมาณ 12 เมตร ทำจากกระจกนิรภัย สามารถมองเห็นแม่น้ำแควใสไหลผ่านใต้ฝ่าเท้า ชมวิวทิวทัศน์ของแม่น้ำแควและภูเขาโดยรอบ</p>

            <p>บริเวณสกายวอล์คมีศาลาพักผ่อน ร้านกาแฟเล็กๆ และจุดขายของที่ระลึก เป็นสถานที่ยอดนิยมสำหรับถ่ายรูปและชมพระอาทิตย์ตก</p>
        `,
    info: [
      {icon: 'fas fa-map-marker-alt', label: 'ที่ตั้ง', value: 'ต.บ้านใต้ อ.เมืองกาญจนบุรี จ.กาญจนบุรี'},
      {icon: 'fas fa-clock', label: 'เวลาเปิด', value: '09:00-18:00 น.'},
      {icon: 'fas fa-ticket-alt', label: 'ค่าเข้าชม', value: 'ค่ารองเท้าคลุม 20 บาท'},
      {icon: 'fas fa-ruler-vertical', label: 'ขนาด', value: 'ยาว 150 ม. สูง 12 ม.'},
      {icon: 'fas fa-car', label: 'ระยะทาง', value: 'จากตัวเมือง 15 กม. (30 นาที)'},
      {icon: 'fas fa-camera', label: 'จุดถ่ายรูป', value: 'วิวแม่น้ำแคว 360 องศา'}
    ],
    highlights: [
      'เดินบนสกายวอล์คกระจกใสยาว 150 เมตร',
      'ชมวิวแม่น้ำแควจากมุมสูง',
      'ถ่ายรูปกับบิวพันนิงค์แม่น้ำและภูเขา',
      'ชมพระอาทิตย์ตกริมแม่น้ำแคว',
      'เยือนวัดถ้ำมังคลธรรมในบริเวณใกล้เคียง',
      'จิบกาแฟและชมวิวในคาเฟ่'
    ],
    tips: [
      'ช่วงเย็นวิวสวยที่สุด เหมาะชมพระอาทิตย์ตก',
      'ต้องสวมรองเท้าคลุมก่อนขึ้นสกายวอล์ค',
      'หากกลัวความสูงอาจรู้สึกเวียนหัว',
      'ควรถ่ายรูปในมุมต่างๆ ได้วิวสวย',
      'มีที่จอดรถและห้องน้ำบริการ',
      'สามารถผนวกกับการเยือนวัดถ้ำได้'
    ]
  }
};

function openModal(attraction) {
  const modal = document.getElementById('attractionModal');
  const data = attractionData[attraction];

  if (!data) return;

  document.getElementById('modalTitle').textContent = data.title;
  document.getElementById('modalImage').src = data.image;
  document.getElementById('modalImage').alt = data.title;
  document.getElementById('modalDescription').innerHTML = data.description;

  // Populate info
  const infoHTML = data.info.map(item => `
        <div class="modal-info-item">
            <strong><i class="${item.icon}"></i> ${item.label}:</strong>
            <span>${item.value}</span>
        </div>
    `).join('');
  document.getElementById('modalInfo').innerHTML = infoHTML;

  // Populate highlights
  const highlightsHTML = data.highlights.map(item => `<li>${item}</li>`).join('');
  document.getElementById('modalHighlights').innerHTML = highlightsHTML;

  // Populate tips
  const tipsHTML = data.tips.map(item => `<li>${item}</li>`).join('');
  document.getElementById('modalTips').innerHTML = tipsHTML;

  modal.style.display = 'block';
  document.body.style.overflow = 'hidden';
}

function closeModal() {
  const modal = document.getElementById('attractionModal');
  modal.style.display = 'none';
  document.body.style.overflow = 'auto';
}

// Close modal when clicking outside
window.onclick = function(event) {
  const modal = document.getElementById('attractionModal');
  if (event.target === modal) {
    closeModal();
  }
}

// Close modal with Escape key
document.addEventListener('keydown', function(event) {
  if (event.key === 'Escape') {
    closeModal();
  }
});