本功能是为了解决运营对后台管理系统中用户上传的各种角度和尺寸的图片难以浏览的问题,于是花了两天时间写了这个插件,给大家分享。
兼容现代浏览器,不兼容ie678,主要是一些效果无法实现。
带有图片查看器的常用功能,UI设计和交互灵感来源于google的picasa。
为了保证整体的清洁,界面没有使用任何图标,有需要的可以自行修改CSS。
不知道什么原因插不了iframe,DEMO。
效果图:
代码如下:
/** * 照片浏览 * -- * @author Lianer * @version 2015.06.11 * @description 带有常用照片查看功能,包括缩放、自适应、移动、切换、旋转、下载,ie9+ * @example * var pv=new PhotoView(); * pv.add(["1.jpg", "2.jpg", "3.jpg"]); // 追加列表 * pv.show(); // 显示 * pv.close(); // 关闭 * pv.aim(1); // 定位到指定位置 * pv.reset(); // 重置 */(function () { "use strict"; var PhotoView=window.PhotoView=function () { var createElement=function (type, className, parent) { var elem=document.createElement(type); if(className) elem.className=className; if(parent) parent.appendChild(elem); return elem; }; var bindWheel=function (elem, fn, cancelBubble) { if("onwheel" in document){ elem.onwheel=handler; } else if("onmousewheel" in document){ elem.onmousewheel=handler; } else{ return false; } return true; function handler(e) { e=window.event||e; var deltaX = e.deltaX || // wheel -e.wheelDeltaX || // onmousewheel 0; // Firefox,DOMMouseScroll不支持2D var deltaY = e.deltaY || // wheel -e.wheelDeltaY || // onmousewheel -e.wheelDelta || // 1D e.detail || // firefox,DOMMouseScroll 0; deltaX=deltaX>0?1:deltaX<0?-1:0; deltaY=deltaY>0?1:deltaY<0?-1:0; fn(deltaY, deltaX, e); if(cancelBubble){ if(e.PReventDefault) e.preventDefault(); if(e.stopPropagation) e.stopPropagation(); e.cancelBubble=true; e.returnValue=false; return false; } } }; var pv=function () { this.index=0; this.queue=[]; var elem=this.elem={}; // 外框 elem.wrap=createElement("div", "photoview photoview_" + pv.size++); elem.wrap.setAttribute("tabindex", "0"); // 容器 elem.container=createElement("div", "photoview-container", elem.wrap); // 缩放指数 elem.scaleValue=createElement("div", "photoview-scale-value", elem.container); elem.scaleValue.style.display="none"; // 预览 elem.view=createElement("div", "photoview-view", elem.container); elem.viewCache=createElement("img"); // 控制栏 elem.control=createElement("div", "photoview-control", elem.wrap); // 控制栏队列 elem.controlQueue=createElement("div", "photoview-control-queue", elem.control); // 编辑 elem.controlEdit=createElement("div", "photoview-control-edit", elem.control); // 放大 elem.scaleUp=createElement("div", "photoview-scale-up", elem.controlEdit); // 缩小 elem.scaleDown=createElement("div", "photoview-scale-down", elem.controlEdit); // 自适应 elem.scaleAdapt=createElement("div", "photoview-scale-adapt", elem.controlEdit); // 上一张 elem.prev=createElement("div", "photoview-prev", elem.controlEdit); // 下一张 elem.next=createElement("div", "photoview-next", elem.controlEdit); // 逆时针旋转 elem.rotateCCW=createElement("div", "photoview-rotate-ccw", elem.controlEdit); // 顺时针旋转 elem.rotateCW=createElement("div", "photoview-rotate-cw", elem.controlEdit); // 下载 if(window.Blob) elem.download=createElement("div", "photoview-download", elem.controlEdit); // 关闭 elem.close=createElement("div", "photoview-close", elem.wrap); elem.close.innerHTML="关闭"; document.body.appendChild(elem.wrap); this.$bind(); }; pv.prototype={ // control定位 aim: function (n) { var _this=this, elem=this.elem, queue=this.queue; if(n>queue.length-1){ n=queue.length; } else if(n<0){ n=0; } var target=elem.controlQueue.querySelectorAll("p"); if(target){ target=target[n]; } if(target){ var last=elem.controlQueue.querySelector(".active"); if(last){ last.className=""; } target.className="active"; elem.controlQueue.style.left=(elem.control.clientWidth/2-target.offsetLeft-target.offsetWidth/2)+"px"; this.$view(this.queue[n]); this.index=n; } return this; }, // 适应 $adapt: function () { var _this=this, elem=this.elem, target=this.queue[this.index], view=elem.view, img=elem.viewCache, container=elem.container, scale=target.scale; var imgSize={ width: img.width, height: img.height, rate: img.width/img.height }; var conSize={ width: container.clientWidth, height: container.clientHeight, rate: container.clientWidth/container.clientHeight }; if(target.scale==null){ var coverage=0.7; if(imgSize.rate>conSize.rate){ // 更宽 if(imgSize.width>conSize.width*coverage){ target.scale=conSize.width/imgSize.width*coverage; } else{ target.scale=1; } } else{ if(imgSize.height>conSize.height*coverage){ target.scale=conSize.height/imgSize.height*coverage; } else{ target.scale=1; } } } target.width=imgSize.width*target.scale; target.height=imgSize.height*target.scale; target.left=((conSize.width-imgSize.width*target.scale)/2+target.x); target.top=((conSize.height-imgSize.height*target.scale)/2+target.y); view.style.width=target.width+"px"; view.style.height=target.height+"px"; view.style.left=target.left + "px"; view.style.top=target.top + "px"; view.style.transform="rotate(" + target.rotate + "deg)"; }, // 追加列表 add: function () { var _this=this, elem=this.elem, queue=this.queue; var arg; for (var i = 0; arg=arguments[i]; i++) { if(!arg){ return false; } if(arg.length){ var a; for (var i = 0; a=arg[i]; i++) { checkType(a); } } else{ check(arg); } } function checkType(mixed) { if(typeof mixed==="string"){ var img=document.createElement("img"); img.src=mixed; add(img, null, null); } else if(mixed.nodeName&&mixed.nodeName.toLowerCase()==="img"){ add(mixed.getAttribute("data-source")||mixed.src, mixed.getAttribute("data-rotate")||null, mixed.getAttribute("data-scale")||null); } else{ return false; } } function add(src, rotate, scale) { var q={ src: src, // 图片路径 rotate: rotate||0, // 旋转角度 scale: scale, // 缩放比例,null时会通过adapt计算以contain x: 0, // x轴偏移 y: 0 // y轴偏移 }; queue.push(q); var p=createElement("p", null, elem.controlQueue), img=createElement("img"); p.style.cssText="opacity: 0;background-image: url(" + src + ");"; p.photoview={ index: queue.length-1 }; img.src=src; img.onload=function () { p.style.opacity=""; this.onload=nul
新闻热点
疑难解答