<template>
  <div
    class="img-review-wrapper"
    v-show="imgReviewVisible"
    @click.self="closeImgReview"
    @mousewheel.prevent="rollImg()"
  >
    <!-- 顶部信息栏 & 工具栏 -->
    <div class="tip-wrapper" v-if="imgReviewVisible">
      <div class="name" :title="activeFileName + activeExtendName">{{ activeFileName }}.{{ activeExtendName }}</div>
      <div class="opera-btn-group">
        <el-input-number v-model="inputActiveIndex" :min="1" :max="imgReviewList.length" size="mini"></el-input-number>
        <span class="split-line">/</span>{{ imgReviewList.length }}
      </div>
      <div class="tool-wrapper">
        <i class="item el-icon-refresh-right" title="向右旋转" @click="rotateImg"></i>
        <a
          class="item download-link"
          target="_blank"
          :href="activeDownloadLink"
          :download="activeFileName + '.' + activeExtendName"
        >
          <i class="el-icon-download" title="保存到本地"></i>
        </a>
        <el-tooltip effect="dark" placement="bottom">
          <div slot="content">
            操作提示：<br />
            点击图片以外的区域可退出查看；<br />
            按Esc键可退出查看；<br />
            鼠标滚轮可放大缩小图片
          </div>
          <div class="item text-wrapper">
            <span class="text">操作提示</span>
            <i class="el-icon-question"></i>
          </div>
        </el-tooltip>
      </div>
    </div>
    <!-- 大图查看 -->
    <img
      class="img-large"
      ref="imgLarge"
      v-for="(item, index) in imgReviewList"
      :key="index"
      :src="item.fileUrl"
      v-show="index === activeIndex"
    />
    <!-- 左右切换图标 -->
    <i class="pre-icon el-icon-arrow-left" title="上一张" v-show="activeIndex > 0" @click.stop="activeIndex--"></i>
    <i
      class="next-icon el-icon-arrow-right"
      title="下一张"
      v-show="activeIndex < imgReviewList.length - 1"
      @click.stop="activeIndex++"
    ></i>
    <!-- 底部显示放大缩小比例 -->
    <div class="zoom-bar">
      <el-slider
        v-model="imgZoom"
        :min="imgZoomMin"
        :max="imgZoomMax"
        :format-tooltip="formatZoom"
        @input="changeZoom"
      ></el-slider>
      <div class="zoom-count">{{ imgZoom }}%</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ImgReview',
  data() {
    return {
      rotate: 0, //  旋转角度
      activeIndex: 0, //  当前图片索引 从 0 开始
      imgZoom: 40, //  图片缩放比例
      imgZoomMin: 1, //  图片缩放最小比例
      imgZoomMax: 200 //  图片缩放最大比例
    }
  },
  computed: {
    // 图片查看组件是否显示
    imgReviewVisible() {
      return this.$store.state.imgReview.imgReviewVisible
    },
    // 图片列表
    imgReviewList() {
      return this.$store.state.imgReview.imgReviewList
    },
    // 默认显示的图片索引 从 0 开始
    defaultActiveIndex() {
      return this.$store.state.imgReview.defaultActiveIndex
    },
    // 当前显示的图片名称
    activeFileName() {
      return this.imgReviewList[this.activeIndex].fileName
    },
    // 当前显示的图片扩展名
    activeExtendName() {
      return this.imgReviewList[this.activeIndex].extendName
    },
    // 对用户而言 显示的图片索引 从 1 开始 顶部栏输入框控制此值变化
    inputActiveIndex: {
      get() {
        return this.activeIndex + 1
      },
      set(value) {
        this.activeIndex = value - 1
      }
    },
    // 当前显示的图片下载链接
    activeDownloadLink() {
      return this.imgReviewList[this.activeIndex].downloadLink
    }
  },
  watch: {
    // 监听 图片查看组件 显隐状态变化
    imgReviewVisible(val) {
      let body = document.querySelector('body')
      if (val) {
        this.activeIndex = this.defaultActiveIndex
        // 挂在body下，防止组件元素有样式transform而使position: fixed失效
        body.appendChild(this.$el)
        body.style.overflow = 'hidden'
        // 添加键盘Esc事件
        this.$nextTick(() => {
          document.addEventListener('keyup', (e) => {
            if (e.keyCode === 27) {
              this.closeImgReview()
            }
          })
        })
        this.$nextTick(() => {
          this.$refs.imgLarge[this.activeIndex].style.zoom = '40%'
        })
      } else {
        body.style.overflow = 'auto'
        document.removeEventListener('keyup', (e) => {
          if (e.keyCode === 27) {
            this.closeImgReview()
          }
        })
      }
    },
    // 监听 图片索引变化
    activeIndex(newValue) {
      this.rotate = 0
      this.$nextTick(() => {
        if (this.$refs.imgLarge[newValue].style.zoom) {
          this.imgZoom = Number(this.$refs.imgLarge[newValue].style.zoom.split('%')[0])
        } else {
          this.$refs.imgLarge[newValue].style.zoom = '40%'
          this.imgZoom = 40
        }
      })
    }
  },
  methods: {
    //  关闭图片预览
    closeImgReview() {
      this.$store.commit('setImgReviewData', { imgReviewVisible: false })
      this.rotate = 0
      this.$refs.imgLarge[this.activeIndex].style.transform = `rotate(${this.rotate}deg)`
    },
    // 格式化缩放数字 显示图片缩放比例
    formatZoom(value) {
      return value + '%'
    },
    // 图片缩放改变事件
    changeZoom(value) {
      if (this.$refs.imgLarge) {
        this.$refs.imgLarge[this.activeIndex].style.zoom = value + '%'
      }
    },
    // 缩放图片
    rollImg() {
      let zoom = parseInt(this.$refs.imgLarge[this.activeIndex].style.zoom) || 100
      zoom += event.wheelDelta / 12
      if (zoom >= this.imgZoomMin && zoom < this.imgZoomMax) {
        this.imgZoom = zoom
        this.$refs.imgLarge[this.activeIndex].style.zoom = zoom + '%'
      }
      return false
    },
    //  旋转图片
    rotateImg() {
      this.rotate += 90
      this.$refs.imgLarge[this.activeIndex].style.transform = `rotate(${this.rotate}deg)`
    }
  }
}
</script>

<style lang="stylus" scoped>
@import '../assets/style/varibles.styl'

.img-review-wrapper
  position fixed
  top 0
  right 0
  bottom 0
  left 0
  overflow auto
  width 100%
  height 100%
  z-index 2010
  text-align center
  display flex
  align-items center
  animation imgReviewAnimation 0.3s
  -webkit-animation imgReviewAnimation 0.3s /* Safari and Chrome */
  animation-iteration-count 0.3
  -webkit-animation-iteration-count 0.3
  animation-fill-mode forwards
  -webkit-animation-fill-mode forwards /* Safari 和 Chrome */
  @keyframes imgReviewAnimation
    0%
      background transparent
    100%
      background rgba(0, 0, 0, 0.8)
  @keyframes imgReviewAnimation
    0%
      background transparent
    100%
      background rgba(0, 0, 0, 0.8)
  .tip-wrapper
    position fixed
    top 0
    left 0
    z-index 2011
    background rgba(0, 0, 0, 0.5)
    padding 0 48px
    width calc(100% - 96px)
    height 48px
    line-height 48px
    color #fff
    font-size 16px
    display flex
    justify-content space-between
    .name
      flex 1
      padding-right 16px
      text-align left
      overflow hidden
      text-overflow ellipsis
      white-space nowrap
    .opera-btn-group
      width 100px
      display flex
      >>> .el-input-number
        width 40px
        .el-input-number__decrease,
        .el-input-number__increase
          display none
        .el-input__inner
          margin-top 14px
          background rgba(0, 0, 0, 0.5)
          height 20px
          line-height 20px
          padding 0
          font-size 16px
          color #fff
      .split-line
        margin 0 8px
    .tool-wrapper
      flex 1
      display flex
      justify-content flex-end
      .item
        margin-left 16px
        cursor pointer
        &:hover
          opacity 0.7
      .el-icon-refresh-right
        line-height 48px
        font-size 18px
      .download-link
        color inherit
        font-size 18px
      .text-wrapper
        margin-left 32px
        .text
          margin-right 8px
  .img-large
    margin 0 auto
    transition transform 0.5s
    -webkit-transition transform 0.5s /* Safari */
  .pre-icon,
  .next-icon
    font-size 60px
    color #fff
    position fixed
    top 50%
    cursor pointer
    &:hover
      opacity 0.7
  .pre-icon
    left 64px
  .next-icon
    right 64px
  .zoom-bar
    position fixed
    right 0
    bottom 20px
    left 0
    margin 0 auto
    width 600px
    display flex
    >>> .el-slider
      flex 1
      .el-slider__bar
        background $PrimaryText
      .el-slider__button
        border-color $PrimaryText
    .zoom-count
      width 60px
      height 38px
      line-height 38px
      text-align right
      color #fff
</style>
