PageSourceSearch

https://ieben.net/calendar/moon-animation/moon-animation/animation.js

js ieben.net collected 2026-10-02 22:53:45 UTC 8,641 bytes, 260 lines download raw bytes

1'use strict';
2let moonNList;
3let animationGroup;
4let runBtn;
5let pauseBtn;
6
7const defaultset = () => {
8  const s12Nlist = document.querySelectorAll('.s12'),
9    s336Nlist = document.querySelectorAll('.s336'),
10    s12_4ele = document.querySelector('.s124'),
11    measure = document.querySelector('.measure'),
12    knob = document.getElementById('position-range'),
13    plusBtn = document.getElementById('plus-btn'),
14    minusBtn = document.getElementById('minus-btn'),
15    sMeter = document.getElementById('speedometer'),
16    measureElm = document.getElementById('time-measure'),
17    uBox = document.getElementById('universebox'),
18    gBox = document.getElementById('groundbox'),
19    checkboxHTMLcol = document.getElementById('checkbox').children,
20    canvas1 = document.getElementById('shadow');
21  moonNList = s12_4ele.querySelectorAll('svg');
22  animationGroup = document.querySelectorAll('.s12, .s124, .s336, .measure');
23  runBtn = document.getElementById('run-btn');
24  pauseBtn = document.getElementById('pause-btn');
25
26  const earthJitenDuration = 12000,
27    moonKoutenDays = 29,
28    moonKoutenDuration = earthJitenDuration * moonKoutenDays,
29    synodicDuration = earthJitenDuration * moonKoutenDays / (moonKoutenDays - 1);
30
31  let startTime = null,
32    pauseTime = null,
33    total_elapsedTime = 0,
34    elapsedDelay = 0,
35    speedRange = 1,
36    speedometer = 45,
37    isRunning = false,
38    inRangeChangeTemporaryPause = false;
39  const speedRangeArr = [0.1, 0.2, 0.5, 1, 2, 3, 4],
40    speedometerArr = [-40, -20, 10, 45, 105, 165, 225];
41
42  /* -------------------- utilities -------------------- */
43  const positionSet = () => {
44    for (let i = 0; i < s12Nlist.length; i++) { // s12
45      s12Nlist[i].style.animationDuration = `${earthJitenDuration / speedRange}ms`;
46      s12Nlist[i].style.animationDelay = `${elapsedDelay}ms`;
47    }
48    s12_4ele.style.animationDuration = `${synodicDuration / speedRange}ms`; // s12.4
49    s12_4ele.style.animationDelay = `${elapsedDelay}ms`;
50    for (let i = 0; i < s336Nlist.length; i++) { // s336
51      s336Nlist[i].style.animationDuration = `${moonKoutenDuration / speedRange}ms`;
52      s336Nlist[i].style.animationDelay = `${elapsedDelay}ms`;
53    }
54    for (let i = 0; i < moonNList.length; i++) { // s336
55      moonNList[i].style.animationDuration = `${moonKoutenDuration / speedRange}ms`;
56      moonNList[i].style.animationDelay = `${((-(synodicDuration / 2 ) + (synodicDuration * i))/ speedRange) + elapsedDelay}ms`;
57    }
58    measure.style.animationDuration = `${1200 / speedRange}ms`; // s12
59    measure.style.animationDelay = `${elapsedDelay}ms`;
60  };
61
62  const timeSekisan = () => {
63    total_elapsedTime += pauseTime - startTime;
64  };
65
66  const speedChange = (num) => {
67    if (isRunning) {
68      pauseTime = performance.now().toFixed(4);
69      timeSekisan();
70      startTime = performance.now().toFixed(4);
71    }
72    let currentPosition = (total_elapsedTime - elapsedDelay) * speedRange;
73    speedRange = num;
74    let prePosition = total_elapsedTime * speedRange;
75    let positionDifference = prePosition - currentPosition;
76    elapsedDelay = positionDifference / speedRange;
77    positionSet();
78  };
79
80  const runORpauseSet = (st) => {
81    for (let j = 0; j < animationGroup.length; j++) {
82      animationGroup[j].style.animationPlayState = st;
83    }
84    for (let i = 0; i < moonNList.length; i++) {
85      moonNList[i].style.animationPlayState = st;
86    }
87  };
88
89  const runMotion = () => {
90    startTime = performance.now().toFixed(4);
91    isRunning = true;
92    runORpauseSet('running');
93  };
94
95  const pauseMotion = () => {
96    pauseTime = performance.now().toFixed(4);
97    isRunning = false;
98    timeSekisan();
99    runORpauseSet('paused');
100  };
101
102  /* -------------------- event -------------------- */
103  runBtn.addEventListener('click', () => {
104    runBtn.style.display = 'none';
105    pauseBtn.style.display = 'flex';
106    runMotion();
107  }, false);
108
109  pauseBtn.addEventListener('click', () => {
110    pauseBtn.style.display = 'none';
111    runBtn.style.display = 'flex';
112    pauseMotion();
113  }, false);
114
115  plusBtn.addEventListener('click', () => {
116    if (speedRange != 4) {
117      let newRange = speedRangeArr[speedRangeArr.indexOf(speedRange) + 1];
118      speedChange(newRange);
119      let newAngle = speedometerArr[speedometerArr.indexOf(speedometer) + 1];
120      meterChange(newAngle);
121    }
122  }, false);
123
124  minusBtn.addEventListener('click', () => {
125    if (speedRange != 0.1) {
126      let newRange = speedRangeArr[speedRangeArr.indexOf(speedRange) - 1];
127      speedChange(newRange);
128      let newAngle = speedometerArr[speedometerArr.indexOf(speedometer) - 1];
129      meterChange(newAngle);
130    }
131  }, false);
132
133  knob.addEventListener('input', (e) => {
134    const moonAge = e.target.value;
135    let rangePosition = (moonAge * earthJitenDuration) / speedRange;
136    elapsedDelay = total_elapsedTime - rangePosition;
137    positionSet();
138  }, false);
139
140  knob.addEventListener('pointerdown', () => {
141    gBox.style.opacity = '0.1';
142    uBox.style.opacity = '0.6';
143    if (isRunning) {
144      inRangeChangeTemporaryPause = true;
145      pauseMotion();
146    }
147  });
148
149  const rangechangeEnd = () => {
150    gBox.style.opacity = '1';
151    uBox.style.opacity = '1';
152    if (inRangeChangeTemporaryPause) {
153      runMotion();
154      inRangeChangeTemporaryPause = false;
155    }
156  };
157
158  knob.addEventListener('pointerup', rangechangeEnd, false);
159  knob.addEventListener('pointerout', rangechangeEnd, false);
160  knob.addEventListener('pointercancel', rangechangeEnd, false);
161
162  measureElm.addEventListener('animationiteration', () => {
163    if (!inRangeChangeTemporaryPause) {
164      let v = Number(knob.value);
165      if (v >= 60) {
166        v = Math.floor(((v * 10) - 290) / 10);
167        knob.value = String(v);
168      }
169      v = Math.floor(v * 10);
170      v++;
171      knob.value = String(v / 10);
172    }
173  }, false);
174
175  /* -------------------- selectbox -------------------- */
176  const show_hide_Arr = [];
177  show_hide_Arr.push(document.getElementById('un-moonbox'), document.getElementById('un-hrLine'), document.getElementById('sunlight'), document.getElementById('gr-moonbox'));
178  for (let i = 0; i < checkboxHTMLcol.length; i++) {
179    checkboxHTMLcol[i].addEventListener('click', () => {
180      const elm = checkboxHTMLcol[i];
181      if (elm.className === 'check-Yes') {
182        elm.className = 'check-No';
183        show_hide_Arr[i].style.opacity = '0';
184      } else {
185        elm.className = 'check-Yes';
186        show_hide_Arr[i].style.opacity = '1';
187      }
188    });
189  }
190
191  /* -------------------- canvas -------------------- */
192  canvas1.width = 75;
193  canvas1.height = 150;
194  const ctx1 = canvas1.getContext('2d');
195  ctx1.fillStyle = "rgba(0, 0, 0, 0.75)";
196  ctx1.beginPath();
197  ctx1.arc(75, 75, 75, 90 * Math.PI / 180, 270 * Math.PI / 180, false);
198  ctx1.closePath();
199  ctx1.fill();
200
201  sMeter.width = 300;
202  sMeter.height = 300;
203  const ctx2 = sMeter.getContext('2d');
204  const meterChange = (angle) => {
205    speedometer = angle;
206    ctx2.clearRect(-150, -150, 300, 300);
207    ctx2.save();
208    ctx2.fillStyle = "#1a1a1a";
209    ctx2.strokeStyle = "gray";
210    ctx2.lineWidth = 20;
211    ctx2.beginPath();
212    ctx2.arc(150, 150, 140, 45 * Math.PI / 180, 135 * Math.PI / 180, true);
213    ctx2.fill();
214    ctx2.stroke();
215    ctx2.closePath();
216    ctx2.restore();
217    ctx2.save();
218    ctx2.fillStyle = '#ffcc00';
219    ctx2.translate(150, 150);
220    ctx2.rotate(angle * Math.PI / 180);
221    ctx2.translate(-150, -150);
222    ctx2.beginPath();
223    ctx2.moveTo(40, 157);
224    ctx2.lineTo(40, 143);
225    ctx2.lineTo(160, 135);
226    ctx2.lineTo(160, 165);
227    ctx2.fill();
228    ctx2.restore();
229  };
230  positionSet();
231  meterChange(45);
232};
233
234/* -------------------- default -------------------- */
235window.onload = () => {
236  defaultset();
237};
238
239/* -------------------- modalcloseのアニメーション初期化 -------------------- */
240const closeEle = document.querySelectorAll('.md_close');
241const openElm = document.getElementById('md-open');
242closeEle.forEach((target) => {
243  target.addEventListener('click', () => {
244    openElm.style.pointerEvents = 'none';
245    for (let j = 0; j < animationGroup.length; j++) {
246      animationGroup[j].style.animationPlayState = 'paused';
247    }
248    for (let i = 0; i < moonNList.length; i++) {
249      moonNList[i].style.animationPlayState = 'paused';
250    }
251    pauseBtn.style.display = 'none';
252    runBtn.style.display = 'flex';
253    const resetWrap = document.getElementById('displaywrap');
254    const clone = resetWrap.cloneNode(true);
255    resetWrap.parentNode.replaceChild(clone, resetWrap);
256    document.getElementById('position-range').value = 29;
257    defaultset();
258    openElm.style.pointerEvents = 'auto';
259  }, false);
260});

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.