首页 JavaScript正文

js实现图片查看器

JavaScript 2022-09-14 04:09:07 165

本文实例为大家分享了js实现图片查看器的具体代码,供大家参考,具体内容如下

1. 前言

网上已经有不少成熟的图片查看器插件,如果是单纯想要点击图片放大预览的话,可以直接使用插件。例如viewerjs

但是,当打开图片后还需要对图片进行一些像删除、下载、标记等业务层面上的操作,使用插件就显得不那么便捷,于是决定自己简单写个图片查看器

2. 设计思路

项目中用的是vue+iview,于是使用Modal弹窗组件做为播放器的盒子,考虑需要用到的基本功能有:
放大缩小、
监听鼠标滚轮放大缩小、
拖拽、
全屏查看、
查看上/下一张、
双击图片回到初始大小和初始位置

3. 完成效果

4. 代码思路

html部分:

<Modal
 id="picture_viewer_modal"
 v-model="visible"
 :mask-closable = "false"
 @on-cancel="cancel()"
 footer-hide
 width="70%"
 :fullscreen="fullscreen"
>
 <div class="wrap">
  <p class="num_tip">第 {{index+1}}/{{picArr.length}} 张</p>
  
  <!-- 查看图片的盒子 -->
  <div id="father" class="box">
    <img id="box" class="img_max img_auto" @dblclick="getDefault()" :src="row.src">
    <!-- 查看上一张 -->
    <span class="next_btn btn_left" @click="left()"></span>
    <!-- 查看下一张 -->
    <span class="next_btn btn_right" @click="right()"></span>
  </div>
  
  <!-- 按钮条 -->
  <div class="tool_bar">
    <!-- 裁剪 -->
    <span class="tool_btn btn_1" @click="cutPic()"></span>
    <!-- 全屏 -->
    <span class="tool_btn btn_2" @click="fullScreen()"></span>
    <!-- 放大 -->
    <span class="tool_btn btn_3" @click="big()"></span>
    <!-- 缩小 -->
    <span class="tool_btn btn_4" @click="small()"></span>
    <!-- 下载 -->
    <span class="tool_btn btn_5" @click="download()"></span>
     <!-- 选中 -->
     <span class="tool_btn btn_8" @click="choose()"></span>
     <!-- 删除 -->
     <span class="tool_btn btn_9" @click="del(row.id)"></span>
   </div>
 </div>
</Modal>

js部分:

props: {
  picList:Array,
  rowData:Object
},
data() {
  return {
   //弹窗显隐
    visible: false,
    //当前查看的图片
    row: {},
    //当前查看的图片在数组中的位置
    index: 0,
    //所有图片
    picArr: [],
    //是否全屏
    fullscreen: false,
  };
},
watch: {
 //监听弹窗打开事件
  modal(val) {
    this.visible = val;
    if(val){
      this.init();
      this.getObj();
    }
  },
},
mounted(){
  this.move();
},
methods: {
  /**
  * 打开弹窗后,获取传入弹窗组件的数据
  */
  getObj(){
    this.row = this.rowData.row;
    this.index = this.rowData.index;
    this.picArr = this.picList;
  },
  /**
   * 初始化
   */
  init(){
    this.fullscreen = false;
    //重新打开后图片要重置回默认大小和居中
    this.getDefault();
  },
  /**
   * 双击图片恢复默认大小、位置
   */
  getDefault(){
    var image = document.getElementById("box");
    image.classList.add('img_max');
    image.classList.add('img_auto');
    box.style.left = '50%';
    box.style.top = '50%';
    box.style.transform = 'translate(-50%,-50%)';
  },
  /**
   * 拖拽移动
   */
  move(){
    var thiz = this;
    thiz.$nextTick(() => {
      var box = document.getElementById("box");
      var fa = document.getElementById('father');
      // 图片移动效果
      box.onmousedown=function(ev) {
        var oEvent = ev;
        // 浏览器有一些图片的默认事件,这里要阻止
        oEvent.preventDefault();
        var disX = oEvent.clientX - box.offsetLeft;
        var disY = oEvent.clientY - box.offsetTop;
        fa.onmousemove=function (ev) {
          oEvent = ev;
          oEvent.preventDefault();
          var x = oEvent.clientX - disX;
          var y = oEvent.clientY - disY;

          // 图形移动的边界判断
          // x = x <= 0 ? 0 : x;
          // x = x >= fa.offsetWidth-box.offsetWidth ? fa.offsetWidth-box.offsetWidth : x;
          // y = y <= 0 ? 0 : y;
          // y = y >= fa.offsetHeight-box.offsetHeight ? fa.offsetHeight-box.offsetHeight : y;
          box.style.left = x + 'px';
          box.style.top = y + 'px';
          //取消居中效果
          // box.style.transform = 'translate(0,0)';
        };
        // 图形移出父盒子取消移动事件,防止移动过快触发鼠标移出事件,导致鼠标弹起事件失效
        fa.onmouseleave = function () {
          fa.onmousemove = null;
          fa.onmouseup = null;
        };
        // 鼠标弹起后停止移动
        fa.onmouseup=function() {
          fa.onmousemove = null;
          fa.onmouseup = null;
        }
      }
      //监听鼠标滚轮放大缩小
      box.addEventListener("mousewheel", MouseWheelHandler, false);// IE9, Chrome, Safari, Opera
      box.addEventListener("DOMMouseScroll", MouseWheelHandler, false);// Firefox
      function MouseWheelHandler(e) {
        // cross-browser wheel delta 
        var e = window.event || e; // old IE support 
        var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));//IE、Opera、Safari、Chrome e.wheelDelta,Firefox中 e.detail 判断是向上还是向下滚动负值delta取-1 正值delta取1 
        box.height = Math.max(100, Math.min(2500, box.height + (50 * delta)));
        box.classList.remove('img_max');
        box.classList.remove('img_auto');
        return false;
      }
    });
  },
  /**
   * 全屏
   */
  fullScreen(){
    //控制弹窗全屏
    this.fullscreen = !this.fullscreen;
    //图片恢复默认大小、位置
    this.getDefault();
  },
  /**
   * 放大
   */
  big(){
    var image = document.getElementById("box");
    if (image.height <= 2500) {
      image.height = image.height + 40;
    }
    image.classList.remove('img_max');
    image.classList.remove('img_auto');
  },
  /**
   * 缩小
   */
  small(){
    var image = document.getElementById("box");
    if (image.height > 100) {
      image.height = image.height - 40;
    }
    image.classList.remove('img_auto');
  },
  /**
   * 查看上一张
   */
  left(){
    var thiz = this;
    if(thiz.index == 0){
      //如果是第一张,则跳到最后一张
      thiz.index = thiz.picArr.length - 1;
      thiz.row = thiz.picArr[thiz.index];
    }else{
      thiz.index = thiz.index - 1;
      thiz.row = thiz.picArr[thiz.index];
    }
    //查看上下一张的时候,图片回到初始大小和位置,这里会闪烁,待优化
    this.getDefault();
  },
  /**
   * 查看下一张
   */
  right(){
    var thiz = this;
    if(thiz.index == thiz.picArr.length-1){
      //如果是最后一张,则跳到第一张
      thiz.index = 0;
      thiz.row = thiz.picArr[thiz.index];
    }else{
      thiz.index = thiz.index + 1;
      thiz.row = thiz.picArr[thiz.index];
    }
    //查看上下一张的时候,图片回到初始大小和位置,这里会闪烁,待优化
    this.getDefault();
  },
}

css部分:

//less
@pictureBg: #fff,
@pictureBorder: #fff,
@pictureCloseBg: #fff,
@pictureCloseBorder: #1A82FD,
@pictureClose: #1A82FD,
@pictureBtn1: url('../assets/map/view_image/icon_cut_blue.png')
@pictureBtn2: url('../assets/map/view_image/icon_move_blue.png')
@pictureBtn3: url('../assets/map/view_image/icon_zoom_blue.png')
@pictureBtn4: url('../assets/map/view_image/icon_reduce_blue.png')
@pictureBtn5: url('../assets/map/view_image/icon_download_blue.png')
@pictureBtn6: url('../assets/map/view_image/icon_play_blue.png')
@pictureBtn7: url('../assets/map/view_image/icon_video_blue.png')
@pictureBtn8: url('../assets/map/view_image/icon_chose_blue.png')
@pictureBtn9: url('../assets/map/view_image/icon_delete_blue.png')
@pictureBtnHov1: url('../assets/map/view_image/icon_cut_hov.png')
@pictureBtnHov2: url('../assets/map/view_image/icon_move_hov.png')
@pictureBtnHov3: url('../assets/map/view_image/icon_zoom_hov.png')
@pictureBtnHov4: url('../assets/map/view_image/icon_reduce_hov.png')
@pictureBtnHov5: url('../assets/map/view_image/icon_download_hov.png')
@pictureBtnHov6: url('../assets/map/view_image/icon_play_hov.png')
@pictureBtnHov7: url('../assets/map/view_image/icon_video_hov.png')
@pictureBtnHov8: url('../assets/map/view_image/icon_chose_hov.png')
@pictureBtnHov9: url('../assets/map/view_image/icon_delete_hov.png')
#picture_viewer_modal{
 .ivu-modal{
  //覆盖modal关闭按钮样式
   .ivu-modal-close{
     right: -12px;
     top: -12px;
     border-radius: 100px;
     background: @pictureCloseBg;
      border:1px solid @pictureCloseBorder;
     .ivu-icon-ios-close{
       font-size: 24px;
       color: @pictureClose;
     }
   }
   //覆盖modal弹窗盒子样式
   .ivu-modal-content{
    background: @pictureBg;
      border:1px solid @pictureBorder;
     border-radius: 0;
     .ivu-modal-body{
       height: 80vh;
       padding: 35px 15px 0;
       overflow: hidden;
     }
     
     // 内容样式
     .wrap{
       height: 100%;
       >.num_tip{
        color: @pictureClose;
         position: absolute;
         top: 10px;
         left: 15px;
         z-index: 9;
       }
       //图片盒子样式
       >.box{
         height: calc(100% - 20px - 1.2vw);
         position: relative;
         //展示的图片样式
         >img{
           position: absolute;
           top: 50%;
           left: 50%;
           transform: translate(-50%, -50%);
           cursor: move;
           &.img_auto{
             width: auto;
             height: auto;
           }
           &.img_max{
             max-height: 100%;
             max-width: 100%;
           }
         }
         //上/下一张按钮样式
         >.next_btn{
           display: block;
           width: 3vw;
           height: 3vw;
           position: absolute;
           top: 50%;
           margin-top: -1.5vw;
           cursor: pointer;
           transition: all 0.2s;
           &.btn_left{
             left: 6px;
             background: url('../../../assets/map/view_image/btn_left.png') no-repeat;
             background-size: 100% 100%;
             &:hover{
               background: url('../../../assets/map/view_image/btn_left_hov.png') no-repeat;
               background-size: 100% 100%;
             }
           }
           &.btn_right{
             right: 6px;
             background: url('../../../assets/map/view_image/btn_right.png') no-repeat;
             background-size: 100% 100%;
             &:hover{
               background: url('../../../assets/map/view_image/btn_right_hov.png') no-repeat;
               background-size: 100% 100%;
             }
           }
         }
       }
     
       //底部工具条样式
       >.tool_bar{
         text-align: center;
         font-size: 0;
         position: relative;
         z-index: 9;
         .tool_btn{
           font-size: 12px;
           display: inline-block;
           width: 1.2vw;
           height: 1.2vw;
           margin: 10px 0.8vw;
           transition: all 0.2s;
           cursor: pointer;
         }
         .btn_1{
            background: @pictureBtn1 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov1 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_2{
            background: @pictureBtn2 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov2 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_3{
            background: @pictureBtn3 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov3 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_4{
            background: @pictureBtn4 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov4 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_5{
            background: @pictureBtn5 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov5 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_6{
            background: @pictureBtn6 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov6 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_7{
            background: @pictureBtn7 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov7 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_8{
            background: @pictureBtn8 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov8 no-repeat;
              background-size: 100% 100%;
            }
          }
          .btn_9{
            background: @pictureBtn9 no-repeat;
            background-size: 100% 100%;
            &:hover{
              background: @pictureBtnHov9 no-repeat;
              background-size: 100% 100%;
            }
          }
       }
     }
   }
 
   //弹窗全屏样式
   &.ivu-modal-fullscreen{
     .ivu-modal-close{
       right: 0;
       top: 0;
     }
     .ivu-modal-content{
       .ivu-modal-body{
         height: 100vh;
         overflow: hidden;
       }
     }
   }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

© 编程脚本学习网