vue.js 图片预览

Vue.js的图片预览的插件还是不少,但是找了半天还是没找到跟现在项目里能用得很顺手的,其实项目里图片预览功能很简单,点击放大,能双指缩放就可以了。部分vue.js的图片预览库都需要把图片资源单独拿出来进行预加载,这个项目比较特殊,图片属于数据内容的一部分,数据内容都是从服务器异步获取的HTML内容,异步加载完成html内容完成后,才能去给每个图片加上预览功能。

所以就只能自己根据需要添加图片预览功能了。

当然不是从零开始,可以借助一些移动端的触控库帮我们解决一些基础的触控事件,这里选用的是harmmer.js,选用这个库原因很简单,文档相对来说比较全面。

window.iv = {
  init: function () {
    var ivRoot = document.getElementById('iv-root')

    if (ivRoot) {
    } else {
      ivRoot = document.createElement('div')
      ivRoot.style.zIndex = 9999
      ivRoot.style.backgroundColor = 'rgba(0, 0, 0, 1)'
      ivRoot.style.position = 'fixed'
      ivRoot.style.top = '0'
      ivRoot.style.left = '0'
      ivRoot.style.right = '0'
      ivRoot.style.bottom = '0'
      ivRoot.style.display = 'none'
      ivRoot.id = 'iv-root'

      let ivImg = document.createElement('img')
      ivImg.id = 'iv-image'
      ivImg.style.position = 'absolute'
      ivRoot.appendChild(ivImg)

      document.body.appendChild(ivRoot)

      ivRoot.onclick = function () {
        this.style.display = 'none'
      }
    }
  },
  bind: function (node) {
    var _this = this
    var ivImg = document.getElementById('iv-image')
    var ivRoot = document.getElementById('iv-root')

    if (typeof (node) !== 'object') return

    node.onclick = function () {
      var nodeWidth = this.width
      var nodeHeight = this.height
      var position = _this.getPosition(nodeWidth, nodeHeight)
      var src = this.getAttribute('src')
      ivImg.style.width = position.width + 'px'
      ivImg.style.height = position.height + 'px'
      ivImg.style.top = position.top + 'px'
      ivImg.style.left = position.left + 'px'
      ivImg.src = src
      ivRoot.style.display = ''

      _this.bindSlide()
      _this.bindEnlarge()
    }
  },
  bindSlide: function () {
    var imageViewNode = document.getElementById('iv-image')
    var hammertime = new Hammer(imageViewNode)
    var _this = this

    // 滑动坐标
    var startPosition = {}
    var endPosition = {}
    let currentPosition = {}

    hammertime.on('panstart', function (ev) {
      startPosition = ev.center
      currentPosition = {
        left: _this.getStyleValue(imageViewNode, 'left'),
        top: _this.getStyleValue(imageViewNode, 'top')
      }
    })

    hammertime.on('panmove', function (ev) {
      let offset = { x: 0, y: 0 }
      let newPositon = {}

      endPosition = ev.center
      offset.x = endPosition.x - startPosition.x
      offset.y = endPosition.y - startPosition.y
      newPositon.left = currentPosition.left + offset.x
      newPositon.top = currentPosition.top + offset.y
      // vueThis.debugMsg = imageViewNode.style.left;

      imageViewNode.style.left = newPositon.left + 'px'
      imageViewNode.style.top = newPositon.top + 'px'
    })
  },
  bindEnlarge: function () {
    var imageViewNode = document.getElementById('iv-image')
    var hammertime = new Hammer(imageViewNode)
    var _this = this

    // 为该dom元素指定触屏移动事件
    hammertime.add(new Hammer.Pinch())
    var currentScale = 1
    hammertime.on('pinchstart', function (e) {
      // vueThis.debugMsg = JSON.stringify(e);

      currentScale = _this.getStyleValue(
        imageViewNode,
        'transform'
      )

      if (currentScale < 1) {
        currentScale = 1
      }
    })

    // 添加放大事件
    hammertime.on('pinchout', function (e) {
      var newScale = currentScale * e.scale
      imageViewNode.style.transform = `scale(${newScale})`
    })

    // 添加缩小事件
    hammertime.on('pinchin', function (e) {
      var newScale = currentScale * e.scale
      if (newScale < 1) {
        newScale = 1
      }
      imageViewNode.style.transform = `scale(${newScale})`
    })
  },
  getPosition: function (width, height) {
    let screenHeight = screen.height // 可视区域高
    let screenWidth = screen.width // 可是区域宽

    let displayHeight = height
    let displayWidth = width
    let displayLeft = 0
    let displayTop = 0
    // 适应宽度,调整高度
    displayWidth = screenWidth
    displayHeight = screenWidth * (height / width)
    displayTop = (screenHeight - displayHeight) / 2
    // 超过屏幕高度
    if (displayHeight > screenHeight) {
      // console.log("适应宽度时,超过可视高度!")
      displayHeight = screenHeight
      displayWidth = screenHeight * (width / height)
      displayTop = 0
      displayLeft = (screenWidth - displayWidth) / 2
    }

    console.log(`计算之后的宽高:width${displayWidth}, height:${displayHeight}`)
    console.log(`计算后的位置, left:${displayLeft}, top:${displayTop}`)

    return {
      top: displayTop,
      left: displayLeft,
       displayWidth,
      height: displayHeight
    }
  },
  getStyleValue: function (node, name) {
    let value = node.style[name]

    if (value) {
      if (value.indexOf('px') >= 0) {
        value = value.replace('px', '')
      } else if (value.indexOf('scale') >= 0) {
        value = value.replace('scale', '')
        value = value.replace('(', '')
        value = value.replace(')', '')
      }
      value = parseFloat(value)

      return value
    }

    return 0
  }
}

window.iv.init()

这里没有使用其他库,范例暂时只列举vue的环境

<template>
    <div class="imgs">
        <img src="../assets/images/001.jpg" class="testImage" />
        <img src="../assets/images/002.jpg" class="testImage" />
    </div>
</template>
<script>
require("../assets/js/hammer.min.js");
require("../assets/js/image-view");

export default {
  name: "Index",
  data() {
    return {};
  },
  mounted() {
    let nodes = document.getElementsByClassName("testImage");

    for (var index in nodes) {
      let currentNode = nodes[index];

      iv.bind(currentNode);
    }
  }
};
</script>

<style scoped>
.imgs {
   100%;
}

img {
   100%;
}
</style>

其他非vue的环境也可以直接引用harmmer.js后直接使用,功能比较简单。

 下载源代码,http://download.csdn.net/download/speedupnow/10169409

原文地址:https://www.cnblogs.com/stealth7/p/8084974.html