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