カンマ
Nuxt3とGSAP ScrollTriggerでカンマ含み数字をカウントアニメーションさせる
北海道の事件というアプリを作っている中で、画面に到達したら事件数をカウントアニメーションさせていたが、自作のカンマ区切りプラグインだと、数字が切り上げられ、一桁になることが発覚。どうしたものかと、調べたので、メモ。
カンマ区切りの数字の挙動がおかしい
昨年末から北海道で発生した事件を表示するアプリを作っていて、月ごとと総数で事件数を表示していました。せっかくだから、アニメーションさせるかとやってみると、カンマがない時は普通にカウントされるのですが、千の位以上でカンマがあると、数字が一つしか表示されません。自作プラグインだと、GSAPとうまく連携できないみたい。他にやり方がないかなとググってみると、下記のいい感じのページがあり、さっそく取り入れることに。
TS仕様に変更する
上記を自分のプログラムにコピペして使ってみると、とりあえずちゃんと動くことはわかりました。ただし、vue-tscエラーが結構発生しているので、修正しなければなりません。copilotに聞きながら、エラーに合わせて変更すると、なんだかおかしなエラーが出てきたので、一旦リセット。変更しておかしくなるものはそのまま残して、辻褄をあわせる形で変更すると、vue-tscエラーが解消された上で、動きました。ただ、もっとうまくいくやり方があるような気がします。一応、できたものは以下。composablesにファイルがあり、それを使用する場所で呼び出して、animate(‘.lastmonthNumber’, ‘.lastmonthNumberBox’);のようにクラスを引数に渡し、使います。nextTickが入っているのは、別の場所でawaitで数字を取得しているので、その遅延処理のためです。
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
export function useAnimation () {
function numberWithCommas (n: string) {
const parts = n.toString().split('.');
return parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
function animate (targetSelector: string, targetSelectorBox: string) {
nextTick(() => {
gsap.from(targetSelector, {
textContent: 0,
duration: 3,
ease: 'Power4.easeOut',
snap: { textContent: 1 },
stagger: {
each: 1,
onUpdate: function (this: gsap.core.Tween) {
this.targets().forEach((target: unknown) => {
const element = target as HTMLElement;
const val = gsap.getProperty(element, 'innerText');
element.innerText = numberWithCommas(String(val));
});
}
},
roundProps: 'innerText',
scrollTrigger: {
trigger: targetSelectorBox,
start: 'center bottom-=20',
end: 'bottom+=1000 top',
markers: false
}
});
});
}
return { animate };
}
これにより、数字のカウントアニメーションは解決したんですが、apexchartsの方のアニメーションがうまくいってないんですよね。scrolltriggerとの組み合わせで、いけそうな気がするんだけどなぁ。