export const common = { mnPopupSwiper: function (obj) { var init = function (obj) { var $el = $(obj).find('.swiper'); var $btnPrev = $(obj).find('.swiper-button-prev')[0]; var $btnNext = $(obj).find('.swiper-button-next')[0]; var $btnPlayStop = $(obj).find('.swiper-btn-playstop-toggle')[0]; var isPaused = false; // 재생 상태를 추적하는 변수 var slideCount = $el.find('.swiper-slide').length; // 슬라이드 개수 // 현재 브레이크포인트에서 slidesPerView 값 설정 var getSlidesPerView = function () { var width = window.innerWidth; if (width >= 1023) return 3; if (width >= 767) return 2; return 1; }; var slidesPerView = getSlidesPerView(); var enableAutoplay = slideCount > slidesPerView; var enableLoop = slideCount > slidesPerView; var enableCenteredSlides = slideCount < slidesPerView; var swiper = new Swiper($el[0], { preloadImages: true, spaceBetween: 16, centeredSlides: enableCenteredSlides, autoplay: enableAutoplay ? { delay: 4000, disableOnInteraction: false, } : false, loop: enableLoop, loopedSlides: 0, speed: 1000, initialSlide: 0, watchSlidesProgress: true, navigation: { prevEl: $btnPrev, nextEl: $btnNext }, breakpoints: { 480: { slidesPerView: 1, }, 767: { slidesPerView: 2, }, 1023: { slidesPerView: 3, }, }, }); // 중지 버튼 클릭 이벤트 $($btnPlayStop).on('click', function() { if (isPaused) { // 슬라이드 재생 swiper.autoplay.start(); $(this).removeClass('is-stop').text('중지'); // 버튼 텍스트 변경 isPaused = false; } else { // 슬라이드 정지 swiper.autoplay.stop(); $(this).addClass('is-stop').text('재생'); // 버튼 텍스트 변경 isPaused = true; } }); // 브라우저 리사이즈 시 slidesPerView 재확인 $(window).on('resize', function () { var newSlidesPerView = getSlidesPerView(); if (newSlidesPerView !== slidesPerView) { slidesPerView = newSlidesPerView; enableAutoplay = slideCount > slidesPerView; enableLoop = slideCount > slidesPerView; enableCenteredSlides = slideCount < slidesPerView; swiper.params.autoplay = enableAutoplay ? { delay: 3000, disableOnInteraction: false } : false; swiper.params.loop = enableLoop; swiper.params.enableCenteredSlides = enableCenteredSlides; swiper.update(); if (!enableAutoplay) swiper.autoplay.stop(); } }); }; init(this); return $(this); }, mnVisualSwiper: function (obj) { var init = function (obj) { var $el = $(obj).find('.swiper'); var $btnPrev = $(obj).find('.swiper-button-prev')[0]; var $btnNext = $(obj).find('.swiper-button-next')[0]; var $btnPlayStop = $(obj).find('.swiper-btn-playstop-toggle')[0]; var $progress = $(obj).find('.swiper-progress-bar')[0]; var isPaused = false; // 재생 상태를 추적하는 변수 var swiper = new Swiper($el[0], { effect:'fade', fadeEffect: { crossFade: true }, preloadImages: true, autoplay: { delay: 4000, disableOnInteraction: false, }, loop: true, loopedSlides: 0, speed: 1000, slidesPerView: 1, initialSlide: 0, watchSlidesProgress: true, navigation: { prevEl: $btnPrev, nextEl: $btnNext }, on: { slideChangeTransitionStart: function() { if (!isPaused) { $progress.style.transition = 'none'; $progress.style.width = '0%'; } }, slideChangeTransitionEnd: function() { if (!isPaused) { setTimeout(() => { $progress.style.transition = 'width 4s linear'; $progress.style.width = '100%'; }, 10); } } } }); // 중지 버튼 클릭 이벤트 $($btnPlayStop).on('click', function() { if (isPaused) { // 슬라이드 재생 swiper.autoplay.start(); $progress.style.transition = 'width 4s linear'; $progress.style.width = '100%'; $(this).removeClass('is-stop').text('중지'); // 버튼 텍스트 변경 isPaused = false; } else { // 슬라이드 정지 swiper.autoplay.stop(); $progress.style.transition = 'none'; $progress.style.width = '0%'; // 프로그레스 바를 0으로 설정 $(this).addClass('is-stop').text('재생'); // 버튼 텍스트 변경 isPaused = true; } }); } init(this); return $(this); }, mnNoticeSwiper: function () { var init = function (obj) { var $el = $(obj).find('.swiper'); var $btnPrev = $(obj).find('.swiper-button-prev')[0]; var $btnNext = $(obj).find('.swiper-button-next')[0]; var $btnPlayStop = $(obj).find('.swiper-btn-playstop-toggle')[0]; var $progress = $(obj).find('.swiper-progress-bar')[0]; var isPaused = false; // 재생 상태를 추적하는 변수 var swiper = new Swiper($el[0], { preloadImages: true, autoplay: { delay: 3000, disableOnInteraction: false, }, loop: true, loopedSlides: 0, speed: 1000, slidesPerView: 1, initialSlide: 0, watchSlidesProgress: true, navigation: { prevEl: $btnPrev, nextEl: $btnNext }, on: { slideChangeTransitionStart: function() { if (!isPaused) { $progress.style.transition = 'none'; $progress.style.width = '0%'; } }, slideChangeTransitionEnd: function() { if (!isPaused) { setTimeout(() => { $progress.style.transition = 'width 4s linear'; $progress.style.width = '100%'; }, 10); } } } }); // 중지 버튼 클릭 이벤트 $($btnPlayStop).on('click', function() { if (isPaused) { // 슬라이드 재생 swiper.autoplay.start(); $progress.style.transition = 'width 4s linear'; $progress.style.width = '100%'; $(this).removeClass('is-stop').text('중지'); // 버튼 텍스트 변경 isPaused = false; } else { // 슬라이드 정지 swiper.autoplay.stop(); $progress.style.transition = 'none'; $progress.style.width = '0%'; // 프로그레스 바를 0으로 설정 $(this).addClass('is-stop').text('재생'); // 버튼 텍스트 변경 isPaused = true; } }); } init(this); return $(this); }, // mnQuickSwiper: function () { // var init = function (obj) { // var $el = $(obj).find('.swiper'); // var $btnPrev = $(obj).find('.swiper-button-prev')[0]; // var $btnNext = $(obj).find('.swiper-button-next')[0]; // var swiper = new Swiper($el[0], { // preloadImages: true, // slidesPerView: 2.2, // loop: false, // loopedSlides: 0, // speed: 500, // initialSlide: 0, // watchSlidesProgress: true, // navigation: { // prevEl: $btnPrev, // nextEl: $btnNext // }, // breakpoints: { // 480: { slidesPerView: 3.2 }, // 767: { slidesPerView: 6.2 }, // 1023: { slidesPerView: 8 }, // } // }); // } // init(this); // return $(this); // }, mnQuickAsideSwiper: function () { var init = function (obj) { var $el = $(obj).find('.swiper'); var $btnPrev = $(obj).find('.swiper-button-prev')[0]; var $btnNext = $(obj).find('.swiper-button-next')[0]; var swiper = new Swiper($el[0], { preloadImages: true, slidesPerView: 1, // 한 번에 표시할 슬라이드 개수 loop: true, loopedSlides: 0, speed: 500, initialSlide: 0, watchSlidesProgress: true, navigation: { prevEl: $btnPrev, nextEl: $btnNext }, }); } init(this); return $(this); }, }; $.extend($.fn, common); // window.mnQuickSwiper = function (selector) { // var $el = $(selector).find('.swiper'); // var $btnPrev = $(selector).find('.swiper-button-prev')[0]; // var $btnNext = $(selector).find('.swiper-button-next')[0]; // return new Swiper($el[0], { // preloadImages: true, // slidesPerView: 2.2, // loop: false, // loopedSlides: 0, // speed: 500, // initialSlide: 0, // watchSlidesProgress: true, // navigation: { // prevEl: $btnPrev, // nextEl: $btnNext // }, // breakpoints: { // 480: { slidesPerView: 3.2 }, // 767: { slidesPerView: 6.2 }, // 1023: { slidesPerView: 8 }, // } // }); // }; window.mnQuickSwiper = function (selector) { var $el = $(selector).find('.swiper'); var $btnPrev = $(selector).find('.swiper-button-prev')[0]; var $btnNext = $(selector).find('.swiper-button-next')[0]; var swiperInstance = new Swiper($el[0], { preloadImages: true, slidesPerView: 2.2, loop: false, loopedSlides: 0, speed: 500, initialSlide: 0, watchSlidesProgress: true, navigation: { prevEl: $btnPrev, nextEl: $btnNext }, breakpoints: { 480: { slidesPerView: 3.2 }, 767: { slidesPerView: 6.2 }, 1023: { slidesPerView: 8 }, } }); // Swiper 인스턴스를 해당 요소에 저장 $(selector).data('swiper', swiperInstance); return swiperInstance; }; //헤더 체크 const checkIsSticky = () => { const header = document.querySelector('.site-header'); if (!header) return; if (window.scrollY > 10) { header.classList.add('is-sticky'); } else { header.classList.remove('is-sticky'); } } // 메인 독서통계 const mnBookLegendPlugin = { id: 'mnBookLegendPlugin', afterDraw: (chart) => { const { ctx } = chart; const datasets = chart.data.datasets; datasets.forEach((dataset, index) => { const meta = chart.getDatasetMeta(index); const lastPoint = meta.data[meta.data.length - 1]; if (lastPoint) { const label = dataset.label; const fontSize = 10; const paddingTop = 4; const paddingBottom = 4; const paddingLeft = 8; const paddingRight = 8; // 텍스트 측정 ctx.font = `${fontSize}px Pretendard`; const textWidth = ctx.measureText(label).width; const textHeight = fontSize; // 범례 박스의 너비와 높이 계산 const boxWidth = textWidth + paddingLeft + paddingRight; const boxHeight = textHeight + paddingTop + paddingBottom; // 범례 박스 위치 지정 let x = lastPoint.x - boxWidth / 2; // 중앙 정렬 let y = lastPoint.y - boxHeight / 2; // 차트의 경계와 비교하여 범례 박스 위치 조정 if (x < 0) { x = 0; } if (y < 0) { y = 0; } if (x + boxWidth > chart.width) { x = chart.width - boxWidth; } if (y + boxHeight > chart.height) { y = chart.height - boxHeight; } // 배경 사각형 그리기 ctx.save(); ctx.fillStyle = dataset.borderColor; ctx.beginPath(); ctx.roundRect(x, y, boxWidth, boxHeight, textHeight); ctx.fill(); ctx.restore(); // 텍스트 그리기 ctx.save(); ctx.font = `${fontSize}px Pretendard`; ctx.fillStyle = '#FFF'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(label, x + boxWidth / 2, y + boxHeight / 2); ctx.restore(); } }); } }; const mnBookDatasetConfig = { fill: false, pointRadius: 0, borderWidth: 1.6, tension: 0.4 }; const createMnBookChart = ({ id, labels, datasets }) => { const ctx = document.getElementById(id).getContext('2d'); // 데이터셋에 공통 설정과 색상 추가 const datasetWithConfig = datasets.map((dataset, index) => { const colors = ['#358AEB', '#004BA0']; // 색상 배열 return { ...mnBookDatasetConfig, ...dataset, // 전달된 데이터셋 설정을 오버라이드 borderColor: colors[index % colors.length] // 데이터셋 순서에 따른 색상 지정 }; }); const config = { type: 'line', data: { labels, datasets: datasetWithConfig }, options: { animation: false, responsive: true, maintainAspectRatio: false, scales: { y: { ticks: { stepSize: 5, maxTicksLimit: 5, color: '#999', font: { family: 'Pretendard', size: 10, style: 'normal', weight: '400', lineHeight: 1, }, textAlign: 'center' }, grid: { color: '#EFEFEF', borderColor: 'transparent', borderWidth: 0 } }, x: { ticks: { color: '#999', font: { family: 'Pretendard', size: 10, style: 'normal', weight: '400', lineHeight: 1, }, textAlign: 'center' }, grid: { display: false } } }, plugins: { legend: { display: false } } }, plugins: [mnBookLegendPlugin] }; return new Chart(ctx, config); }; window.createMnBookChart = createMnBookChart; export const initCusCommon= () => { $(document).ready(function () { $('.mn-popup-area').mnPopupSwiper(); $('.mn-notice').mnNoticeSwiper(); $('aside.mn-quick').mnQuickAsideSwiper(); checkIsSticky(); window.onscroll = () => { checkIsSticky(); } //테마 타입 추가 //$("html").attr("data-theme-color", "spring"); }); $(window).on('load', function () { //swiper //$('.mn-visual').mnVisualSwiper(); //window.mnQuickSwiper('section.mn-quick'); }); };