Image Group

複数の画像をグループ化してモーダルで拡大表示する機能

CSSに関しては一部CSSライブラリを採用しているので併用してください。

画像をモーダルで拡大表示します。

  • DEMO
  • 別要素テスト1
  • 別要素テスト2
  • 単体テスト
  • Text Test

  • Text Test

  • Text Test

  • No.1

  • No.2

  • No.3

  • No.4

  • No.5

  • No.6

使い方

グループ化したい*-img-*を包む要素に+-.GzoomMod-+クラスを指定してください。

モーダル表示と併用するのでModalライブラリの記述も読み込んでください。
  • CSS
  • Script
.GzoomMod {
    display: flex;
    gap: 16px;
  }
  .GzoomMod-wrap {
    flex: 1;
    height: fit-content;
    display: block;
    cursor: zoom-in;
    position: relative;
  }
  .GzoomMod-wrap::after {
    content: '\e8ff';
    padding: 4px;
    border-radius: 50px;
    background: var(--bg-overlay);
    color: #fff;
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 1;
    opacity: 0;
    transition: .2s;
  }
  .GzoomMod-wrap:hover:after {opacity: 1;}
  .GzoomMod-img {width: 100%;}
  
  .zoom .modalMod-sec ,
  .GzoomMods ,
  .GzoomMods-imgset-fig ,
  .GzoomMods-imgset-li {height: 100%;}
  .zoom .modalMod-sec {max-height: 95%;}
  
  .GzoomMods {position: relative;}
  .GzoomMods-imgset {
    height: calc(100% - 16px);
    display: flex;
    gap: 24px;
    overflow: hidden;
  }
  .GzoomMods-imgset-li {
    min-width: 100%;
    transition: 0.2s;
  }
  .GzoomMods-imgset-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
  }
  .GzoomMods-pager {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
  }
  .GzoomMods-pager-dot {
    width: fit-content;
    margin: auto;
    padding: 8px 16px;
    border-radius: 16px;
    background: var(--bg-overlay);
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 16px;
    position: absolute;
    bottom: -16px;
    left: 0;
    right: 0;
    z-index: 1;
    opacity: 0;
    transition: 0.2s;
  }
  .GzoomMods-pager-dot-btn {
    width: 8px;
    height: 8px;
    border-radius: 50% 50%;
    background: rgba(255,255,255,0.5);
  }
  .GzoomMods-pager-dot-btn:hover ,
  .act .GzoomMods-pager-dot-btn {background: rgba(255,255,255,1);}
  .GzoomMods-pager-btn {
    width: 32px;
    height: 32px;
    margin: auto;
    background: var(--bg-overlay);
    color: #fff;
    border-radius: 50% 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 1;
    opacity: 0;
    transition: 0.2s;
  }
  .GzoomMods:hover .GzoomMods-pager-dot,
  .GzoomMods:hover .GzoomMods-pager-btn {opacity: 1;}
  .GzoomMods-pager-btn:hover {background: rgba(0,0,0,0.9);}
  .GzoomMods-pager-btn.prev {left: 8px;}
  .GzoomMods-pager-btn.next {right: 8px;}
  .GzoomMods-pager-btn.prev .ico-mui::before {content: '\e408';}
  .GzoomMods-pager-btn.next .ico-mui::before {content: '\e409';}
  
  @media screen and (max-width: 768px) {
    .zoom .modalMod-sec,
    .GzoomMods,
    .GzoomMods-imgset-fig,
    .GzoomMods-imgset,
    .GzoomMods-imgset-li {height: auto;}
    .GzoomMods-imgset-li {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .GzoomMods-pager-dot {bottom: 0;}
    .GzoomMods-pager-dot , .GzoomMods-pager-btn {opacity: 1;}
//初期設定
  $('.GzoomMod img').each(function(){
    $(this).addClass('GzoomMod-img');
    let wrapOBJ = '';
  
    if($(this).siblings('img')[0] || $(this).parents('.GzoomMod').find('.GzoomMod-img').length > 1){
      //複数画像
      wrapOBJ = '';
    }
    if(!$(this).parents('.GzoomMod-wrap')[0]){
      $(this).wrap(wrapOBJ);
    }
  });
  
  //ズームアクション
  $bd.on('click','.GzoomMod-wrap',function(){
    let $Mod = $(this).parents('.GzoomMod');
    let imgleng = $Mod.find('.GzoomMod-wrap').length;
    let $i = $Mod.find('.GzoomMod-wrap').index($(this));
    let $img = $(this).find('.GzoomMod-img');

    let src = $img.attr('src');
    if($img.data('suffix') != ''){
      let suffix = 'zoom';
      if($img.data('suffix') != undefined){
        suffix = $img.data('suffix');
      }
      src = src.replace('.','_'+suffix +'.');
    }
    let obj = '
'; if($(this).hasClass('list')){ //複数画像 obj = '
      '; modalOpen(obj,'swip-zoom','zoom','','hug'); //画像・ドット作成 for(var i = 0; i < imgleng; i++) { let t = $Mod.find('.GzoomMod-img').eq(i); let src = t.attr('src'); if(t.data('suffix') != ''){ let suffix = 'zoom'; if(t.data('suffix') != undefined){ suffix = t.data('suffix'); } src = src.replace('.','_'+suffix +'.'); } $('.GzoomMods-imgset').append('
    • '); $('.GzoomMods-pager-dot').append('
    • '); } $('.GzoomMods-imgset-li').css('transform',translateX($i)); $('.GzoomMods-pager-dot-li').eq($i).addClass('act'); } else { //単体画像 modalOpen(obj,'swip','zoom','','fill'); } }); //ページングアクション $bd.on('click','.GzoomMods-pager-btn',function(){ let $li = $('.GzoomMods-imgset-li'); let $dot = $('.GzoomMods-pager-dot-li'); let full = $dot.length; let now = $('.GzoomMods-pager-dot-li.act').index() + 1; $('.GzoomMods-pager-dot-li.act').removeClass('act'); if($(this).hasClass('next')){ //次へ if(full == now){ //最後なら $dot.eq(0).addClass('act'); $li.css('transform','translateX(0)'); } else { $dot.eq(now).addClass('act'); $li.css('transform',translateX(now)); } } else if($(this).hasClass('prev')){ //前へ if(now == 1){ //最初なら $dot.last().addClass('act'); $li.css('transform',translateX(full - 1)); } else { let Num = Number(now - 2); $dot.eq(Num).addClass('act'); $li.css('transform',translateX(Num)); } } }); //ドットアクション $bd.on('click','.GzoomMods-pager-dot-btn',function(){ let $papa = $(this).parent(); let $i = $papa.index(); $('.GzoomMods-pager-dot-li.act').removeClass('act'); $papa.addClass('act'); $('.GzoomMods-imgset-li').css('transform',translateX($i)); }); //移動量計算 function translateX(num){ return 'translateX(calc(-' + num + '00% - ' + 24 * num + 'px))'; } //スワイプ $bd.on({ 'touchstart': function(e){ this.pageX = (isTouch ? event.changedTouches[0].pageX : e.pageX); this.pageY = (isTouch ? event.changedTouches[0].pageY : e.pageY); this.touchedTree = true; this.touched = false; }, 'touchmove': function(e){ if(!this.touchedTree){return;} this.pageXm = (isTouch ? event.changedTouches[0].pageX : e.pageX); this.pageYm = (isTouch ? event.changedTouches[0].pageY : e.pageY); if(this.pageXm != 0){ var act = $('.GzoomMods-pager-dot-li.act').index(); //最初もしくは最後のアイテムの場合は動かさない if(this.pageXm - this.pageX > 0 && act === 0 || this.pageXm - this.pageX < 0 && act + 1 == $('.GzoomMods-pager-dot-li').length){ this.touchedTree = false; return; } //移動量計算 if(act === 0){var X = 0;} else {var X = -(act * 100);} let Y = this.pageXm - this.pageX; let yc = Y + X; if(Y > 100 || Y < -108 - (act * 8)){ return; } else { $('.GzoomMods-imgset-li').css({ 'transform':'translateX(' + yc + '%)', 'transition':'none' }); } nowTouch = true; } }, 'touchend': function(e){ if(!this.touchedTree){return;} this.touchedTree = false; this.left = this.pageX - (isTouch ? event.changedTouches[0].pageX : e.pageX); this.top = this.pageY - (isTouch ? event.changedTouches[0].pageY : e.pageY); let act = $('.GzoomMods-pager-dot-li.act').index(); if(this.top == 0 && this.left == 0){ return; } else if(this.left > 30){ let Xm = act + 1; if(act == 0){Xm = 1;} $('.GzoomMods-imgset-li').css('transform',translateX(Xm)); $('.GzoomMods-pager-dot-li.act').removeClass('act'); $('.GzoomMods-pager-dot-li').eq(act + 1).addClass('act'); nowTouch = false; } else if(this.left < -30){ let Xm = act - 1; if(act == 0){Xm = 100;} $('.GzoomMods-imgset-li').css('transform',translateX(Xm)); $('.GzoomMods-pager-dot-li.act').removeClass('act'); $('.GzoomMods-pager-dot-li').eq(act - 1).addClass('act'); nowTouch = false; } else { let tX = '-' + act + '00%'; if(act == 0){tX = 0;} $('.GzoomMods-imgset-li').css({'transform':translateX(tX)}); } $('.GzoomMods-imgset-li').css({'transition':'0.2s'}); } }, '.modalMod-sec.swip-zoom');

      サフィックス

      拡大後の画像置換設定

      デフォルトでは拡大後の画像は元画像のファイル名に[_zoom]のサフィックスを付けたファイル名にしています。
      他のサフィックスを使用する場合は[data-suffix]属性に「_」を抜いたサフィックスの値を入れてください。
      画像の置換をせずに元画像をそのまま拡大する場合は空で[data-suffix]属性を付けてください。

      拡大前)hoge.jpg

      デフォルト)hoge_zoom.jpg

      data-suffix="xl")hoge_xl.jpg

      data-suffix="")hoge.jpg

      • サフィックス指定
      • サフィックス無し