EITCH DESIGN エイチ デザイン / 画像拡大表示

menu

画像拡大表示

画像をモーダルで拡大表示する機能

  • CODE
  • DEMO
  • 説明
  • 使い方
  • 解説

準備中

imgを包むfigureに[zoomMod]classを指定。
CSSは先にmodal関数のCSSを設置してからzoomのCSSを設置

  • html

    copy
    
    
  • css

    copy
    .zoomMod {
      display: flex;
      gap: 16px;
    }
    .zoomMod-wrap {
      flex: 1;
      display: block;
      cursor: zoom-in;
      position: relative;
    }
    .zoomMod-wrap::after {
      content: '\e8ff';
      font-size: 24px;
      font-family: 'Material Icons';
      padding: 4px 4px 3px;
      line-height: 1;
      border-radius: 4px;
      background: rgba(0,0,0,0.7);
      color: #fff;
      position: absolute;
      top: 8px;
      right: 8px;
      z-index: 1;
    }
    .zoomMod-img {width: 100%;}
    
    .zoom .modalMod-sec ,
    .zoomMods ,
    .zoomMods-imgset-fig ,
    .zoomMods-imgset ,
    .zoomMods-imgset-li {height: 100%;}
    .zoom .modalMod-sec {max-height: 95%;}
    
    .zoomMods {position: relative;}
    .zoomMods-imgset {
      display: flex;
      gap: 24px;
      overflow: hidden;
    }
    .zoomMods-imgset-li {
      min-width: 100%;
      transition: 0.2s;
    }
    .zoomMods-imgset-img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
    .zoomMods-pager {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
    }
    .zoomMods-pager-dot {
      width: fit-content;
      margin: auto;
      padding: 4px 16px;
      border-radius: 16px;
      background: rgba(0,0,0,0.7);
      display: flex;
      justify-content: center;
      align-items: center;
      gap: 16px;
      position: absolute;
      bottom: -20px;
      left: 0;
      right: 0;
      z-index: 1;
      opacity: 0;
      transition: 0.2s;
    }
    .zoomMods-pager-dot-btn {
      width: 8px;
      height: 8px;
      border-radius: 50% 50%;
      background: rgba(255,255,255,0.5);
    }
    .zoomMods-pager-dot-btn:hover ,
    .act .zoomMods-pager-dot-btn {background: rgba(255,255,255,1);}
    .zoomMods-pager-btn {
      width: 32px;
      height: 32px;
      margin: auto;
      background: rgba(0,0,0,0.6);
      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;
    }
    .zoomMods:hover .zoomMods-pager-dot,
    .zoomMods:hover .zoomMods-pager-btn {opacity: 1;}
    .zoomMods-pager-btn:hover {background: rgba(0,0,0,0.9);}
    .zoomMods-pager-btn.prev {left: 8px;}
    .zoomMods-pager-btn.next {right: 8px;}
    .zoomMods-pager-btn.prev .ico-mui::before {content: '\e408';}
    .zoomMods-pager-btn.next .ico-mui::before {content: '\e409';}
    
    @media screen and (max-width: 768px) {
      .zoomMod-wrap::after {font-size: 20px;}
      .zoom .modalMod-sec,
      .zoomMods,
      .zoomMods-imgset-fig,
      .zoomMods-imgset,
      .zoomMods-imgset-li {height: auto;}
      .zoomMods-imgset-li {
        display: flex;
        justify-content: center;
        align-items: center;
      }
      .zoomMods-pager-dot {bottom: 0;}
      .zoomMods-pager-dot , .zoomMods-pager-btn {opacity: 1;}
    }
  • jQuery

    copy
    //初期設定
    $('.zoomMod img').each(function(){
      $(this).addClass('zoomMod-img');
    
      if($(this).siblings('img')[0] || $(this).prev('.zoomMod-wrap')[0]){
        //複数画像
        var wrapOBJ = '';
      } else {
        //単体画像
        var wrapOBJ = '';
      }
      if(!$(this).parents('.zoomMod-wrap')[0]){
        $(this).wrap(wrapOBJ);
      }
    });
    
    //ズームアクション
    $bd.on('click','.zoomMod-wrap',function(){
      const imgObj = $(this).find('.zoomMod-img').clone();
      const imgleng = $(this).siblings().size() + 1;
      const $i = $(this).index();
      if($(this).hasClass('list')){
        //複数画像
        var obj = '
        '; modalOpen(obj,'swip-zoom','zoom','','hug'); //画像・ドット作成 for(var i = 0; i < imgleng; i++) { $('.zoomMods-imgset').append('
      • '); $('.zoomMods-pager-dot').append('
      • '); } $('.zoomMods-imgset-li').css('transform',translateX($i)); $('.zoomMods-pager-dot-li').eq($i).addClass('act'); } else { //単体画像 var obj = '
        '; modalOpen(obj,'swip','zoom','','fill'); } }); //ページングアクション $bd.on('click','.zoomMods-pager-btn',function(){ const $li = $('.zoomMods-imgset-li'); const $dot = $('.zoomMods-pager-dot-li'); const full = $dot.length; const now = $('.zoomMods-pager-dot-li.act').index() + 1; $('.zoomMods-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 { const Num = Number(now - 2); $dot.eq(Num).addClass('act'); $li.css('transform',translateX(Num)); } } }); //ドットアクション $bd.on('click','.zoomMods-pager-dot-btn',function(){ const $papa = $(this).parent(); const $i = $papa.index(); $('.zoomMods-pager-dot-li.act').removeClass('act'); $papa.addClass('act'); $('.zoomMods-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 = $('.zoomMods-pager-dot-li.act').index(); //最初もしくは最後のアイテムの場合は動かさない if(this.pageXm - this.pageX > 0 && act === 0 || this.pageXm - this.pageX < 0 && act + 1 == $('.zoomMods-pager-dot-li').length){ this.touchedTree = false; return; } //移動量計算 if(act === 0){var X = 0;} else {var X = -(act * 100);} var Y = this.pageXm - this.pageX; var yc = Y + X; if(Y > 100 || Y < -108 - (act * 8)){ return; } else { $('.zoomMods-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); var act = $('.zoomMods-pager-dot-li.act').index(); if(this.top == 0 && this.left == 0){ return; } else if(this.left > 30){ if(act == 0){var Xm = 1;} else {var Xm = act + 1;} $('.zoomMods-imgset-li').css('transform',translateX(Xm)); $('.zoomMods-pager-dot-li.act').removeClass('act'); $('.zoomMods-pager-dot-li').eq(act + 1).addClass('act'); nowTouch = false; } else if(this.left < -30){ if(act == 0){var Xm = 100;} else {var Xm = act - 1;} $('.zoomMods-imgset-li').css('transform',translateX(Xm)); $('.zoomMods-pager-dot-li.act').removeClass('act'); $('.zoomMods-pager-dot-li').eq(act - 1).addClass('act'); nowTouch = false; } else { if(act == 0){var tX = 0;} else {var tX = '-' + act + '00%';} $('.zoomMods-imgset-li').css({'transform':translateX(tX)}); } $('.zoomMods-imgset-li').css({'transition':'0.2s'}); } }, '.modalMod-sec.swip-zoom');

      画像リスト


      単体画像