PageSourceSearch

https://sabohani.com/yoshimunenchi/assets/js/common.js?ver=240129_3

js sabohani.com collected 2026-10-02 19:30:02 UTC 19,734 bytes, 658 lines download raw bytes

1//ScrollTrigger
2gsap.registerPlugin(ScrollTrigger);
3
4document.addEventListener('DOMContentLoaded', (event) => {
5    // ハンバーガーメニュー
6    var gnav = document.querySelector('#g-nav');
7    var sp_btn = document.querySelector('#sp-btn');
8    var nav_close_links = document.querySelectorAll('.nav-close');
9    var body = document.querySelector('body');
10
11    function change_sp_nav() {
12        if (sp_btn.classList.contains('active')) {
13            gnav.classList.remove('active');
14            sp_btn.classList.remove('active');
15        } else {
16            gnav.classList.add('active');
17            sp_btn.classList.add('active');
18        }
19        return false;
20    }
21
22    function change_sp_nav_close() {
23        if (sp_btn.classList.contains('active')) {
24            gnav.classList.remove('active');
25            sp_btn.classList.remove('active');
26        }
27        return false;
28    }
29
30    sp_btn.addEventListener('click', function (e) {
31        e.stopPropagation();
32        e.preventDefault();
33        change_sp_nav();
34    });
35
36    nav_close_links.forEach(function (nav_close) {
37        nav_close.addEventListener('click', function (e) {
38            e.stopPropagation();
39            change_sp_nav();
40        });
41    });
42
43    body.addEventListener('click', function (e) {
44        change_sp_nav_close();
45    });
46
47    //
48    // 導入パート
49    //
50
51    // gsapで#sp-btnを非表示にセット
52    gsap.set("#sp-btn, #js-header__logo", {
53        autoAlpha: 0,
54    });
55
56    var section1_swipe = gsap.fromTo("#js-section-1-swipe, #js-section-1-separator", {
57        duration: 0.5,
58        autoAlpha: 0,
59    }, {
60        duration: 0.5,
61        autoAlpha: 1,
62        delay: 8.5,
63    });
64
65    var sp_btn_display = gsap.fromTo("#sp-btn, #js-header__logo", {
66        duration: 0.5,
67        autoAlpha: 0,
68    }, {
69        duration: 0.5,
70        autoAlpha: 1,
71        delay: 8.5,
72    });
73
74
75    var section1_skip = gsap.fromTo("#js-video-skip", {
76        duration: 0.5,
77        autoAlpha: 1,
78    }, {
79        duration: 0.5,
80        autoAlpha: 0,
81        delay: 8,
82    });
83
84    const first_video = document.getElementById('js-video-1');
85
86    function videoPlay() {
87        // #js-video-1を最初から再生する
88        first_video.play();
89    }
90
91    videoPlay();
92    section1_swipe.play();
93    sp_btn_display.play();
94    section1_skip.play();
95
96    function skipFirstMovie() {
97        // js-video-1のビデオを終了位置で一時停止する
98        first_video.currentTime = 9;
99        first_video.pause();
100
101        // js-section-1-swipeのgsapを一時停止する
102        section1_swipe.pause();
103        sp_btn_display.pause();
104        section1_skip.pause();
105
106        // #sp-btnを表示する
107        gsap.to("#js-section-1-swipe, #sp-btn, #js-header__logo, #js-section-1-separator", {
108            autoAlpha: 1,
109        });
110
111        // #js-video-skipを非表示する
112        gsap.to("#js-video-skip", {
113            autoAlpha: 0,
114            duration: 0
115        });
116    }
117
118    //js-section-1をクリック、スワイプ、タップした場合
119    document.querySelector("#scrollableDiv1").addEventListener("touchend", skipFirstMovie);
120    document.querySelector("#scrollableDiv1").addEventListener("click", skipFirstMovie);
121    document.querySelector("#scrollableDiv1").addEventListener("touchmove", skipFirstMovie);
122    document.querySelector("#js-video-skip").addEventListener("click", skipFirstMovie);
123
124
125
126    //
127    //挨拶パート
128    //
129
130    //スクロール + フェードアップ要素
131    gsap.utils.toArray(".fadeup").forEach(target => {
132        gsap.from(target, {
133            scrollTrigger: {
134                // scroller: "#scrollContent",
135                trigger: target,
136                start: "top bottom-=200",
137                // markers: true,
138            },
139            opacity: 0,
140            y: 20,
141            duration: 0.75,
142        });
143    });
144
145    //スクロール + 左からフェードイン要素
146    gsap.utils.toArray(".fadeInLeft").forEach(target => {
147        gsap.from(target, {
148            scrollTrigger: {
149                // scroller: "#scrollContent",
150                trigger: target,
151                start: "top bottom-=200",
152                // markers: true,
153            },
154            opacity: 0,
155            x: -20,
156            duration: 0.75,
157        });
158    });
159
160    //左から回転しながらスライドイン
161    gsap.utils.toArray(".rotateLeft").forEach(target => {
162        gsap.from(target, {
163            scrollTrigger: {
164                // scroller: "#scrollContent",
165                trigger: target,
166                start: "top bottom-=200",
167                // markers: true,
168            },
169            opacity: 0,
170            rotate: -20,
171            duration: 0.75,
172        });
173    });
174
175    //右から回転しながらスライドイン
176    gsap.utils.toArray(".rotateRight").forEach(target => {
177        gsap.from(target, {
178            scrollTrigger: {
179                // scroller: "#scrollContent",
180                trigger: target,
181                start: "top bottom-=200",
182                // markers: true,
183            },
184            opacity: 0,
185            rotate: 20,
186            duration: 0.75,
187        });
188    });
189
190    //
191    //歴史パート
192    //
193    gsap.utils.toArray(".js-history-video").forEach(target => {
194        gsap.from(target, {
195            scrollTrigger: {
196                // scroller: "#scrollContent",
197                trigger: target,
198
199                start: 'top bottom', // ビューポートの上端が要素の下端に触れたとき
200                end: 'bottom top', // ビューポートの下端が要素の上端に触れたとき
201                onEnter: () => target.play(), // ビューポートに入ったときに再生
202                onLeave: () => target.pause(), // ビューポートから出たときに一時停止
203                onEnterBack: () => target.play(), // ビューポートに戻ったときに再生
204                onLeaveBack: () => target.pause(), // ビューポートから再び出たときに一時停止
205            },
206        });
207    });
208
209    //.radialを変数radialに代入
210    const radial = document.querySelector(".radial");
211
212    //gsapで.radialの初期状態をscale: 0にする
213    gsap.set(radial, {
214        scale: 0,
215    });
216
217    //放射素材の拡大縮小するタイムライン
218    const radialTl = gsap.timeline()
219        .from(radial, {
220            scale: 0,
221            opacity: 1,
222        })
223        .to(radial, {
224            scale: 8,
225            opacity: 1,
226            duration: 4,
227            ease: "power2.in",
228        }, ">")
229        .to(radial, {
230            scale: 8,
231            opacity: 0,
232            // duration: 1,
233        })
234
235
236    //.radial-triggerがビューポートの中央にきたらタイムラインradialTlを再生する
237    gsap.utils.toArray(".radial-trigger").forEach(target => {
238        ScrollTrigger.create({
239            // scroller: "#scrollContent",
240            trigger: target,
241            start: "top bottom-=30%",
242            end: "top top",
243            animation: radialTl,
244            scrub: true,
245
246        });
247    });
248
249    //gsapで.radial-childの初期状態をautoAlpha: 0にする
250    gsap.set(".radial-child:not(.radial-20)", {
251        display: 'none',
252    });
253
254
255    //年ごとの放射素材を表示する関数
256    function createScrollTriggerForYear(year) {
257        ScrollTrigger.create({
258            // scroller: "#scrollContent",
259            trigger: `#js-year-${year}`,
260            start: "top bottom",
261            onEnter: () => {
262                gsap.to(`.radial-child:not(.radial-${year})`, {
263                    display: 'none',
264                });
265                gsap.to(`.radial-${year}`, {
266                    display: 'block',
267                });
268            },
269            onLeave: () => {
270                gsap.to(`.radial-${year}`, {
271                    display: 'none',
272                });
273            },
274            onEnterBack: () => {
275                gsap.to(`.radial-child:not(.radial-${year})`, {
276                    display: 'none',
277                });
278                gsap.to(`.radial-${year}`, {
279                    display: 'block',
280                });
281            },
282            onLeaveBack: () => {
283                gsap.to(`.radial-${year}`, {
284                    display: 'none',
285                });
286            }
287        });
288    }
289
290    createScrollTriggerForYear('03');
291    createScrollTriggerForYear('08');
292    createScrollTriggerForYear('13');
293    createScrollTriggerForYear('20');
294
295
296    // ナビゲーションのボタンがクリックされたときに対応する.radial-クラスを表示する関数
297    function createClickEventForYear(year) {
298        document.querySelector(`#button-year-${year}`).addEventListener('click', () => {
299            gsap.to(`.radial-child:not(.radial-${year})`, {
300                display: 'none',
301            });
302            gsap.to(`.radial-${year}`, {
303                display: 'block',
304            });
305        });
306    }
307
308    createClickEventForYear('03');
309    createClickEventForYear('08');
310    createClickEventForYear('13');
311    createClickEventForYear('20');
312
313
314    //年号タイトルスライドイン
315    gsap.utils.toArray(".sec3_Year").forEach(target => {
316
317        let historyHeading = target.querySelector('.history__heading');
318
319        //historyHeadingの初期状態をx: 91%にする
320        gsap.set(historyHeading, {
321            x: "91%",
322        });
323
324        gsap.from(target, {
325            scrollTrigger: {
326                // scroller: "#scrollContent",
327                trigger: target,
328                start: "top center+=20%",
329                end: "bottom bottom",
330                // markers: true,
331                onEnter: () => {
332                    gsap.to(historyHeading, {
333                        x: 0,
334                        duration: 0.5,
335                    });
336                },
337                onLeaveBack: () => {
338                    gsap.to(historyHeading, {
339                        x: "91%",
340                        duration: 0.5,
341                    });
342                },
343                onLeave: () => {
344                    gsap.to(historyHeading, {
345                        x: "-91%",
346                        duration: 0.5,
347                    });
348                },
349                onEnterBack: () => {
350                    gsap.to(historyHeading, {
351                        x: 0,
352                        duration: 0.5,
353                    });
354                }
355            },
356        });
357    });
358
359    // 吉宗バイク
360    // .bikeWrapの初期状態をx:-100%にする
361    gsap.set(".bikeWrap", {
362        autoAlpha: 0,
363    });
364    gsap.set(".bike__video", {
365        x: "-100%",
366    });
367
368    // const bike_video = document.getElementById('js-bike-video');
369
370    // lottie
371    const bikeLottie = document.getElementById('bike__video__lottie');
372    const bikeLottieData = {
373        container: bikeLottie,
374        renderer: 'svg',
375        loop: true,
376        autoplay: false,
377        path: 'assets/js/lottie/data.json'
378    };
379    const bikeLottieAnim = lottie.loadAnimation(bikeLottieData);
380
381
382    //bikeTlEnterのタイムライン作成
383    const bikeTlEnter = gsap.timeline({
384        paused: true,
385        onComplete: () => {
386            // bike_video.loop = true;
387            bikeLottieAnim.play();
388        }
389    })
390        .fromTo(".bikeWrap",
391            {
392                autoAlpha: 0,
393            },
394            {
395                autoAlpha: 1,
396                duration: 0,
397            })
398        .fromTo(".bike__video",
399            {
400                x: "-100%",
401            },
402            {
403                x: 0,
404                duration: 0.5,
405            });
406
407    //bikeTlLeaveのタイムライン作成
408    const bikeTlLeave = gsap.timeline({
409        paused: true,
410        onComplete: () => {
411            bikeLottieAnim.pause();
412        }
413    })
414        .to(".bike__video",
415
416            {
417                x: "100%",
418                duration: 0.5,
419            })
420        .to(".bikeWrap",
421
422            {
423                autoAlpha: 0,
424                duration: 0,
425            });
426
427    //bikeLottieAnimを一時停止
428    function pauseVideoAtStart() {
429        bikeLottieAnim.pause();
430    }
431
432
433    // ".bike__video"にclass="is-leave"を付与する関数
434    function addIsLeaveAddClass() {
435        document.querySelector(".bike__video").classList.add("is-leave");
436    }
437
438    // ".bike__video"にclass="is-leave"を削除する関数
439    function removeIsLeaveRemoveClass() {
440        document.querySelector(".bike__video").classList.remove("is-leave");
441    }
442
443    gsap.timeline({
444        scrollTrigger: {
445            // scroller: "#scrollContent",
446            trigger: ".section-3",
447            start: "top top-=10%",
448            end: "bottom bottom",
449            // markers: true,
450
451            //挨拶から歴史に入ったとき //左から中央にバイクが入ってくる
452            onEnter: () => {
453                bikeTlEnter.restart();
454                removeIsLeaveRemoveClass();
455                // console.log('onEnter');
456            },
457            //トリビアから歴史に戻ったとき //左から中央にバイクが入ってくる
458            onEnterBack: () => {
459                bikeTlEnter.restart();
460                removeIsLeaveRemoveClass();
461                // console.log('onEnterBack');
462            },
463            //歴史からトリビアに出たとき //中央から右にバイクが出ていく
464            onLeave: () => {
465                pauseVideoAtStart();
466                bikeTlLeave.restart();
467                addIsLeaveAddClass();
468                // console.log('onLeave');
469            },
470            //歴史から挨拶に戻ったとき //中央から右にバイクが出ていく
471            onLeaveBack: () => {
472                pauseVideoAtStart();
473                bikeTlLeave.restart();
474                addIsLeaveAddClass();
475                // console.log('onLeaveBack');
476            },
477        }
478    });
479
480
481
482    //
483    // 家ついて行ってイイですか?パート
484    //
485
486    //dialog polyfill
487    document.querySelectorAll('dialog').forEach((dialog) => {
488        if (!dialog.showModal) {
489            dialogPolyfill.registerDialog(dialog);
490        }
491    });
492
493
494    //ポップアップ
495    const showButtons = document.querySelectorAll('.sec4_show-btn')
496    const closeButtons = document.querySelectorAll('.sec4_close-btn')
497
498    showButtons.forEach((button) => {
499        button.addEventListener('click', function () {
500            const dialog = this.parentElement.querySelector('dialog')
501            show(dialog)
502        })
503    })
504
505    closeButtons.forEach((button) => {
506        button.addEventListener('click', function () {
507            const dialog = this.closest('dialog')
508            close(dialog)
509        })
510    })
511
512    function show(dialog) {
513        dialog.classList.add('show-from')
514        dialog.showModal()
515
516        requestAnimationFrame(() => {
517            dialog.classList.remove('show-from')
518        })
519    }
520
521    function close(dialog) {
522        dialog.classList.add('hide-to')
523
524        dialog.addEventListener(
525            'transitionend',
526            () => {
527                dialog.classList.remove('hide-to')
528                dialog.close()
529            },
530            {
531                once: true,
532            },
533        )
534    }
535
536    document.querySelectorAll('dialog').forEach((dialog) => {
537        dialog.addEventListener('keydown', function (event) {
538            event.preventDefault()
539            if (event.key === 'Escape') {
540                close(this)
541            }
542        })
543
544        dialog.addEventListener('click', function (event) {
545            if (event.target === this) {
546                close(this)
547            }
548        })
549    })
550
551    //下部固定
552    // .sec4_fixの初期状態をx:-100%にする
553    gsap.set(".sec4_fix", {
554        x: "100%",
555    });
556
557    // .sec4_areaWrapがビューポートの中央にきたら下部固定を出現させる
558    const sec4FixTl = gsap.timeline({
559        scrollTrigger: {
560            // scroller: "#scrollContent",
561            trigger: ".sec4_areaWrap",
562            start: "top center",
563            end: "bottom bottom",
564
565            onEnter: () => sec4FixTl.play(),
566            onEnterBack: () => sec4FixTl.play(),
567            onLeave: () => sec4FixTl.reverse(),
568            onLeaveBack: () => sec4FixTl.reverse(),
569
570        },
571        // onComplete: () => {
572        //     bike_video.loop = true;
573        //     bike_video.play();
574        // }
575    });
576    sec4FixTl.fromTo(".sec4_fix",
577        {
578            x: "100%",
579            duration: 0.5,
580        },
581        {
582            x: 0,
583        })
584
585
586
587
588    //
589    //おみくじパート
590    //
591    // ボタンとビデオ、ダイアログ、おみくじ画像の要素を取得
592    const buttons = ['button_left', 'button_center', 'button_right'].map(id => document.getElementById(id));
593    const video = document.getElementById('js-video-5');
594    const dialog = document.querySelector('.sec5_dialog');
595    const lottery = document.getElementById('js-lottery');
596    const dialogImg = document.getElementById('js-dialogImg');
597    const closeButton = document.querySelector('.sec5_close-btn');
598
599    // ランダムなおみくじ画像を選択する関数
600    const lotteryImagesBase = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
601    function getRandomLotteryImage(baseName) {
602        const lotteryImages = lotteryImagesBase.map(letter => `assets/img/section-5/lottery/${letter}-${baseName}.png`);
603        return lotteryImages[Math.floor(Math.random() * lotteryImages.length)];
604    }
605
606    // GSAPを使用して.sec5_movieを初期状態で非表示に設定
607    gsap.set(video, { display: "none" });
608
609    // GSAPを使用して#js-lotteryの初期状態を設定
610    gsap.set(dialogImg, { opacity: 0, scale: 1.27 });
611
612    buttons.forEach((button, index) => {
613        button.addEventListener('click', () => {
614            video.querySelector('source').src = `assets/img/section-5/movie/${button.id.split('_')[1]}.mp4`;
615            lottery.src = getRandomLotteryImage(index + 1);
616            video.load();
617            video.onloadeddata = () => {
618                gsap.set(video, { display: "block" });
619                video.play();
620            };
621            video.onended = () => {
622                dialog.classList.add('show-from');
623                dialog.showModal();
624                requestAnimationFrame(() => {
625                    dialog.classList.remove('show-from');
626                    gsap.to(dialogImg, { opacity: 1, scale: 1, duration: 0.5 });
627                });
628                gsap.set(video, { display: "none" });
629            };
630        });
631    });
632
633    // 閉じるボタンとモーダルの背景のクリックイベントリスナーを設定
634    [closeButton, dialog].forEach(element => {
635        element.addEventListener('click', () => {
636            dialog.classList.add('hide-to');
637            dialog.addEventListener('transitionend', () => {
638                dialog.classList.remove('hide-to');
639                dialog.close();
640                gsap.set(dialogImg, { opacity: 0, scale: 1.27 });
641            }, { once: true });
642        });
643    });
644
645    // モーダルの背景のクリックイベントリスナーを設定
646    dialog.addEventListener('keydown', function (event) {
647        event.preventDefault()
648        if (event.key === 'Escape') {
649            dialog.classList.add('hide-to');
650            dialog.addEventListener('transitionend', () => {
651                dialog.classList.remove('hide-to');
652                dialog.close();
653                gsap.set(dialogImg, { opacity: 0, scale: 1.27 });  // #js-lotteryを初期状態に設定
654            }, { once: true });
655        }
656    })
657
658});

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.