/* ---------- js ---------- */ jQuery(function ($) { /* 모바일 메뉴 열기 */ function mNav_open() { $(".btn-nav").addClass("mNav_open"); $("#header .navWrap").addClass("mNav_open"); $(".gnbMenuBg").fadeIn(); } function mNav_close() { $(".btn-nav").removeClass("mNav_open"); $("#header .navWrap").removeClass("mNav_open"); $(".gnbMenuBg").fadeOut(); } $(".btn-nav").click(function () { if (!$(this).hasClass("mNav_open")) { mNav_open(); } else { mNav_close(); } }); $(".gnbMenuBg,.mobile-header-close,.navWrap .gnb > li > a,.header-go-to-top").click(function () { mNav_close(); }); $(window).resize(function () { if ($(window).width() > 991) { mNav_close(); }; }); $(window).scroll(function () { if ($(this).scrollTop() > 150) $('.go-to-top').fadeIn('slow'); else $('.go-to-top').fadeOut('slow'); }); $('.header-go-to-top').click(function () { $("html, body").animate({ scrollTop: 0 }, 500); return false; }); $('.go-to-top').click(function () { $("html, body").animate({ scrollTop: 0 }, 500); return false; }); }); // 유튜브 $(document).ready(function () { initYouTubeBackground(); }); var youtubePlayer; function initYouTubeBackground() { var container = $('.youtube-background-container'); if (!container.length) { return; } var videoId = container.data('video-id'); var startSeconds = container.data('start-seconds') || 0; var endSeconds = container.data('end-seconds') || 0; var mute = container.data('mute') !== undefined ? container.data('mute') : true; var autoplay = container.data('autoplay') !== undefined ? container.data('autoplay') : true; var loop = container.data('loop') !== undefined ? container.data('loop') : true; var fitType = container.data('fit-type') || 'auto'; if (!videoId) { console.error('data-video-id 속성이 필요합니다.'); return; } if (typeof YT === 'undefined' || typeof YT.Player === 'undefined') { // YouTube API 로드 var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = $('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); window.onYouTubeIframeAPIReady = function () { createYouTubePlayer(videoId, startSeconds, endSeconds, mute, autoplay, loop, fitType); }; } else { createYouTubePlayer(videoId, startSeconds, endSeconds, mute, autoplay, loop, fitType); } } function createYouTubePlayer(videoId, startSeconds, endSeconds, mute, autoplay, loop, fitType) { // 컨테이너 스타일 초기화 $('.youtube-background-container').css({ 'position': 'absolute', 'overflow': 'hidden', 'width': '100%', 'height': '100%' }); var playerContainer = $('
') .addClass('youtube-background-player') .attr('id', 'youtube-player-' + videoId) .css({ 'position': 'absolute', 'pointer-events': 'none' }); $('.youtube-background-container').append(playerContainer); var playerVars = { 'autoplay': autoplay ? 1 : 0, 'controls': 0, 'showinfo': 0, 'modestbranding': 1, 'loop': 0, // 루프는 직접 제어하기 위해 0으로 설정 'fs': 0, 'cc_load_policy': 0, 'iv_load_policy': 3, 'autohide': 1, 'mute': mute ? 1 : 0, 'playsinline': 1, 'disablekb': 1, 'widget_referrer': window.location.href, 'quality': 'hd1080' // 1080p 화질 설정 }; if (startSeconds > 0) { playerVars['start'] = startSeconds; } youtubePlayer = new YT.Player('youtube-player-' + videoId, { videoId: videoId, playerVars: playerVars, events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); function onPlayerReady(event) { // 최고 화질로 설정 event.target.setPlaybackQuality('hd1080'); adjustPlayerSize(fitType); $(window).on('resize', function () { adjustPlayerSize(fitType); }); } function onPlayerStateChange(event) { // 동영상이 끝났을 때 처리 if (loop && event.data === YT.PlayerState.ENDED) { // 시작 시간으로 돌아가서 다시 재생 if (startSeconds > 0 || endSeconds > 0) { event.target.seekTo(startSeconds); event.target.playVideo(); } else { event.target.playVideo(); } } // 동영상 재생 중 종료 시간에 도달했는지 확인 if (endSeconds > 0 && event.data === YT.PlayerState.PLAYING) { // 현재 시간을 주기적으로 확인하여 종료 시간에 도달하면 처리 var checkTime = setInterval(function () { var currentTime = event.target.getCurrentTime(); if (currentTime >= endSeconds) { clearInterval(checkTime); if (loop) { event.target.seekTo(startSeconds); event.target.playVideo(); } else { event.target.pauseVideo(); } } }, 1000); // 다음 상태 변경 시 이전 인터벌 제거 $(youtubePlayer).on('onStateChange', function () { clearInterval(checkTime); }); } } } function adjustPlayerSize(fitType) { if (!youtubePlayer) { return; } var container = $('.youtube-background-container'); var playerElement = youtubePlayer.getIframe(); if (!container.length || !playerElement) { return; } // 컨테이너가 보이지 않는 경우를 대비한 최소 크기 설정 if (container.height() === 0) { container.css('height', '100vh'); } var containerWidth = container.width(); var containerHeight = container.height(); var videoRatio = 16 / 9; var containerRatio = containerWidth / containerHeight; var newWidth, newHeight; if (fitType === 'contain') { if (containerRatio > videoRatio) { newHeight = containerHeight; newWidth = containerHeight * videoRatio; } else { newWidth = containerWidth; newHeight = containerWidth / videoRatio; } } else if (fitType === 'cover' || fitType === 'auto') { if (containerRatio > videoRatio) { newWidth = containerWidth; newHeight = containerWidth / videoRatio; } else { newHeight = containerHeight; newWidth = containerHeight * videoRatio; } } $(playerElement).css({ 'position': 'absolute', 'width': newWidth + 'px', 'height': newHeight + 'px', 'top': '50%', 'left': '50%', 'transform': 'translate(-50%, -50%)', 'pointer-events': 'none' }); } // 윈도우 로드 완료 후 한번 더 사이즈 조정 $(window).on('load', function () { if (youtubePlayer) { adjustPlayerSize($('.youtube-background-container').data('fit-type') || 'auto'); } }); // 연결선 동적 생성 및 조정 document.addEventListener('DOMContentLoaded', function () { // 창 크기가 변경될 때마다 연결선 업데이트 function updateConnectors() { // 모든 highlight-pair를 순회 const pairs = document.querySelectorAll('.highlight-pair'); pairs.forEach(function (pair, index) { const circle = pair.querySelector('.highlight-circle'); const infoBox = pair.querySelector('.info-box'); const connector = document.querySelectorAll('.connector-line')[index]; if (circle && infoBox && connector) { // 원과 박스의 위치 계산 const circleRect = circle.getBoundingClientRect(); const boxRect = infoBox.getBoundingClientRect(); const containerRect = document.querySelector('.antler-container').getBoundingClientRect(); // 컨테이너를 기준으로 한 상대 위치 계산 const circleX = circleRect.left + circleRect.width / 2 - containerRect.left; const circleY = circleRect.top + circleRect.height / 2 - containerRect.top; const boxX = boxRect.left + ((index % 2 === 0) ? 0 : boxRect.width) - containerRect.left; const boxY = boxRect.top + boxRect.height / 2 - containerRect.top; // 경로 문자열 생성 - 직선으로 변경 const path = `M ${circleX},${circleY} L ${boxX},${boxY}`; connector.setAttribute('d', path); } }); } // 초기 실행 setTimeout(updateConnectors, 100); // 윈도우 크기 변경 시 실행 window.addEventListener('resize', updateConnectors); // 설명 박스 마우스 오버 효과 const infoBoxes = document.querySelectorAll('.info-box'); infoBoxes.forEach(function (infoBox, index) { const pair = infoBox.closest('.highlight-pair'); const circle = pair.querySelector('.highlight-circle'); const connector = document.querySelectorAll('.connector-line')[index]; infoBox.addEventListener('mouseenter', function () { circle.classList.add('active-animation'); connector.classList.add('active-line'); }); infoBox.addEventListener('mouseleave', function () { circle.classList.remove('active-animation'); connector.classList.remove('active-line'); }); }); }); // init Isotope var initial_items = 24; var next_items = 24; var filterShowCount = {}; var currentFilter = $('.button-group-home .filter-button.is-checked').data('filter') || '.jeju-ranch'; filterShowCount[currentFilter] = initial_items; // Isotope 초기화 var $grid = $('.portfolio-grid').isotope({ itemSelector: '.element-item', layoutMode: 'masonry', stamp: '.element-item--static', filter: currentFilter, masonry: { columnWidth: '.element-item' } }); // 버튼 클릭 시 is-checked 관리 $('.button-group-home').each(function (i, buttonGroup) { var $buttonGroup = $(buttonGroup); $buttonGroup.on('click', 'button', function () { $buttonGroup.find('.is-checked').removeClass('is-checked'); $(this).addClass('is-checked'); }); }); // 카테고리(필터) 버튼 클릭 시 $('.button-group-home').on('click', 'button', function () { var filterValue = $(this).attr('data-filter'); currentFilter = filterValue; // 해당 필터의 더보기 개수, 없으면 기본값 var showCount = filterShowCount[filterValue] || initial_items; $grid.isotope({ filter: filterValue }); updateFilterCounts(showCount); }); // 더보기 버튼 클릭 시 $('#showMore').on('click', function (e) { e.preventDefault(); // 현재 필터에서 보여줘야 할 개수를 누적 증가 filterShowCount[currentFilter] = (filterShowCount[currentFilter] || initial_items) + next_items; updateFilterCounts(filterShowCount[currentFilter]); }); // 필터 적용/더보기 후 보여줄 아이템 관리 function updateFilterCounts(showCount) { // 현재 필터된 아이템 목록 var itemElems = $grid.isotope('getFilteredItemElements'); var count_items = $(itemElems).length; // 더보기 버튼 표시/숨김 if (count_items > showCount) { $('#showMore').show(); } else { $('#showMore').hide(); } // 모두 visible 해제 후 showCount만큼만 숨김 해제 $('.element-item').removeClass('visible_item'); var index = 0; $(itemElems).each(function () { if (index >= showCount) { $(this).addClass('visible_item'); // visible_item 클래스가 붙은 것은 숨김 } index++; }); $grid.isotope('layout'); } // 페이지 로드시, 처음 보여줄 개수만 남기고 나머지 숨김 function hideItems(showCount) { var itemElems = $grid.isotope('getFilteredItemElements'); var count_items = $(itemElems).length; $('.element-item').removeClass('visible_item'); var index = 0; $(itemElems).each(function () { if (index >= showCount) { $(this).addClass('visible_item'); } index++; }); // 더보기 버튼 표시/숨김 if (count_items > showCount) { $('#showMore').show(); } else { $('#showMore').hide(); } $grid.isotope('layout'); } // 최초 한 번 실행 (초기 카테고리 상태 반영) hideItems(initial_items); // 유튜브 링크가 있는 td.board_desc의 부모 tr에 클래스 추가 및 아이프레임 생성 (반응형 비율) $(document).ready(function() { console.log('YouTube script started'); // 디버깅용 // .wb_board.board-read td.board_desc 내의 유튜브 링크 확인 $('.wb_board.board-read td.board_desc').each(function() { var $td = $(this); var content = $td.html(); console.log('Checking content:', content); // 디버깅용 // 유튜브 링크 패턴들 var youtubePatterns = [ /https?:\/\/(?:www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)/, /https?:\/\/(?:www\.)?youtu\.be\/([a-zA-Z0-9_-]+)/, /https?:\/\/(?:www\.)?youtube\.com\/embed\/([a-zA-Z0-9_-]+)/, /youtube\.com\/watch\?v=([a-zA-Z0-9_-]+)/, /youtu\.be\/([a-zA-Z0-9_-]+)/ ]; var videoId = null; var hasYouTubeLink = false; // 각 패턴을 확인하여 유튜브 링크가 있는지 검사하고 비디오 ID 추출 for (var i = 0; i < youtubePatterns.length; i++) { var match = content.match(youtubePatterns[i]); console.log('Pattern', i, 'match result:', match); // 디버깅용 if (match && match[1]) { hasYouTubeLink = true; videoId = match[1]; console.log('Found YouTube video ID:', videoId); // 디버깅용 break; } } // 유튜브 링크가 있으면 처리 if (hasYouTubeLink && videoId) { console.log('Processing YouTube link for video:', videoId); // 디버깅용 // 부모 tr에 클래스 추가 $td.closest('tr').addClass('has-youtube-link'); // post_area 확인 및 처리 var $postArea = $('#post_area'); console.log('Post area found:', $postArea.length > 0); // 디버깅용 if ($postArea.length > 0) { // 기존 유튜브 컨테이너가 있는지 확인 var existingContainer = $postArea.find('.youtube-iframe-container'); if (existingContainer.length === 0) { console.log('Creating YouTube iframe'); // 디버깅용 // 반응형 유튜브 아이프레임 생성 (16:9 비율 유지) var iframeHtml = '
' + '' + '
'; // post_area의 맨 앞에 추가 $postArea.prepend(iframeHtml); console.log('YouTube iframe added to post_area'); // 디버깅용 } else { console.log('YouTube container already exists'); // 디버깅용 } } else { console.log('Post area not found'); // 디버깅용 } } else { console.log('No YouTube link found in this td'); // 디버깅용 } }); console.log('YouTube script completed'); // 디버깅용 });