カウントアップ

要素がウィンドウ画面内に入ったら数字がカウントアップします。

追加可能
パーツ
変更可能箇所 同一ページ
に複数設置
ページ複製・
クリップボード使用可否

※リッチテキストの機能で
追加可能なもの
  • テキストカラー

  • フォントサイズ

 

JS変更箇所

  • カウントアップの速さ
  • SP時の挙動
※留意事項

※数字は半角数字を使用してください。
※オプションクラス「italic」を使用する場合は、斜体機能を使用した全てにデザインがあたります。

 

【JS】
※デフォルトのカウント数
 1500→1.5秒
 3000→3秒

デモ

ノーマル: 契約数61

カンマあり: 契約数335,633,456

ドットあり: 契約数335.633.456

斜体あり(オプションクラス): 契約数333.333.333

設定方法

  • CSSをカスタムCSSに記述。
  • JavaScriptを使用したいパーツのセクション一番下に配置。複数ページで使用する場合は共通フッターに配置。
  1. カウントアップさせたいテキストパーツにクラス「js-count_text」を追加。
  2. 対象となる数字に斜体を選択。

 

斜体を使用したい場合:

  1. 斜体にさせたいカウントアップ用のテキストパーツにオプションクラス「italic」を追加。

カスタムCSS

CSS内にデフォルトで用意されている、「JSパーツ集記述場所」の中に追加してください。
※アップセル等で見つからない場合は、LP記述欄の下などに入れてください。

2024-05-10更新

/*----- カウントアップ START v1.0.0 -----*/
.component {
&.richtext {
&.js-count_text {
p {
em {
font-style: normal;
}
}
//オプション
&.italic {
p {
em {
font-style: italic;
}
}
}
}
}
}
/*----- カウントアップ END -----*/
<script>
'use strict';
/* -----------------------
カウントアップ v1.0.0
----------------------- */
document.addEventListener('DOMContentLoaded', function () {

/*------------- 変数定義 【変更可能】 START -------------*/
const DURATION = 1500; /* 全体時間(ms) */
const THRESHOLD = 0.5; /* スクロール着火開始位置(0.5→要素の50%見えたら着火) */
/*------------- 変数定義 【変更可能】 END -------------*/

/*------------- 設定 START -------------*/
const BASE_MINUS = 5; /* 各桁 -5 から開始 */
const EXTRA_TURNS_MIN = 1; /* 余分回転(最小) */
const EXTRA_TURNS_MAX = 3; /* 余分回転(最大) */
const DIGIT_DELAY_MAX = 0.25; /* 各桁の開始遅延(割合) */
const FINAL_WINDOW = 0.06; /* 終盤で最終値を許可する割合 */
/*------------- 設定 END -------------*/

const blocks = document.querySelectorAll('.js-count_text');
if (!blocks.length) return;

/* 数値処理用 */
const clamp01 = (v) => Math.min(Math.max(v, 0), 1);
const randInt = (min, max) =>
Math.floor(Math.random() * (max - min + 1)) + min;
const easeInOutQuad = (t) =>
(t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2);

/* em要素からカウント用データを作成 */
const createCounters = (elements) => {
return [...elements].map(el => {
const chars = el.innerText.trim().split('');
const digits = [];

chars.forEach((ch, i) => {
if (!/\d/.test(ch)) return;

const target = Number(ch);
const start = (target - BASE_MINUS + 10) % 10;
const extraTurns = randInt(EXTRA_TURNS_MIN, EXTRA_TURNS_MAX);
const minSteps = (target - start + 10) % 10;

digits.push({
idx: i,
startDigit: start,
totalSteps: extraTurns * 10 + minSteps,
delay: Math.random() * DIGIT_DELAY_MAX
});
});

return { el, chars, digits };
});
};

/* カウント開始 */
const startCount = (counters) => {
const startTime = performance.now();

const tick = (now) => {
const elapsed = now - startTime;
const globalT = clamp01(elapsed / DURATION);
const allowFinal = globalT >= (1 - FINAL_WINDOW);

counters.forEach(counter => {
const out = counter.chars.slice();

counter.digits.forEach(d => {
const localT = clamp01((globalT - d.delay) / (1 - d.delay));
const eased = easeInOutQuad(localT);
const stepsFloat = d.totalSteps * eased;

let steps = Math.floor(stepsFloat);
if (!allowFinal) {
steps = Math.min(steps, d.totalSteps - 1);
} else {
steps = Math.min(Math.round(stepsFloat), d.totalSteps);
}

out[d.idx] = String((d.startDigit + steps) % 10);
});

counter.el.innerText = out.join('');
});

if (globalT < 1) {
requestAnimationFrame(tick);
}
};

requestAnimationFrame(tick);
};

/* .js-count_text 単位で着火 */
const startedMap = new WeakMap();

const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (!entry.isIntersecting) return;

const block = entry.target;
if (startedMap.get(block)) return;

const ems = block.querySelectorAll('em');
if (!ems.length) {
observer.unobserve(block);
return;
}

startedMap.set(block, true);
startCount(createCounters(ems));
observer.unobserve(block); /* 1回のみ */
});
}, { threshold: THRESHOLD });

blocks.forEach(block => observer.observe(block));
});
/* -----------------------
カウントアップ END
----------------------- */
</script>

JSが必要な実装の注意点スプレッドシート(H列)は読みましたか?

※必ず注意点(H列)をご確認の上閲覧ください

ページトップへ戻る