PageSourceSearch

https://ame-tsuchi.co.jp/assets/js/shikake.js

js ame-tsuchi.co.jp collected 2026-10-02 17:50:27 UTC 6,658 bytes, 149 lines download raw bytes

1/* ==========================================================================
2   shikake.js  ★仕掛け(3つ)
3   --------------------------------------------------------------------------
4   壱 幕開け   紙の幕が左右に開いてサイトが始まる
5   弐 筆跡     カーソルの軌跡が淡墨で残り、すぐ乾いて消える
6   参 罫       章の罫が、左から筆で引かれる
7   ※花火は core.js(ページ全体で時々上がります)、章番号の印も core.js です。
8
9   すべて入った状態で固定しています(入り切りのパネルは外しました)。
10   個別に止めたいときは、下の DEF の該当を false にしてください。
11   本体(core.js)には手を入れていないので、このファイルと
12   100-shikake.css を外すだけで元に戻ります。
13   ========================================================================== */
14(function () {
15  "use strict";
16
17  var $  = function (s, r) { return (r || document).querySelector(s); };
18  var reduce = matchMedia("(prefers-reduced-motion: reduce)").matches;
19  var coarse = matchMedia("(pointer:coarse)").matches;
20
21  /* ★入り切り。全部入りで固定しています。止めたいものだけ false に */
22  var DEF = { maku: true, fude: true, kei: true, hanabi: true };
23  var st = DEF;
24
25  /* 以前のブラウザに残っている選択は、もう見ません。掃除だけしておきます */
26  try { localStorage.removeItem("ametsuchi-shikake"); } catch (e) {}
27
28  function save() {
29    document.body.setAttribute("data-shikake",
30      Object.keys(st).filter(function (k) { return st[k]; }).join(" "));
31  }
32
33  /* ======================================================================
34     壱 幕開け
35     ====================================================================== */
36  function maku() {
37    if (!st.maku || reduce) return;
38    var seen = false;
39    try { seen = sessionStorage.getItem("ametsuchi-maku") === "1"; } catch (e) {}
40    if (seen) return;                       /* 同じブラウジング中は1度だけ */
41
42    var el = document.createElement("div");
43    el.id = "maku"; el.setAttribute("aria-hidden", "true");
44    /* 幕の合わせ目に、天地の角印。幕が開くと先に消えます。
45       ★画像は assets/img/rakkan-tenchi.png(genrakkan.py で作れます)。
46         「開演」の文字に戻したいときは、下の1行を
47         '<span class="seal-open">開演</span>' に差し替えてください。 */
48    el.innerHTML = '<div class="h"></div><div class="h"></div>' +
49                   '<span class="seal-open"><img src="assets/img/rakkan-tenchi.png" alt=""></span>';
50    document.body.appendChild(el);
51    document.documentElement.style.overflow = "hidden";
52
53    /* ★開くきっかけ。
54       以前は「620ミリ秒後」に開いていましたが、画像の読み込みに
55       それ以上かかるため、開ききってから表紙が組み上がる=
56       幕が見えないまま終わることがありました。
57       いまは「読み込みが終わってから0.5秒」で開きます。
58       読み込みが長引いても3秒で必ず開きます(待たせないため)。 */
59    var opened = false;
60    function open() {
61      if (opened) return;
62      opened = true;
63      el.classList.add("is-open");
64      document.documentElement.style.overflow = "";
65      try { sessionStorage.setItem("ametsuchi-maku", "1"); } catch (e) {}
66      setTimeout(function () { el.classList.add("is-done"); }, 1700);
67    }
68    if (document.readyState === "complete") setTimeout(open, 500);
69    else addEventListener("load", function () { setTimeout(open, 500); });
70    setTimeout(open, 3000);                 /* 保険。3秒で必ず開く */
71  }
72
73  /* ======================================================================
74     弐 筆跡 ―― 淡墨の線が残り、すぐ乾いて消える
75     ====================================================================== */
76  function fude() {
77    if (!st.fude || reduce || coarse) return;
78
79    var c = document.createElement("canvas");
80    c.id = "fude"; c.setAttribute("aria-hidden", "true");
81    document.body.appendChild(c);
82    var g = c.getContext("2d"), dpr = Math.min(devicePixelRatio || 1, 2);
83
84    function size() {
85      c.width  = innerWidth  * dpr;
86      c.height = innerHeight * dpr;
87      c.style.width  = innerWidth + "px";
88      c.style.height = innerHeight + "px";
89      g.setTransform(dpr, 0, 0, dpr, 0, 0);
90    }
91    size(); addEventListener("resize", size);
92
93    var pts = [], px = null, py = null, speed = 0;
94
95    addEventListener("mousemove", function (e) {
96      var x = e.clientX, y = e.clientY;
97      if (px !== null) {
98        var d = Math.hypot(x - px, y - py);
99        speed = speed * .7 + d * .3;
100      }
101      px = x; py = y;
102      /* ★線の太さ。速いほど細い(筆と同じ)。
103         もっと太くしたいときは 22 と 4.2 を上げてください。 */
104      var w = Math.max(6.5, 26 - speed * .40);
105      pts.push({ x: x, y: y, w: w, a: 1 });
106      if (pts.length > 110) pts.shift();
107    }, { passive: true });
108
109    (function loop() {
110      g.clearRect(0, 0, innerWidth, innerHeight);
111      for (var i = 1; i < pts.length; i++) {
112        var p = pts[i], q = pts[i - 1];
113        if (p.a <= 0) continue;
114        g.strokeStyle = "rgba(32,30,28," + (p.a * .26).toFixed(3) + ")";
115        /* 太さは薄れきる前に細くしすぎない(乾いても線幅は残る) */
116        g.lineWidth = p.w * (0.62 + 0.38 * p.a);
117        g.lineCap = "round"; g.lineJoin = "round";
118        g.beginPath(); g.moveTo(q.x, q.y); g.lineTo(p.x, p.y); g.stroke();
119        p.a -= .020;                         /* ★乾いていく速さ */
120      }
121      while (pts.length && pts[0].a <= 0) pts.shift();
122      requestAnimationFrame(loop);
123    })();
124  }
125
126  /* ======================================================================
127     肆 罫 ―― 章の罫が、左から筆で引かれる
128     0.9秒。読むのを邪魔しません。
129     ====================================================================== */
130  function kei() {
131    if (!st.kei || reduce) return;
132    var rules = [].slice.call(document.querySelectorAll(".rule-set"));
133    rules.forEach(function (r) {
134      r.classList.add("kei");
135      var io = new IntersectionObserver(function (es) {
136        es.forEach(function (e) {
137          if (!e.isIntersecting) return;
138          r.classList.add("is-on"); io.disconnect();
139        });
140      }, { threshold: 0.4 });
141      io.observe(r);
142    });
143  }
144
145  save();
146  maku();
147  fude();
148  kei();
149})();

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.