<ul class="carousel-03" id="js-carousel-03">
    <li class="carousel-03__item-wrapper"><a class="carousel-03__item" href="#">
            <div class="carousel-03__bg" style="background-image: url(https://picsum.photos/id/1000/800/400)"></div>
            <div class="carousel-03__text">
                <h2 class="carousel-03__title"><span>TITLE1</span></h2><br />
                <p class="carousel-03__catch"><span>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</span></p>
            </div>
        </a></li>
    <li class="carousel-03__item-wrapper"><a class="carousel-03__item" href="#">
            <div class="carousel-03__bg" style="background-image: url(https://picsum.photos/id/1001/800/400)"></div>
            <div class="carousel-03__text">
                <h2 class="carousel-03__title"><span>TITLE2</span></h2><br />
                <p class="carousel-03__catch"><span>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</span></p>
            </div>
        </a></li>
    <li class="carousel-03__item-wrapper"><a class="carousel-03__item" href="#">
            <div class="carousel-03__bg" style="background-image: url(https://picsum.photos/id/1002/800/400)"></div>
            <div class="carousel-03__text">
                <h2 class="carousel-03__title"><span>TITLE3</span></h2><br />
                <p class="carousel-03__catch"><span>テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。</span></p>
            </div>
        </a></li>
</ul>
ul.carousel-03#js-carousel-03
  each item in carouselItems
    li.carousel-03__item-wrapper
      a.carousel-03__item(href=item.link)
        div.carousel-03__bg(style='background-image: url(' + item.img + ')')
        div.carousel-03__text
          h2.carousel-03__title
            span #{ item.title }
          br
          p.carousel-03__catch
            span #{ item.catch }
{
  "carouselItems": [
    {
      "link": "#",
      "img": "https://picsum.photos/id/1000/800/400",
      "title": "TITLE1",
      "catch": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。"
    },
    {
      "link": "#",
      "img": "https://picsum.photos/id/1001/800/400",
      "title": "TITLE2",
      "catch": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。"
    },
    {
      "link": "#",
      "img": "https://picsum.photos/id/1002/800/400",
      "title": "TITLE3",
      "catch": "テキストが入ります。テキストが入ります。テキストが入ります。テキストが入ります。"
    }
  ]
}
  • Content:
    $BLOCK_NAME: '.carousel-03';
    
    // 変数
    $color_primary: #d31619;
    $color_white: #fff;
    $duration_default: 1s;
    $easing_default: cubic-bezier(0.55, 0.05, 0.22, 0.99);
    @mixin clipTransition($delay: 0) {
      clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
      transition: clip-path $duration_default $easing_default #{$delay + 's'};
      transform: translateZ(0);
      will-change: clip-path;
      @at-root #{ $BLOCK_NAME }__item-wrapper.is-current & {
        clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
      }
      @at-root #{ $BLOCK_NAME }__item-wrapper.is-next & {
        clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
      }
    }
    
    #{ $BLOCK_NAME } {
      position: relative;
      width: 100%;
      height: calc(100vh - 32px);
    
      &__item-wrapper {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        overflow: hidden;
        clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%);
        transition: clip-path $duration_default ease 0s;
        transform: translateZ(0);
        &.is-current,
        &.is-next {
          clip-path: polygon(100% 0, 0 0, 0 100%, 100% 100%);
        }
        &.is-next {
          z-index: 2;
          &.is-current {
            z-index: 1;
          }
        }
      }
    
      &__item {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        display: block;
      }
    
      &__bg {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background-repeat: no-repeat;
        background-position: center center;
        background-size: cover;
        transition: transform 5s 0s;
        @at-root #{ $BLOCK_NAME }__item-wrapper.is-active & {
          transform: scale(1.1);
        }
        @at-root #{ $BLOCK_NAME }__item-wrapper.is-next & {
          transform: scale(1.1);
        }
      }
    
      &__text {
        position: absolute;
        bottom: 100px;
        left: 100px;
        z-index: 1;
      }
    
      &__title {
        position: relative;
        display: inline-block;
        padding: 10px;
        font-size: 24px;
        color: $color_white;
        @include clipTransition(1);
        &::before {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          z-index: -1;
          content: '';
          background: $color_primary;
        }
        & > span {
          @include clipTransition(2);
        }
      }
    
      &__catch {
        position: relative;
        display: inline-block;
        padding: 10px;
        font-size: 18px;
        color: $color_primary;
        @include clipTransition(1);
        &::before {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          z-index: -1;
          content: '';
          background: $color_white;
        }
        & > span {
          @include clipTransition(2);
        }
      }
    }
    
  • URL: /components/raw/carousel03/carousel03.scss
  • Filesystem Path: src/components/carousels/carousel03/carousel03.scss
  • Size: 2.7 KB
  • Content:
    'use strict';
    
    export const carousel03 = () => {
      const carousel = new Carousel03('js-carousel-03');
      carousel.init();
    }
    
    class Carousel03 {
      el: HTMLElement;
      itemEls: NodeListOf<HTMLElement>;
      currentIndex: number;
      slideTime: number;
      loadedImg: number;
      constructor(elId: string) {
        this.el = document.getElementById(elId);
        if (!this.el) return;
        this.itemEls = this.el.querySelectorAll('.carousel-03__item-wrapper');
        this.loadedImg = 0;
        this.currentIndex = 0;
        this.slideTime = 4000;
      }
    
      /**
       * 初期化
       */
      init(): void {
        if (!this.el) return;
        this.loadingHandler();
      }
    
      /**
       * スライド
       * @param first 初期表示であるか
       */
      slide(first: Boolean = false): void {
        [...this.itemEls].forEach(el => {
          if (el.classList.contains('is-current')) {
            el.classList.remove('is-current');
            el.classList.remove('is-next');
          }
        });
        let current;
        if (first) {
          current = this.itemEls.length - 1;
        } else {
          current = this.currentIndex;
        }
        const next = current >= this.itemEls.length - 1 ? 0 : current + 1;
        const currentEl = this.itemEls[current];
        const nextEl = this.itemEls[next];
        currentEl.classList.add('is-current');
        nextEl.classList.add('is-next');
        // 次のスライドをアニメーションさせる
        setTimeout(() => {
          this.currentIndex = next;
          this.slide();
        }, this.slideTime);
      }
    
      /**
       * 画像読み込み完了時の処理
       */
      loadingHandler(): void {
        [...this.itemEls].forEach(el => {
          const bgEl = <HTMLElement>el.querySelector('.carousel-03__bg');
          // 背景要素から画像URLを取得
          const url = bgEl.style.backgroundImage.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
          const img = new Image();
          img.addEventListener('load', () => {
            this.loadedImg++;
            this.startSlide();
          });
          img.src = url;
        });
      }
    
      /**
       * スライドの開始
       */
      startSlide(): void {
        // 全ての画像の読み込みが完了していない場合、処理を終了
        if (this.loadedImg !== this.itemEls.length) return;
        this.slide(true);
      }
    }
    
  • URL: /components/raw/carousel03/carousel03.ts
  • Filesystem Path: src/components/carousels/carousel03/carousel03.ts
  • Size: 2.3 KB