<ul class="scroll-anim-21" id="js-scroll-anim-21">
    <li class="scroll-anim-21__item">
        <h3 class="scroll-anim-21__heading">プロジェクト</h3>
        <p class="scroll-anim-21__number"><span class="scroll-anim-21__count" data-count="123">0</span>件以上</p>
    </li>
    <li class="scroll-anim-21__item">
        <h3 class="scroll-anim-21__heading">顧客満足度</h3>
        <p class="scroll-anim-21__number"><span class="scroll-anim-21__count" data-count="70">0</span>%</p>
    </li>
    <li class="scroll-anim-21__item">
        <h3 class="scroll-anim-21__heading">現在のプロジェクト</h3>
        <p class="scroll-anim-21__number"><span class="scroll-anim-21__count" data-count="15">0</span></p>
    </li>
    <li class="scroll-anim-21__item">
        <h3 class="scroll-anim-21__heading">経験年数</h3>
        <p class="scroll-anim-21__number"><span class="scroll-anim-21__count" data-count="5">0</span></p>
    </li>
</ul>
ul.scroll-anim-21#js-scroll-anim-21
  each item in items
    li.scroll-anim-21__item
      h3.scroll-anim-21__heading #{ item.heading }
      p.scroll-anim-21__number
        span.scroll-anim-21__count( data-count=item.count ) 0
        | #{ item.unit }
{
  "items": [
    {
      "heading": "プロジェクト",
      "count": 123,
      "unit": "件以上"
    },
    {
      "heading": "顧客満足度",
      "count": 70,
      "unit": "%"
    },
    {
      "heading": "現在のプロジェクト",
      "count": 15,
      "unit": "件"
    },
    {
      "heading": "経験年数",
      "count": 5,
      "unit": "年"
    }
  ]
}
  • Content:
    $BLOCK_NAME: '.scroll-anim-21';
    
    #{ $BLOCK_NAME } {
      @include Mq(md) {
        display: flex;
      }
    
      &__item {
        display: flex;
        flex-direction: column;
        flex-grow: 1;
        align-items: center;
        justify-content: center;
        margin-bottom: 16px;
        @include Mq(md) {
          margin-bottom: 0;
        }
      }
    
      &__number {
        font-size: 24px;
        font-weight: bold;
      }
    }
    
  • URL: /components/raw/scroll-anim21/scroll-anim21.scss
  • Filesystem Path: src/components/scroll-anims/scroll-anim21/scroll-anim21.scss
  • Size: 397 Bytes
  • Content:
    'use strict';
    
    export const scrollAnim21 = () => {
      const anim = new Anim21('js-scroll-anim-21');
      anim.init();
    }
    
    class Anim21 {
      el: HTMLElement;
      numEl: NodeListOf<HTMLElement>;
      countTime: number;
      countInterval: number;
      constructor(elId: string) {
        this.el = document.getElementById(elId);
        if (!this.el) return;
        this.numEl = this.el.querySelectorAll('.scroll-anim-21__count');
        this.countTime = 1000;
        this.countInterval = 50;
      }
    
      /**
       * 初期化
       */
      init(): void {
        if (!this.el) return;
        this.scrollHandler();
      }
    
      /**
       * カウントアップ開始
       */
      startCountUp() {
        [...this.numEl].forEach(el => {
          let count = el.dataset.count;
          this.countUp(el, Number(count));
        });
      }
    
      /**
       * カウントアップ
       * @param el カウントする要素
       * @param count カウント数
       */
      countUp(el: HTMLElement, count: number) {
        let currentNumber = 0;
        let currentTime = 0;
        const timer = setInterval(() => {
          el.textContent = currentNumber.toString();
          currentTime += this.countInterval;
          currentNumber = Math.floor(count / this.countTime * currentTime);
          if(currentTime === this.countTime){
            clearInterval(timer);
            el.textContent = count.toString();
          }
        }, this.countInterval);
      }
    
      /**
       * スクロール連動のイベント設定
       */
      scrollHandler(): void {
        const options = {
          // @ts-ignore
          root: null,
          rootMargin: '-30% 0px',
          threshold: 0
        }
        const observer = new IntersectionObserver((entries) => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              this.startCountUp();
              observer.disconnect();
            }
          });
        }, options);
        observer.observe(this.el);
      }
    }
    
  • URL: /components/raw/scroll-anim21/scroll-anim21.ts
  • Filesystem Path: src/components/scroll-anims/scroll-anim21/scroll-anim21.ts
  • Size: 1.9 KB

No notes defined.