资讯专栏INFORMATION COLUMN

js实现图片查看器

3403771864 / 500人阅读

  1. 前言

  以对图片进行一些处理,例如:删除、下载、标记等。

  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;
  }
  }
  }
  }
  }


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/127669.html

相关文章

  • 你不知道的CSS

    摘要:不要忘了给子元素设置字号用來清除浮动除了著名的清除浮动类,利用属性也可以清除浮动。 本文首发于我的博客 CSS的世界是神奇的。随着各浏览器WEB标准的日趋统一,CSS在WEB世界中扮演的角色也愈发的重要。甚至于在GitHub上出现了You-Dont-Need-JavaScript这样Star近万的优秀开源项目,抛开该项目的实用性不说,项目中的众多的DEMO就已经证明了CSS的强大。当然...

    cnio 评论0 收藏0
  • Webpack快速入门

    摘要:了解相关什么是是一个模块打包器。配置文件默认是一个模块,返回一个格式的配置信息对象插件插件件可以完成一些不能完成的功能。插件的使用一般是在的配置信息选项中指定。 了解Webpack相关 什么是webpack Webpack是一个模块打包器(bundler)。 在Webpack看来, 前端的所有资源文件(js/css/img/less/...)都会作为模块处理 它将根据模块的依...

    laznrbfe 评论0 收藏0
  • Webpack快速入门

    摘要:了解相关什么是是一个模块打包器。配置文件默认是一个模块,返回一个格式的配置信息对象插件插件件可以完成一些不能完成的功能。插件的使用一般是在的配置信息选项中指定。 了解Webpack相关 什么是webpack Webpack是一个模块打包器(bundler)。 在Webpack看来, 前端的所有资源文件(js/css/img/less/...)都会作为模块处理 它将根据模块的依...

    curried 评论0 收藏0
  • Webpack快速入门

    摘要:了解相关什么是是一个模块打包器。配置文件默认是一个模块,返回一个格式的配置信息对象插件插件件可以完成一些不能完成的功能。插件的使用一般是在的配置信息选项中指定。 了解Webpack相关 什么是webpack Webpack是一个模块打包器(bundler)。 在Webpack看来, 前端的所有资源文件(js/css/img/less/...)都会作为模块处理 它将根据模块的依...

    LMou 评论0 收藏0

发表评论

0条评论

3403771864

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<