PageSourceSearch

https://commono.co.jp/wp2025/wp-content/themes/corpolate2025/js/navigation.js?ver=1788934948

js commono.co.jp collected 2026-09-29 18:29:03 UTC 18,487 bytes, 568 lines download raw bytes

1import { PointGradient } from './point-gradient.js';
2
3const nav_functions = {};
4nav_functions.onLoad = function(){
5  nav_functions.initHeader();
6  nav_functions.initMenuModal();
7  nav_functions.initNavIcons();
8}
9
10document.addEventListener('pageStart',()=>{
11  // console.log('pageStart');
12  requestAnimationFrame(() => {
13    requestAnimationFrame(() => {
14      initTooltip();
15    });
16  });
17})
18
19initTooltipLoad();
20function initTooltipLoad(){
21  // console.log('initTooltipLoad');
22  //通常遷移時用のロード
23  const intro = document.getElementById('intro');
24  if(intro) return;
25  document.dispatchEvent(new CustomEvent('pageStart'));
26}
27
28nav_functions.initHeader = function() {
29  const CLOSE_CLASS = "scroll-down";
30  const ACTIVE_CLASS = "is-active";
31  const header_nav = document.querySelector("#headMenu");
32  const bottom_nav = document.querySelector("#bottomMenu");
33  const root = document.querySelector(':root');
34  const header_zone_height = 80;
35  if(!header_nav){
36    // ヘッダーがない場合は処理しない
37    return false;
38  }
39  // const scrolling_elem = document.scrollingElement;
40  let st_cache = null;
41  function checkScroll() {
42    const st = lenis.scroll;
43    // const st = scrolling_elem.scrollTop;
44    if (st_cache != null && st > st_cache && st > header_zone_height) {
45      header_nav.classList.add(CLOSE_CLASS);
46      root.classList.add(CLOSE_CLASS);
47    } else {
48      header_nav.classList.remove(CLOSE_CLASS);
49      root.classList.remove(CLOSE_CLASS);
50    }
51
52    // bottom nav
53    // if (bottom_nav) {
54      // if ( st > header_zone_height) {
55      //   bottom_nav.classList.add(ACTIVE_CLASS);
56      // }else{
57      //   bottom_nav.classList.remove(ACTIVE_CLASS);
58      // }
59    // }
60    st_cache = st;
61  }
62  
63  document.removeEventListener("scroll", checkScroll);
64  document.addEventListener("scroll", checkScroll);
65  checkScroll();
66
67}
68
69nav_functions.initMenuModal = function(){
70
71  const header = document.querySelector('header#head');
72  const swiperDelay = 5000;
73  const intervalDelay = swiperDelay / 100;
74  const storyParentSlider = document.querySelector('.storyParentSlider');
75  const storyParentSlides = document.querySelectorAll('.storyParentSlider__slide');
76  const sliderInstances = {};
77  let parentSwiperChanging = false;
78
79  if( ! header || header.classList.contains('is-menuModal-initialized')) return;
80  header.classList.add('is-menuModal-initialized');
81  // console.log('menuModal init');
82
83  if( ! storyParentSlides || storyParentSlides.length === 0 ) return;
84  
85  // slider内のvideoを全て停止し、次に表示するslideに動画があれば再生する
86  function stopAllVideosAndPlayNextVideo(slider){
87    slider.slides.forEach(slide => {
88      const slideVideos = slide.querySelectorAll('video');
89      slideVideos.forEach(video => {
90        if(video.tagName === 'VIDEO'){
91          video.pause();
92          video.currentTime = 0;
93        }
94      });
95    });
96    // 次のスライドに動画があれば再生する
97    if( slider.slides[slider.activeIndex] == null ) return;
98    const nextVideos = slider.slides[slider.activeIndex].querySelectorAll('video');
99    if(nextVideos.length > 0){
100      nextVideos.forEach(video => {
101        video.play();
102      });
103    }
104  }
105
106  //次のスライダーが途中から始まるのを防止
107  function setChildTouchEnabled(enabled){
108    storyParentSlides.forEach((modal)=>{
109      const name = modal.dataset.pagename;
110      const slider = getSliderInstance(name);
111      if(slider){
112        slider.allowTouchMove = enabled;
113      }
114    });
115  }
116
117  //storyParentSliderを初期化
118  if( ! storyParentSlider.classList.contains('swiper-initialized') ){
119    const storyParentSliderInstance = new Swiper(storyParentSlider, {
120      direction: "horizontal",
121      // loop: true,
122      slidesPerView: 1,
123      speed: 500,
124      rewind: true,
125      // watchSlidesProgress: true,
126      init: true,
127      autoplay: false,
128      allowTouchMove: false,
129      on: {
130        slideChangeTransitionStart: function (swiper) {
131          parentSwiperChanging = true;
132          setChildTouchEnabled(false);
133          pauseAllChildSliders();
134
135          //親が切り替わる瞬間に、次に表示される子を先に0へ(即時)
136          const activeSlide = storyParentSlider.querySelector('.storyParentSlider__slide.swiper-slide-active');
137          const name = activeSlide?.dataset?.pagename;
138          const child = name ? getSliderInstance(name) : null;
139          if (child) child.slideTo(0, 0);
140        },
141        slideChangeTransitionEnd: function (swiper) {
142          parentSwiperChanging = false;
143          setChildTouchEnabled(true);
144          resumeChildSliders();
145        },
146      }
147    });
148  }
149
150  //全てのスライダーを用意→初期化/再生停止→マップ追加しておく
151  storyParentSlides.forEach((modal,index)=>{
152    const pageName = modal.dataset.pagename;
153    const sliderElem = modal.querySelector('.swiper.storySlide');
154    const fills = modal.querySelectorAll('.storySlide__progress__fill');
155    const this_modal = modal;
156
157    if(! sliderElem.classList.contains('swiper-initialized') ){
158
159      const slider = new Swiper(sliderElem, {
160        direction: "horizontal",
161        loop: false,
162        // loop: true,
163        slidesPerView: 1,
164        speed: 500,
165        watchSlidesProgress: true,
166        init: true, //自動初期化のoff
167        autoplay: false,
168        nested: true,
169        watchSlidesProgress: true,
170        
171        // 端での抵抗値を設定
172        resistance: true,
173        resistanceRatio: 0.2,
174        
175        // タッチ感度の調整
176        threshold: 10,
177        on: {
178          progress: function (swiper, progress) {
179            if( parentSwiperChanging ) return;
180            // console.log('toEdge', swiper);
181            if(swiper.slides.length > 1){
182              if(swiper.isBeginning && progress < 0){
183                storyParentSlider.swiper.slidePrev();
184              }else if(swiper.isEnd && progress > 1){
185                storyParentSlider.swiper.slideNext();
186              }
187            }else{
188              const direction = swiper.touches.currentX - swiper.touches.previousX > 0 ? 'prev': 'next';
189              console.log(direction, swiper.touches.currentX - swiper.touches.previousX, 'Reached the edge of the slider');
190              if(direction === 'prev'){
191                storyParentSlider.swiper.slidePrev();
192              }else if(direction === 'next'){
193                storyParentSlider.swiper.slideNext();
194              }
195            }
196          }
197        }
198      });
199    
200      // slider.init();
201  
202      //マップにセット
203      sliderInstances[pageName] = slider;
204      // sliderInstance.set(pageName,slider);
205      
206      //スライドが変わった時のリセット処理
207      slider.on('activeIndexChange',(e)=>{
208        // console.log(index,' - activeIndexChange:',e.activeIndex);
209        
210        if( modal.__slide_timer != null ){
211          clearTimeout(modal.__slide_timer);
212        }
213        // fills.forEach(fill => fill.style.width = '0');
214        modal.currentIdx = e.realIndex;
215        modal.progress = 0;
216        if( this_modal.classList.contains('swiper-slide-active') ){
217          if( slider.slides.length > 1 ){
218            barAnim(pageName);
219          }
220        }
221      });
222      slider.on('slideChange',(e)=>{
223        // スライドが変わったら動画を停止して、次の動画を再生する
224        stopAllVideosAndPlayNextVideo(slider);
225      });
226    }
227  });
228
229  function pauseAllChildSliders(){
230    storyParentSlides.forEach((modal)=>{
231      const name  = modal.dataset.pagename;
232      const slider = getSliderInstance(name);
233      if( slider && slider.autoplay.running ){
234        slider.autoplay.stop();
235      }
236      pauseAnim(name);
237    });
238  };
239
240  function resumeChildSliders(){
241    const activeSlide = storyParentSlider.querySelector('.storyParentSlider__slide.swiper-slide-active');
242    const name = activeSlide.dataset.pagename;
243    const slider = getSliderInstance(name);
244    if( slider && ! slider.autoplay.running ){
245      // slider.autoplay.start();
246      playAnim(name);
247      console.log(`Resuming child slider for ${name}`);
248    }
249  };  
250  
251  //呼び出し関数
252  function getSliderInstance(pageName){
253    // console.log(pageName, sliderInstances);
254    return sliderInstances[pageName];
255  }
256
257  function getStorySlide(name) {
258    return document.querySelector(`.storyParentSlider__slide[data-pagename="${name}"]`);
259  }
260
261  function getStorySlideIndexByName(name) {
262    const storySlides = Array.from(storyParentSlides);
263    return storySlides.findIndex(slide => slide.dataset.pagename === name);
264  }
265
266  //アニメーション
267  function pauseAnim(name){
268    const _parent = getStorySlide(name);
269    _parent.isPaused = true;
270    if( ! _parent ) return;
271    if( _parent.__slide_timer != null ){
272      clearTimeout(_parent.__slide_timer);
273    }
274  }
275
276  function playAnim(name){
277    getStorySlide(name).isPaused = false;
278    const sliderElem = getStorySlide(name).querySelector('.storySlide');
279    if(sliderElem.swiper != null && sliderElem.swiper.slides.length > 1){
280      barAnim(name);
281    }
282  }
283
284  function resetAnim(name){
285    const _parent = getStorySlide(name);
286    if( ! _parent ) return;
287    // console.log('resetAnim',name,_parent.currentIdx,_parent.progress,_parent.isPaused);
288    if( _parent.__slide_timer != null ){
289      clearTimeout(_parent.__slide_timer);
290    }
291    _parent.currentIdx = null;
292    _parent.progress = null;
293    _parent.isPaused = false;
294    const fills = _parent.querySelectorAll('.storySlide__progress__fill');
295    fills.forEach(fill => fill.style.width = '0');
296    if( getSliderInstance(name) ){
297      getSliderInstance(name).slideTo(0,0);
298    }
299  }
300    
301  function barAnim(name){
302
303    const _parent = getStorySlide(name);
304    if( ! _parent ) return;
305  
306    const fills = _parent.querySelectorAll('.storySlide__progress__fill');
307
308    if( _parent.__slide_timer != null ){
309      clearTimeout(_parent.__slide_timer);
310    }
311    
312    // 初期化
313    if( _parent.currentIdx == null ){
314      _parent.currentIdx = 0;
315    }
316    if( _parent.progress == null ){
317      _parent.progress = 0;
318    }
319
320    function progressBar(){
321      // console.log('progressBar',_parent.currentIdx,_parent.progress, _parent.isPaused);      
322      if(_parent.isPaused) return;
323      if( _parent.classList.contains('swiper-slide-active') === false ){
324        _parent.isPaused = true;
325        clearTimeout(_parent.__slide_timer);
326        return;
327      };
328      _parent.progress ++;
329
330      fills.forEach((fill, i) => {
331        if (i < _parent.currentIdx) {
332          fill.style.width = '100%';
333        } else if (i === _parent.currentIdx) {
334          fill.style.width = `${Math.min(100, _parent.progress)}%`;
335        } else {
336          fill.style.width = '0%';
337        }
338      });
339
340      if( fills[_parent.currentIdx] != null){
341        fills[_parent.currentIdx].style.width = `${Math.min(100,_parent.progress)}%`;
342      }
343      if(_parent.progress >= 100){
344        clearTimeout(_parent.__slide_timer);
345        const slider = getSliderInstance(name);
346        if (fills[_parent.currentIdx]) fills[_parent.currentIdx].style.width = '100%';
347        if( slider.activeIndex + 1 < slider.slides.length ){
348          const nextPage = slider.activeIndex + 1;
349          slider.slideTo(nextPage);
350        }else{
351          storyParentSlider.swiper.slideNext();
352        }
353      }else{
354        _parent.__slide_timer = setTimeout(progressBar,intervalDelay);
355      }
356    }
357    _parent.__slide_timer = setTimeout(progressBar,intervalDelay);
358  }
359
360  //操作
361  function togglePlayback(){
362
363    storyParentSlides.forEach((modal,idx)=>{
364      const name  = modal.dataset.pagename;
365      const pauseArea = getStorySlide(name);
366
367      //prev用に前のslideを取得
368      let prevName;
369      let prevSlideLength;
370      if(storyParentSlides[idx-1]){
371        prevName = storyParentSlides[idx-1].dataset.pagename;
372        prevSlideLength =  getSliderInstance(prevName).slides.length;
373      }
374      else{
375        //0(works)なら最後の親スライド番号を取得
376        prevName = storyParentSlides[storyParentSlides.length-1].dataset.pagename;
377        prevSlideLength =  getSliderInstance(prevName).slides.length;
378      }
379
380      // console.log('togglePlayback',name,pauseArea);
381      function pauseOnStop(e){
382        e.stopPropagation();
383        // console.log('pauseOnStop',name,e.currentTarget);
384        pauseAnim(name);
385      }
386      function resumeOnRelease(e){
387        e.stopPropagation();
388        // console.log('resumeOnRelease',name,e.currentTarget);
389        playAnim(name);
390      }
391      function goToPrev(e){
392        e.stopPropagation();
393        // console.log('goToPrev',name,e.currentTarget);
394        if(getSliderInstance(name).activeIndex !== 0){
395          const prevPage = getSliderInstance(name).activeIndex -1 >= 0 ? getSliderInstance(name).activeIndex -1 : getSliderInstance(name).slides.length -1;
396          getSliderInstance(name).slideTo(prevPage);
397        }else{
398          //親スライドを切り替え
399          storyParentSlider.swiper.slidePrev();
400          //子スライドを最後にしておく
401          getSliderInstance(prevName).slideTo(prevSlideLength-1);
402        }
403      }
404      function goToNext(e){
405        e.stopPropagation();
406        // console.log('goToNext',name,e.currentTarget);
407        if( getSliderInstance(name).activeIndex + 1 < getSliderInstance(name).slides.length  ){
408          const nextPage = getSliderInstance(name).activeIndex + 1 < getSliderInstance(name).slides.length ? getSliderInstance(name).activeIndex + 1 : 0;
409          getSliderInstance(name).slideTo(nextPage);
410        }else{
411          storyParentSlider.swiper.slideNext();
412        }
413      }
414
415
416      const slideItem = modal.querySelectorAll('.storySlide__item')
417      slideItem.forEach((slide)=>{
418        slide.addEventListener("click", (e) => {
419          const rect = slide.getBoundingClientRect();
420          const clickX = e.clientX - rect.left;   // 要素内のクリック位置
421          const half = rect.width / 2;
422
423          if (clickX > half) {
424            goToNext(e);
425          } else {
426            goToPrev(e);
427          }
428        });
429      })
430      
431    })
432  }
433
434  function initClose(){
435    storyParentSlides.forEach((storyParentSlide)=>{
436      const btn = storyParentSlide.querySelector('.storySlide__close');
437      const links = storyParentSlide.querySelectorAll('a');
438      if( btn == null || btn.classList.contains('is-initialized')) return;
439      const name  = storyParentSlide.dataset.pagename;
440      function close(){
441        storyParentSlider.classList.remove('is-active');
442        // pauseAnim(name);
443        resetAnim(name);
444      };
445      btn.removeEventListener('click',close);
446      btn.addEventListener('click',close);
447      btn.classList.add('is-initialized');
448
449      links.forEach((link)=>{
450        link.removeEventListener('click',close);
451        link.addEventListener('click',close);
452      });
453
454      document.removeEventListener('swup:visit:start', close);
455      document.addEventListener('swup:visit:start', close);
456    });
457  }
458
459  function setIconImages(){
460    storyParentSlides.forEach((storyParentSlide)=>{
461      const name  = storyParentSlide.dataset.pagename;
462      const btn = document.querySelector(`.menuModalBtn[data-pagename="${name}"]`);
463      const icon = btn.querySelector('.head__menuGradientIcon');
464      if( icon && icon.gradientIcon != null ){
465        let icon_src = icon.gradientIcon.captureImage();
466        if( icon_src ){
467          storyParentSlide.querySelector('.storySlide__head .img img').src = icon_src;
468          // キャッシュ解放
469          icon_src = null;
470        }
471      }
472    });
473  }
474
475  function initOpen(){
476    storyParentSlides.forEach((storyParentSlide)=>{
477      const name  = storyParentSlide.dataset.pagename;
478      const btn = document.querySelector(`.menuModalBtn[data-pagename="${name}"]`);
479      const index = getStorySlideIndexByName(name);
480      if( btn == null || btn.classList.contains('is-initialized')) return;
481
482      function open(){
483        // console.log('open',name);
484        if( storyParentSlider.swiper == null ) return;
485        storyParentSlider.swiper.slideTo(index,0.01);
486        storyParentSlider.classList.add('is-active');
487        resetAnim(name);
488        // playAnim(name);
489
490        // 物理演算メニューの描画開始
491        const event = new CustomEvent('menu_opened');
492        window.dispatchEvent(event);
493
494        // モーダルのアイコンをcanvasから画像に変換
495        setIconImages();
496      }
497
498      btn.removeEventListener('click',open);
499      btn.addEventListener('click',open);
500      btn.classList.add('is-initialized')
501    })
502  }
503
504  initOpen();
505  initClose();
506  togglePlayback();
507}
508
509nav_functions.initNavIcons = function(){
510  // console.log('initNavIcons');
511  
512  const icon_containers = document.querySelectorAll('.head__menuGradientIcon');
513  if( ! icon_containers || icon_containers.length === 0 ) return;
514  icon_containers.forEach(container => {
515    if(! container.querySelector('canvas') ){
516      const colors = container.dataset.iconColors ? container.dataset.iconColors.trim().replace(/\s/g,"").split(',') : ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff'];
517      const weights = container.dataset.iconWeights ? container.dataset.iconWeights.trim().split(',') : [0.5, 0.5, 0.5, 0.5, 0.5];
518      const bgColor = container.dataset.iconBgcolor ? container.dataset.iconBgcolor.trim() : '#ffffff';
519      const options = {
520        pointCount: colors.length,
521        colorWeights: weights,
522        colors: colors,
523        baseColor: bgColor,
524      };
525      container.gradientIcon = new PointGradient(container, options);
526      // pointGradient.init();
527      requestAnimationFrame(() => {
528        const fallback_src = container.gradientIcon.captureImage();
529        if(fallback_src){
530          container.style.backgroundImage = `url(${fallback_src})`;
531        }
532        container.gradientIcon.resume();
533      });
534    }
535  });
536};
537
538
539function initTooltip(){
540
541  const openNav = gsap.utils.toArray('.chatOpen__nav');
542
543  // console.log(openNav);
544  
545  if(!openNav) return;
546
547  gsap.set(openNav, { autoAlpha: 0, y: '1rem' });
548
549  gsap.to(openNav, {
550    duration: 0.3,
551    stagger: 0.1,
552    autoAlpha: 1,
553    y: 0,
554    delay: 0.75,
555    onComplete: () => {
556      gsap.to(openNav, {
557        duration: 0.3,
558        stagger: 0.1,
559        autoAlpha: 0,
560        y: '1rem',
561        delay: 1.5,
562      });
563    }
564  })
565
566};
567
568nav_functions.onLoad();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.