/* ---------- 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'); // 디버깅용
});