(async () => { const EXPIRE_SPAN = 24 * 60 * 60 * 1000; const STRAGE_KEY = 'sponsors_comments'; const SPEED_FPS = 150; // 1秒間に進めるピクセル数 const AjaxFunc = async () => { return new Promise((resolve, reject) => { fetch('/gsc/get_sponsors_comment/') .then((resp) => { if (!resp.ok) { throw new Error(`HTTP error, status = ${response.status}`); } return resp.json(); }) .then((json) => { if (json.data !== undefined) { try { const obj = { comments: JSON.parse(json.data), expires_at: Date.now() + EXPIRE_SPAN }; window.localStorage.setItem(STRAGE_KEY, JSON.stringify(obj)); resolve(obj); } catch (e) { obj = null; reject(`Data error : ${e.message}`); } } }) .catch(err => { reject('※エラーが発生しました:' + err); }); }); } const getRandomComment = (ary) => { return ary[Math.floor(Math.random() * ary.length)]; } const startTickerAnimation = (elm) => { if (elm) { // 文字列全体の移動距離 =「親要素の幅(100%分)」+「文字自身の幅」 const parentWidth = elm.parentElement.clientWidth; const textWidth = elm.scrollWidth; const totalDistance = parentWidth + textWidth; // 距離 ÷ 速度 = 必要な秒数 const duration = totalDistance / SPEED_FPS; // アニメーションを再設定 elm.style.animation = 'none'; elm.offsetHeight; requestAnimationFrame(() => { requestAnimationFrame(() => { // 計算した秒数(duration)を動的にセット elm.style.animation = `ticker ${duration}s linear 1`; }); }); } } const setComment2Element = async (elm) => { if (elm) { let obj = null; const json = window.localStorage.getItem(STRAGE_KEY); if (json !== null) { obj = JSON.parse(json); if (obj.expires_at !== undefined && obj.expires_at < Date.now()) { window.localStorage.removeItem(STRAGE_KEY); obj = null; } } if (obj === null) { try { obj = await AjaxFunc(); } catch (err) { elm.textContent = err; obj = null; } } if (obj !== null) { const item = getRandomComment(obj.comments); elm.textContent = `${item.name}様からのコメント:${item.comment}`; startTickerAnimation(elm); } } else { console.log('get_sponsors_comment : target element is null.') } } const elm = document.getElementById('sponsors-comment'); if (elm && elm.checkVisibility()) { setComment2Element(elm); elm.addEventListener('animationend', (evt) => {setComment2Element(evt.target);}); } })();