PageSourceSearch

https://mahouka.jp/3rd/assets/js/3rd.base.js

js mahouka.jp collected 2026-10-02 03:38:01 UTC 15,429 bytes, 553 lines download raw bytes

1'use strict';
2const $html = $('html');
3const $body = $('body');
4const $header = $('header');
5const $footer = $('footer');
6const $main = $('main');
7
8let svh = window.innerHeight;
9let lvh = window.outerHeight;
10let vw = window.innerWidth;
11
12const documentRoot = document.documentElement;
13
14const mq = {
15  hov: () => {
16    return matchMedia('(hover: hover) and (pointer: fine)').matches;
17  },
18  land: () => {
19    return matchMedia('(orientation: landscape)').matches;
20  },
21  pc: function () {
22    let breakpoint = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 960;
23    return matchMedia('(min-width:'.concat(breakpoint, 'px)')).matches;
24  },
25};
26const zeroPadding = function (num) {
27  let length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
28  return String(num).padStart(length, '0');
29};
30const getParameterByName = function (name) {
31  let url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : location.href;
32  name = name.replace(/[\[\]]/g, '\\$&');
33  let regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
34    results = regex.exec(url);
35  if (!results) {
36    return null;
37  }
38  if (!results[2]) {
39    return '';
40  }
41  return decodeURIComponent(results[2].replace(/\+/g, ' '));
42};
43const userAgent = {
44  setup() {
45    var _navigator;
46    const ua = (_navigator = navigator) === null || _navigator === void 0 || (_navigator = _navigator.userAgent) === null || _navigator === void 0 ? void 0 : _navigator.toLowerCase();
47    if (ua.indexOf('iphone') > 0 || (ua.indexOf('android') > 0 && ua.indexOf('mobile') > 0)) {
48      this.ua = 'sp';
49      if (ua.indexOf('iphone') > 0) {
50        this.os = 'iOS';
51      }
52      if (ua.indexOf('android') > 0) {
53        this.os = 'android';
54      }
55    } else if (ua.indexOf('ipad') > 0 || ua.indexOf('android') > 0) {
56      this.ua = 'sp';
57      if (ua.indexOf('ipad') > 0) {
58        this.os = 'iOS';
59      }
60      if (ua.indexOf('android') > 0) {
61        this.os = 'android';
62      }
63    } else {
64      this.ua = 'pc';
65      this.os = 'pc';
66    }
67    if (ua.indexOf('windows nt') !== -1) {
68      this.os = 'win';
69    } else if (this.ua === 'pc' && ua.indexOf('mac os x') !== -1) {
70      this.os = 'mac';
71    }
72
73    if (ua.indexOf('msie') !== -1 || ua.indexOf('trident') !== -1) {
74      this.browser = 'ie';
75    } else if (ua.indexOf('edge') !== -1) {
76      this.browser = 'html_edge';
77    } else if (ua.indexOf('edg') !== -1) {
78      this.browser = 'edge';
79    } else if (ua.indexOf('chrome') !== -1) {
80      this.browser = 'chrome';
81    } else if (ua.indexOf('safari') !== -1) {
82      this.browser = 'safari';
83    } else if (ua.indexOf('firefox') !== -1) {
84      this.browser = 'firefox';
85    } else {
86      this.browser = 'other';
87    }
88  },
89};
90userAgent.setup();
91function setHeight() {
92  let forced = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
93  if (forced || userAgent.ua === 'pc' || vw !== window.innerWidth) {
94    svh = window.innerHeight;
95  }
96  vw = window.innerWidth;
97  lvh = window.outerHeight;
98  documentRoot.style.setProperty('--svh', ''.concat(svh, 'px'));
99  if ($footer) {
100    const footerH = $footer.innerHeight();
101    documentRoot.style.setProperty('--footerH', ''.concat(footerH, 'px'));
102  }
103}
104setHeight();
105
106$(document).ready(() => {
107  $body.addClass('is-ready');
108});
109
110$(window)
111  .on('load', () => {
112    $body.addClass('is-load');
113    setHeight();
114
115    Drawer.init();
116    BGParticle.init();
117  })
118  .on('resize', () => {
119    setHeight();
120  })
121  .on('orientationchange', () => {
122    setHeight(true);
123  });
124
125const Menu = {
126  config: {
127    wrap: '.js-wrap',
128    btn: '.js-menu',
129    area: 'js-menu-area',
130    open: '.js-menu-open',
131    close: '.js-menu-close',
132  },
133  param: {
134    timer: 400,
135    duration: 850,
136  },
137  state: {
138    isDone: true,
139    open: false,
140  },
141  timer: undefined,
142  toggle() {
143    if (!this.state.open) {
144      this.open();
145    } else {
146      this.close();
147    }
148  },
149  open() {
150    if (!this.state.open) {
151      clearTimeout(this.timer);
152      this.state.open = true;
153      $body.addClass('is-menu-show');
154      setTimeout(() => {
155        $body.addClass('is-menu-open');
156      }, 10);
157    }
158  },
159  close() {
160    this.state.open = false;
161    $body.removeClass('is-menu-open');
162    this.timer = setTimeout(() => {
163      $body.removeClass('is-menu-show');
164    }, this.param.duration);
165  },
166  click() {
167    $body.on('click', '.js-menu', (e) => {
168      this.toggle();
169    });
170    $body.on('click keydown', '.js-menu-open', (e) => {
171      this.open();
172    });
173    $body.on('click keydown', '.js-menu-close', (e) => {
174      this.close();
175    });
176  },
177  init() {
178    this.click();
179  },
180};
181Menu.init();
182
183const Scroll = {
184  anchor(top, left) {
185    let option = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
186    $('html,body').animate(
187      {
188        scrollTop: top,
189        scrollLeft: left,
190      },
191      option !== null && option !== void 0 && option.immediate ? 0 : 1000,
192      'easeOutQuart'
193    );
194  },
195  update() {
196    var _this$app, _this$app$resize;
197    (_this$app = this.app) === null || _this$app === void 0 || (_this$app$resize = _this$app.resize) === null || _this$app$resize === void 0 || _this$app$resize.call(_this$app);
198  },
199  start() {
200    var _this$app2, _this$app2$start;
201    (_this$app2 = this.app) === null || _this$app2 === void 0 || (_this$app2$start = _this$app2.start) === null || _this$app2$start === void 0 || _this$app2$start.call(_this$app2);
202  },
203  stop() {
204    var _this$app3, _this$app3$stop;
205    (_this$app3 = this.app) === null || _this$app3 === void 0 || (_this$app3$stop = _this$app3.stop) === null || _this$app3$stop === void 0 || _this$app3$stop.call(_this$app3);
206  },
207  destroy() {
208    var _this$app4, _this$app4$destroy;
209    (_this$app4 = this.app) === null || _this$app4 === void 0 || (_this$app4$destroy = _this$app4.destroy()) === null || _this$app4$destroy === void 0 || _this$app4$destroy();
210  },
211  scrollTo(e) {
212    const dataScroll = typeof e === 'string' ? e : e.attr('data-anchor');
213    const offsetData = typeof e === 'string' ? 0 : isNaN(parseFloat(e.attr('data-anchor-offset'))) ? e.attr('data-anchor-offset') : parseFloat(e.attr('data-anchor-offset'));
214    let offset = 0;
215    if (typeof offsetData === 'string') {
216      offset = $(offsetData).innerHeight();
217    } else if (typeof offsetData === 'number') {
218      offset = offsetData;
219    }
220    let destination = dataScroll;
221    if (dataScroll === 'top') {
222      destination = 'body';
223    }
224    if ($(destination).length > 0) {
225      const scrollHeight = $(destination).offset().top;
226      this.anchor(scrollHeight, $(destination).offset().left, offset);
227    }
228  },
229  event() {
230    $body.on('click keydown', '[data-anchor]', (e) => {
231      if (e.type === 'click' || e.key === 'Enter') this.scrollTo($(e.currentTarget));
232    });
233  },
234  loadScroll() {
235    const _anchor = getParameterByName('scroll');
236    if (_anchor) {
237      this.scrollTo('#'.concat(_anchor));
238    }
239  },
240  init() {
241    this.event();
242  },
243};
244Scroll.init();
245
246const Drawer = {
247  setup() {
248    this.$area.each((_, el) => {
249      $(el)
250        .find('.js-drawer_btn')
251        .on('click', () => {
252          this.open(el);
253        });
254    });
255  },
256  open(target) {
257    const $target = $(target);
258    const $inner = $target.find('.js-drawer_inner');
259    clearTimeout(this.timer);
260    $inner.stop().slideToggle(400);
261    $target.toggleClass('is-open');
262  },
263  async init() {
264    this.$area = $('.js-drawer');
265    this.$content = $('.js-drawer_inner');
266    this.$btn = $('.js-drawer_btn');
267    if (this.$area.length > 0) {
268      this.setup();
269    }
270  },
271};
272
273const ScrollAnimation = {
274  instance: null,
275  param: {
276    elem: '[data-scroll-point]',
277    displayRatio: 0.9,
278    // displayReverse: false,
279    displayReverse: true,
280    addClassNameActive: 'is-active',
281    on: {
282      In: function (item, pos) {
283        ScrollAnimation.update();
284      },
285    },
286  },
287  position() {
288    return window.scrollY + document.documentElement.clientHeight;
289  },
290  set() {
291    this.instance = new SCROLL_EFFECT_MODULE(this.param);
292  },
293  scroll() {
294    window.addEventListener(
295      'scroll',
296      () => {
297        if (this.position() === document.body.clientHeight) {
298          document.querySelectorAll(this.param.elem).forEach((e) => {
299            e.classList.add('is-active');
300          });
301        }
302      },
303      false
304    );
305  },
306  resize() {
307    window.addEventListener('resize', () => {});
308  },
309  update() {
310    if (this.instance) {
311      this.instance.Update();
312    }
313  },
314  refresh() {
315    if (this.instance) {
316      this.instance.Refresh();
317    }
318  },
319  init() {
320    this.set();
321    this.scroll();
322    this.resize();
323  },
324};
325ScrollAnimation.init();
326
327const BGParticle = {
328  app: null,
329  elem: '#bg_particle',
330  source: ['/3rd/assets/img/particle.png'],
331
332  fragment: {
333    x(pos) {
334      return Math.random() * pos;
335    },
336    y(pos) {
337      return Math.random() * pos;
338    },
339    scale(scale) {
340      return mq.pc() ? scale * 0.9 + Math.random() * 1 : scale * 0.6 + Math.random() * 1;
341    },
342  },
343  state: {
344    init: false,
345    pc: true,
346  },
347  calcMultiplyReflect() {
348    // 乗算の乱数
349    const base = Math.random() * Math.random();
350    // 反転
351    const inverse = 1.0 - base;
352
353    const value = Math.random() < 0.5 ? base : inverse;
354
355    return value;
356  },
357  active() {
358    document.querySelector('#bg_particle').classList.add('is-active');
359  },
360  effect() {
361    this.devicePixelRatio = userAgent.ua === 'pc' ? 1 : window.devicePixelRatio > 2 ? 2 : window.devicePixelRatio;
362    const $area = document.querySelector('.js-bg_particle');
363    const $el = document.querySelector('#bg_particle');
364    const app = (this.app = new PIXI.Application({
365      autoStart: false,
366      width: $area.clientWidth * this.devicePixelRatio,
367      height: $area.clientHeight * this.devicePixelRatio,
368      view: $el,
369      backgroundAlpha: 0,
370      resolution: this.devicePixelRatio,
371      transparent: true,
372      forceCanvas: true,
373    }));
374    this.state.init = true;
375
376    let totalSprites = mq.pc() ? 50 : 25;
377    let sprites = new PIXI.ParticleContainer(totalSprites, {
378      scale: true,
379      position: true,
380    });
381    app.stage.addChild(sprites);
382    let fragment = [];
383
384    for (let i = this.source.length - 1; i > 0; i--) {
385      let r = Math.floor(Math.random() * (i + 1));
386      let tmp = this.source[i];
387      this.source[i] = this.source[r];
388      this.source[r] = tmp;
389    }
390    const speed = app.screen.height / 1000;
391    for (let i = 0; i < totalSprites; i++) {
392      let texture = PIXI.Texture.from(this.source[i % this.source.length]);
393      fragment.push(new PIXI.Sprite(texture));
394      const size = Math.random();
395      fragment[i].width = mq.pc() ? (30 + 20 * size) * this.devicePixelRatio : (20 + 15 * 
395size) * this.devicePixelRatio;
396      fragment[i].height = mq.pc() ? (30 + 20 * size) * this.devicePixelRatio : (20 + 15 * size) * this.devicePixelRatio;
397      fragment[i].x = app.screen.width * Math.random();
398      fragment[i].y = app.screen.height * 2 * Math.random();
399      fragment[i].anchor.set(Math.random(), Math.random());
400
401      let randNum = Math.floor(Math.random() * (360 - 1) + 1);
402      fragment[i].direction = Math.random() > 0.5;
403      fragment[i].rotation = randNum * (Math.PI / 180);
404      fragment[i].speed = (speed + Math.random() * speed * 0.2) * this.devicePixelRatio;
405
406      app.stage.addChild(fragment[i]);
407    }
408
409    this.active();
410    let tick = 0;
411    app.ticker.maxFPS = 60;
412    const sinPi = Math.sin(Math.PI / 16);
413    const cosPi = Math.cos(Math.PI / 16);
414
415    app.ticker.add(() => {
416      const screenWidth = app.screen.width;
417      const screenHeight = app.screen.height;
418      for (let i = 0; i < fragment.length; i++) {
419        fragment[i].y -= 1 * fragment[i].speed * cosPi; // 上昇
420        fragment[i].rotation = fragment[i].direction ? fragment[i].rotation - 0.02 : fragment[i].rotation + 0.02; // 回転
421
422        fragment[i].alpha = fragment[i].y / (screenHeight * 0.5) - 0.5;
423
424        // 一番上に到達したら
425        if (fragment[i].y < -200) {
426          fragment[i].x = (screenWidth - this.fragment.x(screenWidth)) * 1.3;
427          fragment[i].y = screenHeight + 200 * Math.random();
428          fragment[i].anchor.set(Math.random(), Math.random());
429          fragment[i].alpha = 1;
430          fragment[i].direction = Math.random() > 0.5;
431        }
432      }
433      tick += 0.1;
434    });
435
436    if (this.state.init) {
437      app.view.style.width = ''.concat($area.clientWidth, 'px');
438      app.view.style.height = ''.concat($area.clientHeight, 'px');
439    }
440    this.resize();
441  },
442  destroy() {
443    if (this.state.init) {
444      this.app.destroy();
445      this.state.init = false;
446    }
447  },
448  resize() {
449    const $area = document.querySelector('.js-bg_particle');
450    window.addEventListener('resize', () => {
451      if (this.state.init) {
452        this.app.renderer.resize($area.clientWidth * this.devicePixelRatio, $area.clientHeight * this.devicePixelRatio);
453        this.app.view.style.width = ''.concat($area.clientWidth, 'px');
454        this.app.view.style.height = ''.concat($area.clientHeight, 'px');
455      }
456    });
457  },
458  start() {
459    if (this.state.init) {
460      this.app.start();
461    }
462  },
463  stop() {
464    if (this.state.init) {
465      this.app.stop();
466    }
467  },
468  init() {
469    this.effect();
470    this.start();
471  },
472};
473
474const ModalModule = {
475  instance: null,
476  set() {
477    let _template =
478      '' +
479      '<section class="m-modal is-close" id="{{ id }}" data-modal-type>' +
480      '  <div class="m-modal__container">' +
481      '  <div class="m-modal__bg" data-modal-ui-close></div>' +
482      '    <div class="m-modal__content">' +
483      '    {{ content }}' +
484      '    </div>' +
485      '  </div>' +
486      '<div class="m-modal__close" data-modal-ui-close>\n' +
487      '  <div class="m-modal__close-in">\n' +
488      '    <div class="m-modal__close-bar -bar1"></div>\n' +
489      '    <div class="m-modal__close-bar -bar2"></div>\n' +
490      '  </div>\n' +
491      '</div>' +
492      '</section>';
493
494    this.instance = new MODAL_MODULE({
495      duration: 800,
496      customModalHtml: _template,
497      elemOutputSelector: 'body',
498      defaultModalStyle: false,
499      zIndex: 10,
500      elemYoutubePlayerAspectRatio: '16:9',
501      movie: {
502        youtube: {
503          playerVars: {
504            rel: 0,
505            loop: 1,
506            fs: 0,
507            // autoplay: 1,
508            controls: 1,
509            showinfo: 0,
510            disablekb: 1,
511            playsinline: 1,
512            playsinline: 1,
513            modestbranding: 1,
514            suggestedQuality: 'hd1080',
515            iv_load_policy: 3,
516            html5: 1,
517          },
518        },
519      },
520      on: {
521        init: () => {},
522        prepOpen: () => {
523          setTimeout(() => {
524            $body.addClass('is-modal-show');
525          }, 100);
526        },
527        afterOpen: (data, target) => {
528          const templateType = $(target).attr('data-modal-category');
529          if (templateType) {
530            $('.m-modal').attr('data-modal-category', templateType);
531          }
532        },
533        afterClose: () => {
534          setTimeout(() => {
535            $('.m-modal').removeAttr('data-modal-category');
536          }, 1000);
537        },
538        prepClose: () => {
539          $body.removeClass('is-modal-show');
540        },
541      },
542    });
543  },
544  update() {
545    this.instance.Update();
546  },
547  click() {},
548  init() {
549    this.set();
550  },
551};
552
553ModalModule.init();

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.