给图片查看器插件Magnify新增放大镜功能

article/2025/11/11 5:20:01

说实话Magnify图片查看器插件已经非常强大了,媲美Windows的图片查看器,但是,毕竟是开源插件,用起来简单,就是兼容性等各种bug问题。不过还好能用,自己优化一下就好。

在实际项目中,如果只是在页面简单的实现这个图片预览、放大、翻看等功能,这个插件就很完美了。废话不多说,看看简单的应用。

API应用案例:http://www.jq22.com/jquery-info17547

Git源码:https://github.com/nzbin/magnify


1.首先看页面部分:

1)前端引用:(第一行为图标样式,第二行为默认样式,第三行是我写的自定义样式(可不用))

<link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link rel="stylesheet" href="<%=path%>/static/common/magnify/dist/jquery.magnify.min.css" >
<link rel="stylesheet" href="<%=path%>/static/common/magnify/docs/css/self-black-theme.css" >
<script type="text/javascript" src="<%=path%>/static/common/magnify/dist/jquery.magnify.js"></script>

放大镜样式:

/*放大镜样式*/
/*Lets create the magnifying glass*/
.magnify-large {width: 132px; height: 132px;position: absolute;border-radius: 100%;z-index: 20;/*Multiple box shadows to achieve the glass effect*/
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85),0 0 4px 4px rgba(0, 0, 0, 0.25),inset 0 0 10px 2px rgba(0, 0, 0, 0.25);/*Lets load up the large image first*/
    /*background: url('./img/1.jpg') no-repeat;*/
    /*hide the glass by default*/
    display: none;
}

2)jsp页面标签引入:(默认在界面插入一个无图显示的图片,data-src存的大图,src存的小图,不过这里大小一样)

<div id="passImg" style="display: none;" ><img  data-show="default" data-caption="暂无图片" data-src="<%=path%>/static/images/notExistImg.jpg" src="<%=path%>/static/images/notExistImg.jpg">
</div>

2.js引用部分:

1)初始化图片查看器:

var options = {footToolbar: ['zoomIn','zoomOut','prev',//'fullscreen',
        'next',//'actualSize',
      'rotateLeft','rotateRight'
    ],i18n: {maximize: '',close: '',zoomIn: '放大',zoomOut: '缩小',prev: '上图',next: '下图',// fullscreen: '全屏查看',
           // actualSize: 'actual-size(Ctrl+Alt+0)',
            rotateLeft: '左旋转',rotateRight: '右旋转'
        },title: true,resizable: false,multiInstances: false,initEvent: 'click',initAnimation: true,fixedModalPos: false,fixedModalSize:true,showMagnify:true

}

$(function() {//初始化图片查看插件
    $('#passImg img').magnify(options);
});

2)触发查询对应记录的照片路径(支持多张显示,因为初始化查看器的有多张,所以每一张都要放入magnify容器):

//出入车图片弹窗
function getImg(imgUnid,dealerId) {var url =path + "/query/parkRecord/image";//清理原图片缓存
    $('[data-show=add]').remove();$.ajax({url : url,data : {"imgUnid" : imgUnid,"dealerId" : dealerId},type : "post",dataType : "json",success : function(returnData) {var imgObjectList=returnData.imgObjectList;if (null != returnData&&imgObjectList.length>0) {for(var i=0,j=1; i<imgObjectList.length;i++,j++){if (null != imgObjectList[i]&&null != imgObjectList[i].imgUrl && "" !=imgObjectList[i].imgUrl && imgObjectList[i].imgUrl != "null") {$("#passImg").append('<img data-show="add"  data-caption="'+j+'('+imgObjectList.length+')" data-src="'+imgObjectList[i].imgUrl+'"  src="'+imgObjectList[i].imgUrl+'" >');}}
              //初始化新增的图片对象
                 $('[data-show=add]').magnify(options);
} }, complete : function() { if( $( '[ data-show =add]'). length> 0){ $( '[ data-show =add]'). first(). click(); } else{ $( '#passImg img '). magnify( options); $( '[ data-show =default]'). click(); } } });}

3)完整对jquery.magnify.js进行改造,代码贴出如下:

;
(function(factory) {if (typeof define === 'function' && define.amd) {// AMD. Register as anonymous module.
    define(['jquery'], factory);} else if (typeof exports === 'object') {// Node / CommonJS
    factory(require('jquery'));} else {// Browser globals.
    factory(jQuery);}
})(function($) {'use strict';/**
 * Private Static Constants
 */
var CLICK_EVENT = 'click',RESIZE_EVENT = 'resize',KEYDOWN_EVENT = 'keydown',WHEEL_EVENT = 'wheel mousewheel DOMMouseScroll',TOUCH_START_EVENT = supportTouch() ? 'touchstart' : 'mousedown',TOUCH_MOVE_EVENT = supportTouch() ? 'touchmove' : 'mousemove',TOUCH_END_EVENT = supportTouch() ? 'touchend' : 'mouseup',EVENT_NS = '.magnify';/**
 * Private Vars
 */
var $W = $(window),$D = $(document),// plugin default options
  defaults = {draggable: true,resizable: true,movable: true,keyboard: true,title: true,modalWidth: 320,modalHeight: 320,fixedContent: true,fixedModalSize: false,initMaximized: false,gapThreshold: 0.02,ratioThreshold: 0.1,minRatio: 0.1,maxRatio: 16,headToolbar: ['maximize','close'
    ],footToolbar: ['zoomIn','zoomOut','prev','fullscreen','next','actualSize','rotateRight'
    ],icons: {minimize: 'fa fa-window-minimize',maximize: 'fa fa-window-maximize',close: 'fa fa-close',zoomIn: 'fa fa-search-plus',zoomOut: 'fa fa-search-minus',prev: 'fa fa-arrow-left',next: 'fa fa-arrow-right',fullscreen: 'fa fa-photo',actualSize: 'fa fa-arrows-alt',rotateLeft: 'fa fa-rotate-left',rotateRight: 'fa fa-rotate-right',loader: 'fa fa-spinner fa-pulse'
    },// lang: 'en',
    i18n: {minimize: 'minimize',maximize: 'maximize',close: 'close',zoomIn: 'zoom-in(+)',zoomOut: 'zoom-out(-)',prev: 'prev()',next: 'next()',fullscreen: 'fullscreen',actualSize: 'actual-size(Ctrl+Alt+0)',rotateLeft: 'rotate-left(Ctrl+,)',rotateRight: 'rotate-right(Ctrl+.)'
    },multiInstances: true,initEvent: 'click',initAnimation: true,fixedModalPos: false,showMagnify:false
    // beforeOpen:$.noop,
    // afterOpen:$.noop,
    // beforeClose:$.noop,
    // afterClose:$.noop
  },// jquery element of calling plugin
  jqEl = null,// image moving flag
  isMoving = false,// modal resizing flag
  isResizing = false,// modal open flag
  isOpened = false,// modal maximize flag
  isMaximized = false,// image rotate 90*(2n+1) flag
  isRotated = false,// image rotate angle
  rotateAngle = 0;/**
 * Magnify Class
 */
var Magnify = function (el, options) {var self = this;this.options = $.extend(true, {}, defaults, options);if (options && $.isArray(options.footToolbar)) {this.options.footToolbar = options.footToolbar;}if (options && $.isArray(options.headToolbar)) {this.options.headToolbar = options.headToolbar;}// As we have multiple instances,
  // so every instance has following variables.
  this.isOpened = false;this.isMaximized = false;this.isRotated = false;this.rotateAngle = 0;// Store image data in every instance
  this.imageData = {};// Store modal data in every instance
  this.modalData = {width: null,height: null,left: null,top: null
  };this.init(el, self.options);};/**
 * Mangify Prototype
 */
Magnify.prototype = {init: function (el, options) {// Get image src
    var imgSrc = this.getImgSrc(el);// Get image group
    this.groupName = null;var currentGroupName = $(el).attr('data-group'),groupList = $D.find('[data-group="' + currentGroupName + '"]');if (currentGroupName !== undefined) {this.groupName = currentGroupName;this.getImgGroup(groupList, imgSrc);} else {this.getImgGroup(jqEl.not('[data-group]'), imgSrc);}this.open();this.loadImg(imgSrc);//是否显示图片的放大镜效果
    supportShowMagnify(!this.options.initMaximized);if (this.options.showMagnify) {this.showMagnify(this.$stage, this.$image);}// draggable & movable & resizable
    if (this.options.draggable) {this.draggable(this.$magnify, this.$magnify, '.magnify-button');}if (this.options.movable) {this.movable(this.$stage, this.$image);}if (this.options.resizable) {this.resizable(this.$magnify, this.$stage, this.$image, this.options.modalWidth, this.options.modalHeight);}},creatBtns: function (toolbar, btns) {var btnsStr = '';$.each(toolbar, function (index, item) {btnsStr += btns[item];});return btnsStr;},creatTitle: function () {return (this.options.title ? '<div class="magnify-title"></div>' : '');},creatDOM: function () {var btnsTpl = {minimize: '<button class="magnify-button magnify-button-minimize" title="' + this.options.i18n.minimize + '">\
                      <i class="' + this.options.icons.minimize + '" aria-hidden="true"></i>\
                    </button>',maximize: '<button class="magnify-button magnify-button-maximize" title="' + this.options.i18n.maximize + '">\
                      <i class="' + this.options.icons.maximize + '" aria-hidden="true"></i>\
                    </button>',close: '<button class="magnify-button magnify-button-close" title="' + this.options.i18n.close + '">\
                      <i class="' + this.options.icons.close + '" aria-hidden="true"></i>\
                    </button>',zoomIn: '<button class="magnify-button magnify-button-zoom-in" title="' + this.options.i18n.zoomIn + '">\
                      <i class="' + this.options.icons.zoomIn + '" aria-hidden="true"></i>\
                    </button>',zoomOut: '<button class="magnify-button magnify-button-zoom-out" title="' + this.options.i18n.zoomOut + '">\
                      <i class="' + this.options.icons.zoomOut + '" aria-hidden="true"></i>\
                    </button>',prev: '<button class="magnify-button magnify-button-prev" title="' + this.options.i18n.prev + '">\
                      <i class="' + this.options.icons.prev + '" aria-hidden="true"></i>\
                    </button>',next: '<button class="magnify-button magnify-button-next" title="' + this.options.i18n.next + '">\
                      <i class="' + this.options.icons.next + '" aria-hidden="true"></i>\
                    </button>',fullscreen: '<button class="magnify-button magnify-button-fullscreen" title="' + this.options.i18n.fullscreen + '">\
                      <i class="' + this.options.icons.fullscreen + '" aria-hidden="true"></i>\
                    </button>',actualSize: '<button class="magnify-button magnify-button-actual-size" title="' + this.options.i18n.actualSize + '">\
                      <i class="' + this.options.icons.actualSize + '" aria-hidden="true"></i>\
                    </button>',rotateLeft: '<button class="magnify-button magnify-button-rotate-left" title="' + this.options.i18n.rotateLeft + '">\
                      <i class="' + this.options.icons.rotateLeft + '" aria-hidden="true"></i>\
                    </button>',rotateRight: '<button class="magnify-button magnify-button-rotate-right" title="' + this.options.i18n.rotateRight + '">\
                      <i class="' + this.options.icons.rotateRight + '" aria-hidden="true"></i>\
                    </button>'
    };// magnify base HTML
    var magnifyHTML = '<div class="magnify-modal">\
                        <div class="magnify-header">\
                          <div class="magnify-toolbar">' + this.creatBtns(this.options.headToolbar, btnsTpl) + '</div>' + this.creatTitle() + '\
                        </div>\
                        <div class="magnify-stage">\
                          <div class="magnify-large"></div>\
                          <img class="magnify-image" src="" alt="" />\
                        </div>\
                        <div class="magnify-footer">\
                          <div class="magnify-toolbar">' + this.creatBtns(this.options.footToolbar, btnsTpl) + '</div>\
                        </div>\
                      </div>';return magnifyHTML;},open: function () {if (!this.options.multiInstances) {$('.magnify-modal').eq(0).remove();}// Fixed modal position bug
    if (!$('.magnify-modal').length && this.options.fixedContent) {$('html').css({ 'overflow': 'hidden' });if (hasScrollbar()) {var scrollbarWidth = getScrollbarWidth();if (scrollbarWidth) {$('html').css({ 'padding-right': scrollbarWidth });}}}this.build();this.addEvent();this.setModalPos(this.$magnify);},build: function () {// Create magnify HTML string
    var magnifyHTML = this.creatDOM();// Make magnify HTML string to jQuery element
    var $magnify = $(magnifyHTML);// Get all magnify element
    this.$magnify = $magnify;this.$header = $magnify.find('.magnify-header');this.$stage = $magnify.find('.magnify-stage').addClass('stage-ready');this.$title = $magnify.find('.magnify-title');this.$image = $magnify.find('.magnify-image').addClass('image-ready');this.$close = $magnify.find('.magnify-button-close');this.$maximize = $magnify.find('.magnify-button-maximize');this.$minimize = $magnify.find('.magnify-button-minimize');this.$zoomIn = $magnify.find('.magnify-button-zoom-in');this.$zoomOut = $magnify.find('.magnify-button-zoom-out');this.$actualSize = $magnify.find('.magnify-button-actual-size');this.$fullscreen = $magnify.find('.magnify-button-fullscreen');this.$rotateLeft = $magnify.find('.magnify-button-rotate-left');this.$rotateRight = $magnify.find('.magnify-button-rotate-right');this.$prev = $magnify.find('.magnify-button-prev');this.$next = $magnify.find('.magnify-button-next');this.$large = $magnify.find('.magnify-large');$('body').append($magnify);},close: function (el) {// Remove instance
    this.$magnify.remove();this.isOpened = false;this.isMaximized = false;this.isRotated = false;this.rotateAngle = 0;// Fixed modal position bug
    if (!$('.magnify-modal').length && this.options.fixedContent) {$('html').css({ 'overflow': '', 'padding-right': '' });}// off events
    if (!$('.magnify-modal').length) {$D.off(KEYDOWN_EVENT + EVENT_NS);$W.off(RESIZE_EVENT + EVENT_NS);}},setModalPos: function (modal) {var winWidth = $W.width(),winHeight = $W.height(),scrollLeft = $D.scrollLeft(),scrollTop = $D.scrollTop();var modalWidth = this.options.modalWidth,modalHeight = this.options.modalHeight;// Set modal maximized when init
    if (this.options.initMaximized) {modal.addClass('magnify-maximize');modal.css({width: '100%',height: '100%',left: 0,top: 0
      });this.isOpened = true;this.isMaximized = true;} else {// Make the modal in windows center
      modal.css({width: modalWidth,height: modalHeight,left: (winWidth - modalWidth) / 2 + scrollLeft + 'px',top: (winHeight - modalHeight) / 2 + scrollTop + 'px'
      });}supportShowMagnify(!this.options.initMaximized);},setModalSize: function (img) {var self = this,winWidth = $W.width(),winHeight = $W.height(),scrollLeft = $D.scrollLeft(),scrollTop = $D.scrollTop();// stage css value
    var stageCSS = {left: this.$stage.css('left'),right: this.$stage.css('right'),top: this.$stage.css('top'),bottom: this.$stage.css('bottom'),borderLeft: this.$stage.css('border-left-width'),borderRight: this.$stage.css('border-right-width'),borderTop: this.$stage.css('border-top-width'),borderBottom: this.$stage.css('border-bottom-width')};// Modal size should calc with stage css value
    var modalWidth = img.width + getNumFromCSSValue(stageCSS.left) + getNumFromCSSValue(stageCSS.right) +getNumFromCSSValue(stageCSS.borderLeft) + getNumFromCSSValue(stageCSS.borderRight),modalHeight = img.height + getNumFromCSSValue(stageCSS.top) + getNumFromCSSValue(stageCSS.bottom) +getNumFromCSSValue(stageCSS.borderTop) + getNumFromCSSValue(stageCSS.borderBottom);var gapThreshold = (this.options.gapThreshold > 0 ? this.options.gapThreshold : 0) + 1,// modal scale to window
      scale = Math.min(winWidth / (modalWidth * gapThreshold), winHeight / (modalHeight * gapThreshold), 1);var minWidth = Math.max(modalWidth * scale, this.options.modalWidth),minHeight = Math.max(modalHeight * scale, this.options.modalHeight);minWidth = this.options.fixedModalSize ? this.options.modalWidth : Math.round(minWidth);minHeight = this.options.fixedModalSize ? this.options.modalHeight : Math.round(minHeight);var modalCSSObj = {width: minWidth + 'px',height: minHeight + 'px',left: (winWidth - minWidth) / 2 + scrollLeft + 'px',top: (winHeight - minHeight) / 2 + scrollTop + 'px'
    };// Add modal init animation
    if (this.options.initAnimation) {this.$magnify.animate(modalCSSObj, function () {self.setImageSize(img);});} else {this.$magnify.css(modalCSSObj);this.setImageSize(img);}this.isOpened = true;},setImageSize: function (img) {var stageData = {w: this.$stage.width(),h: this.$stage.height()};// image scale to stage
    var scale = 1;if (!this.isRotated) {scale = Math.min(stageData.w / img.width, stageData.h / img.height, 1);} else {scale = Math.min(stageData.w / img.height, stageData.h / img.width, 1);}this.$image.css({width: Math.ceil(img.width * scale) + 'px',height: Math.ceil(img.height * scale) + 'px',left: (stageData.w - Math.ceil(img.width * scale)) / 2 + 'px',top: (stageData.h - Math.ceil(img.height * scale)) / 2 + 'px'
    });// Store image initial data
    $.extend(this.imageData, {width: img.width * scale,height: img.height * scale,left: (stageData.w - img.width * scale) / 2,top: (stageData.h - img.height * scale) / 2
    });// Set grab cursor
    setGrabCursor({ w: this.$image.width(), h: this.$image.height() },{ w: this.$stage.width(), h: this.$stage.height() },this.$stage,this.isRotated
    );// loader end
    this.$magnify.find('.magnify-loader').remove();// Add image init animation
    if (this.options.initAnimation) {this.$image.fadeIn();}},loadImg: function (imgSrc) {var self = this;var loaderHTML = '<div class="magnify-loader"><i class="' + this.options.icons.loader + '"></i></div>';// loader start
    this.$magnify.append(loaderHTML);if (this.options.initAnimation) {this.$image.hide();}this.$image.attr('src', imgSrc);preloadImg(imgSrc, function (img) {// Store original data
      self.imageData = {originalWidth: img.width,originalHeight: img.height
      };if (self.isMaximized || (self.isOpened && self.options.fixedModalPos)) {self.setImageSize(img);} else {self.setModalSize(img);}self.$stage.removeClass('stage-ready');self.$image.removeClass('image-ready');}, function () {// loader end
      self.$magnify.find('.magnify-loader').remove();});if (this.options.title) {this.setImgTitle(imgSrc);}},getImgGroup: function (list, imgSrc) {var self = this;self.groupData = [];$(list).each(function (index, item) {var src = self.getImgSrc(this);self.groupData.push({src: src,caption: $(this).attr('data-caption')});// Get image index
      if (imgSrc === src) {self.groupIndex = index;}});},setImgTitle: function (url) {var index = this.groupIndex,caption = this.groupData[index].caption,caption = caption ? caption : getImageNameFromUrl(url);this.$title.text(caption);},getImgSrc: function (el) {// Get data-src as image src at first
    var src = $(el).attr('data-src') ? $(el).attr('data-src') : $(el).attr('href');return src;},jump: function (index) {this.groupIndex = this.groupIndex + index;this.jumpTo(this.groupIndex);},jumpTo: function (index) {index = index % this.groupData.length;if (index >= 0) {index = index % this.groupData.length;} else if (index < 0) {index = (this.groupData.length + index) % this.groupData.length;}this.groupIndex = index;this.loadImg(this.groupData[index].src);if (this.isMaximized) {//去除放大镜显示效果
        this.$large.removeClass('magnify-large');}else{//large赋背景图
        this.showMagnify(this.$stage, this.$image);}},wheel: function (e) {e.preventDefault();var delta = 1;if (e.originalEvent.deltaY) {delta = e.originalEvent.deltaY > 0 ? 1 : -1;} else if (e.originalEvent.wheelDelta) {delta = -e.originalEvent.wheelDelta / 120;} else if (e.originalEvent.detail) {delta = e.originalEvent.detail > 0 ? 1 : -1;}// ratio threshold
    var ratio = -delta * this.options.ratioThreshold;// mouse point position relative to stage
    var pointer = {x: e.originalEvent.clientX - this.$stage.offset().left + $D.scrollLeft(),y: e.originalEvent.clientY - this.$stage.offset().top + $D.scrollTop()};this.zoom(ratio, pointer, e);},zoom: function (ratio, origin, e) {// zoom out & zoom in
    ratio = ratio < 0 ? (1 / (1 - ratio)) : (1 + ratio);if (ratio > 0.95 && ratio < 1.05) {ratio = 1;}ratio = this.$image.width() / this.imageData.originalWidth * ratio;// min image size
    ratio = Math.max(ratio, this.options.minRatio);// max image size
    ratio = Math.min(ratio, this.options.maxRatio);this.zoomTo(ratio, origin, e);},zoomTo: function (ratio, origin, e) {var $image = this.$image,$stage = this.$stage,imgData = {w: this.imageData.width,h: this.imageData.height,x: this.imageData.left,y: this.imageData.top
      };// image stage position
    // We will use it to calc the relative position of image
    var stageData = {w: $stage.width(),h: $stage.height(),x: $stage.offset().left,y: $stage.offset().top
    };var newWidth = this.imageData.originalWidth * ratio,newHeight = this.imageData.originalHeight * ratio,// Think about it for a while ~~~
      newLeft = origin.x - (origin.x - imgData.x) / imgData.w * newWidth,newTop = origin.y - (origin.y - imgData.y) / imgData.h * newHeight;// δ is the difference between image new width and new height
    var δ = !this.isRotated ? 0 : (newWidth - newHeight) / 2,imgNewWidth = !this.isRotated ? newWidth : newHeight,imgNewHeight = !this.isRotated ? newHeight : newWidth;var offsetX = stageData.w - newWidth,offsetY = stageData.h - newHeight;// zoom out & zoom in condition
    // It's important and it takes me a lot of time to get it
    // The conditions with image rotate 90 degree drive me crazy alomst!
    if (imgNewHeight <= stageData.h) {newTop = (stageData.h - newHeight) / 2;} else {newTop = newTop > δ ? δ : (newTop > (offsetY - δ) ? newTop : (offsetY - δ));}if (imgNewWidth <= stageData.w) {newLeft = (stageData.w - newWidth) / 2;} else {newLeft = newLeft > -δ ? -δ : (newLeft > (offsetX + δ) ? newLeft : (offsetX + δ));}$image.css({width: Math.round(newWidth) + 'px',height: Math.round(newHeight) + 'px',left: Math.round(newLeft) + 'px',top: Math.round(newTop) + 'px'
    });// Update image initial data
    $.extend(this.imageData, {width: newWidth,height: newHeight,left: newLeft,top: newTop
    });// Set grab cursor
    setGrabCursor({ w: Math.round(imgNewWidth), h: Math.round(imgNewHeight) },{ w: stageData.w, h: stageData.h },this.$stage
    );},rotate: function (angle) {this.rotateAngle = this.rotateAngle + angle;if ((this.rotateAngle / 90) % 2 === 0) {this.isRotated = false;} else {this.isRotated = true;}this.rotateTo(this.rotateAngle);},rotateTo: function (angle) {var self = this;this.$image.css({transform: 'rotate(' + angle + 'deg)'
    });this.setImageSize({ width: this.imageData.originalWidth, height: this.imageData.originalHeight });// Remove grab cursor when rotate
    this.$stage.removeClass('is-grab');},resize: function () {var self = this;var resizeHandler = throttle(function () {if (self.isOpened) {if (self.isMaximized) {self.setImageSize({ width: self.imageData.originalWidth, height: self.imageData.originalHeight });} else {self.setModalSize({ width: self.imageData.originalWidth, height: self.imageData.originalHeight });}}}, 500);return resizeHandler;},maximize: function () {var self = this;if (!this.isMaximized) {//去除放大镜显示效果
        this.$large.removeClass('magnify-large');// Store modal data before maximize
      this.modalData = {width: this.$magnify.width(),height: this.$magnify.height(),left: this.$magnify.offset().left,top: this.$magnify.offset().top
      };this.$magnify.addClass('magnify-maximize');this.$magnify.css({width: '100%',height: '100%',left: 0,top: 0
      });this.isMaximized = true;} else {//增加放大镜显示效果
      this.$large.addClass('magnify-large');this.$magnify.removeClass('magnify-maximize');this.$magnify.css({width: this.modalData.width ? this.modalData.width : this.options.modalWidth,height: this.modalData.height ? this.modalData.height : this.options.modalHeight,left: this.modalData.left ? this.modalData.left : ($W.width() - this.options.modalWidth) / 2 + $D.scrollLeft(),top: this.modalData.top ? this.modalData.top : ($W.height() - this.options.modalHeight) / 2 + $D.scrollTop()});this.isMaximized = false;}this.setImageSize({ width: this.imageData.originalWidth, height: this.imageData.originalHeight });},fullscreen: function () {requestFullscreen(this.$magnify[0]);},keydown: function (e) {var self = this;if (!this.options.keyboard) {return false;}var keyCode = e.keyCode || e.which || e.charCode,ctrlKey = e.ctrlKey || e.metaKey,altKey = e.altKey || e.metaKey;switch (keyCode) {//       case 37:self.jump(-1);break;//       case 39:self.jump(1);break;// +
      case 187:self.zoom(self.options.ratioThreshold * 3, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);break;// -
      case 189:self.zoom(-self.options.ratioThreshold * 3, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);break;// + Firefox
      case 61:self.zoom(self.options.ratioThreshold * 3, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);break;// - Firefox
      case 173:self.zoom(-self.options.ratioThreshold * 3, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);break;// ctrl + alt + 0
      case 48:if (ctrlKey && altKey) {self.zoomTo(1, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);}break;// ctrl + ,
      case 188:if (ctrlKey) {self.rotate(-90);}break;// ctrl + .
      case 190:if (ctrlKey) {self.rotate(90);}break;default:}},addEvent: function () {var self = this;this.$close.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function (e) {self.close();});this.$stage.off(WHEEL_EVENT + EVENT_NS).on(WHEEL_EVENT + EVENT_NS, function (e) {self.wheel(e);});this.$zoomIn.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function (e) {self.zoom(self.options.ratioThreshold * 3, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);});this.$zoomOut.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function (e) {self.zoom(-self.options.ratioThreshold * 3, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);});this.$actualSize.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function (e) {self.zoomTo(1, { x: self.$stage.width() / 2, y: self.$stage.height() / 2 }, e);});this.$prev.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function () {self.jump(-1);});this.$fullscreen.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function () {self.fullscreen();});this.$next.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function () {self.jump(1);});this.$rotateLeft.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function () {self.rotate(-90);});this.$rotateRight.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function () {self.rotate(90);});this.$maximize.off(CLICK_EVENT + EVENT_NS).on(CLICK_EVENT + EVENT_NS, function () {self.maximize();});$D.off(KEYDOWN_EVENT + EVENT_NS).on(KEYDOWN_EVENT + EVENT_NS, function (e) {self.keydown(e);});$W.on(RESIZE_EVENT + EVENT_NS, self.resize());}};/**
 * Public Static Functions
 */
$.magnify = {instance: Magnify.prototype
};$.fn.magnify = function (options) {jqEl = $(this);// Convert a numeric string into a number
  for (var key in options) {if (typeof (options[key]) === 'string' && !isNaN(options[key])) {options[key] = parseFloat(options[key])}}// Get init event, 'click' or 'dblclick'
  var opts = $.extend(true, {}, defaults, options);if (typeof options === 'string') {// $(this).data('magnify')[options]();

  } else {if (opts.initEvent === 'dblclick') {jqEl.off('click' + EVENT_NS).on('click' + EVENT_NS, function (e) {e.preventDefault();// This will stop triggering data-api event
        e.stopPropagation();});}jqEl.off(opts.initEvent + EVENT_NS).on(opts.initEvent + EVENT_NS, function (e) {e.preventDefault();// This will stop triggering data-api event
      e.stopPropagation();$(this).data('magnify', new Magnify(this, options));});}return jqEl;};/**
 * MAGNIFY DATA-API
 */
$D.on(CLICK_EVENT + EVENT_NS, '[data-magnify]', function (e) {jqEl = $('[data-magnify]');e.preventDefault();$(this).data('magnify', new Magnify(this, {}));});/**
 * [draggable]
 * @param  {[Object]} modal       [the modal element]
 * @param  {[Object]} dragHandle  [the handle element when dragging]
 * @param  {[Object]} dragCancel  [the cancel element when dragging]
 */

var draggable = function (modal, dragHandle, dragCancel) {var self = this;var isDragging = false;var startX = 0,startY = 0,left = 0,top = 0;var dragStart = function (e) {var e = e || window.event;// e.preventDefault();

    // Get clicked button
    var elemCancel = $(e.target).closest(dragCancel);// Stop modal moving when click buttons
    if (elemCancel.length) {return true;}isDragging = true;startX = e.type === 'touchstart' ? e.originalEvent.targetTouches[0].pageX : e.clientX;startY = e.type === 'touchstart' ? e.originalEvent.targetTouches[0].pageY : e.clientY;left = $(modal).offset().left;top = $(modal).offset().top;$D.on(TOUCH_MOVE_EVENT + EVENT_NS, dragMove).on(TOUCH_END_EVENT + EVENT_NS, dragEnd);};var dragMove = function (e) {var e = e || window.event;e.preventDefault();if (isDragging && !isMoving && !isResizing && !self.isMaximized) {var endX = e.type === 'touchmove' ? e.originalEvent.targetTouches[0].pageX : e.clientX,endY = e.type === 'touchmove' ? e.originalEvent.targetTouches[0].pageY : e.clientY,relativeX = endX - startX,relativeY = endY - startY;$(modal).css({left: relativeX + left + 'px',top: relativeY + top + 'px'
      });}};var dragEnd = function (e) {$D.off(TOUCH_MOVE_EVENT + EVENT_NS, dragMove).off(TOUCH_END_EVENT + EVENT_NS, dragEnd);isDragging = false;};$(dragHandle).on(TOUCH_START_EVENT + EVENT_NS, dragStart);};// Add to Magnify Prototype
$.extend(Magnify.prototype, {draggable: draggable
});/**
 * --------------------------------------
 * 1.no movable
 * 2.vertical movable
 * 3.horizontal movable
 * 4.vertical & horizontal movable
 * --------------------------------------
 *
 * [image movable]
 * @param  {[Object]} stage   [the stage element]
 * @param  {[Object]} image   [the image element]
 */

var movable = function (stage, image) {var self = this;var isDragging = false;var startX = 0,startY = 0,left = 0,top = 0,widthDiff = 0,heightDiff = 0,δ = 0;var dragStart = function (e) {var e = e || window.event;e.preventDefault();var imageWidth = $(image).width(),imageHeight = $(image).height(),stageWidth = $(stage).width(),stageHeight = $(stage).height();startX = e.type === 'touchstart' ? e.originalEvent.targetTouches[0].pageX : e.clientX;startY = e.type === 'touchstart' ? e.originalEvent.targetTouches[0].pageY : e.clientY;// δ is the difference between image width and height
    δ = !self.isRotated ? 0 : (imageWidth - imageHeight) / 2;// Width or height difference can be use to limit image right or top position
    widthDiff = !self.isRotated ? (imageWidth - stageWidth) : (imageHeight - stageWidth);heightDiff = !self.isRotated ? (imageHeight - stageHeight) : (imageWidth - stageHeight);// Modal can be dragging if image is smaller to stage
    isDragging = (widthDiff > 0 || heightDiff > 0) ? true : false;isMoving = (widthDiff > 0 || heightDiff > 0) ? true : false;// Reclac the element position when mousedown
    // Fixed the issue of stage with a border
    left = $(image).position().left - δ;top = $(image).position().top + δ;// Add grabbing cursor
    if (stage.hasClass('is-grab')) {$('html,body,.magnify-modal,.magnify-stage,.magnify-button,.magnify-resizable-handle').addClass('is-grabbing');}$D.on(TOUCH_MOVE_EVENT + EVENT_NS, dragMove).on(TOUCH_END_EVENT + EVENT_NS, dragEnd);};var dragMove = function (e) {var e = e || window.event;e.preventDefault();if (isDragging) {var endX = e.type === 'touchmove' ? e.originalEvent.targetTouches[0].pageX : e.clientX,endY = e.type === 'touchmove' ? e.originalEvent.targetTouches[0].pageY : e.clientY,relativeX = endX - startX,relativeY = endY - startY,newLeft = relativeX + left,newTop = relativeY + top;// vertical limit
      if (heightDiff > 0) {if ((relativeY + top) > δ) {newTop = δ;} else if ((relativeY + top) < -heightDiff + δ) {newTop = -heightDiff + δ;}} else {newTop = top;}// horizontal limit
      if (widthDiff > 0) {if ((relativeX + left) > -δ) {newLeft = -δ;} else if ((relativeX + left) < -widthDiff - δ) {newLeft = -widthDiff - δ;}} else {newLeft = left;}$(image).css({left: newLeft + 'px',top: newTop + 'px'
      });// Update image initial data
      $.extend(self.imageData, {left: newLeft,top: newTop
      });}};var dragEnd = function (e) {$D.off(TOUCH_MOVE_EVENT + EVENT_NS, dragMove).off(TOUCH_END_EVENT + EVENT_NS, dragEnd);isDragging = false;isMoving = false;// Remove grabbing cursor
    $('html,body,.magnify-modal,.magnify-stage,.magnify-button,.magnify-resizable-handle').removeClass('is-grabbing');};$(stage).on(TOUCH_START_EVENT + EVENT_NS, dragStart);};// Add to Magnify Prototype
$.extend(Magnify.prototype, {movable: movable
});/**
 * ------------------------------
 * 1.modal resizable
 * 2.keep image in stage center
 * 3.~
 * ------------------------------
 *
 * [resizable]
 * @param  {[Object]} modal       [the modal element]
 * @param  {[Object]} stage       [the stage element]
 * @param  {[Object]} image       [the image element]
 * @param  {[Number]} minWidth    [the option of modalWidth]
 * @param  {[Number]} minHeight   [the option of modalHeight]
 */

var resizable = function (modal, stage, image, minWidth, minHeight) {var self = this;var resizableHandleE = $('<div class="magnify-resizable-handle magnify-resizable-handle-e"></div>'),resizableHandleW = $('<div class="magnify-resizable-handle magnify-resizable-handle-w"></div>'),resizableHandleS = $('<div class="magnify-resizable-handle magnify-resizable-handle-s"></div>'),resizableHandleN = $('<div class="magnify-resizable-handle magnify-resizable-handle-n"></div>'),resizableHandleSE = $('<div class="magnify-resizable-handle magnify-resizable-handle-se"></div>'),resizableHandleSW = $('<div class="magnify-resizable-handle magnify-resizable-handle-sw"></div>'),resizableHandleNE = $('<div class="magnify-resizable-handle magnify-resizable-handle-ne"></div>'),resizableHandleNW = $('<div class="magnify-resizable-handle magnify-resizable-handle-nw"></div>');var resizableHandles = {'e': resizableHandleE,'s': resizableHandleS,'se': resizableHandleSE,'n': resizableHandleN,'w': resizableHandleW,'nw': resizableHandleNW,'ne': resizableHandleNE,'sw': resizableHandleSW
  };$(modal).append(resizableHandleE, resizableHandleW, resizableHandleS, resizableHandleN, resizableHandleSE, resizableHandleSW, resizableHandleNE, resizableHandleNW
  );var isDragging = false;var startX = 0,startY = 0,modalData = {w: 0,h: 0,l: 0,t: 0
    },stageData = {w: 0,h: 0,l: 0,t: 0
    },imageData = {w: 0,h: 0,l: 0,t: 0
    },// δ is the difference between image width and height
    δ = 0,imgWidth = 0,imgHeight = 0,direction = '';// modal CSS options
  var getModalOpts = function (dir, offsetX, offsetY) {// Modal should not move when its width to the minwidth
    var modalLeft = (-offsetX + modalData.w) > minWidth ? (offsetX + modalData.l) : (modalData.l + modalData.w - minWidth),modalTop = (-offsetY + modalData.h) > minHeight ? (offsetY + modalData.t) : (modalData.t + modalData.h - minHeight);var opts = {'e': {width: Math.max((offsetX + modalData.w), minWidth) + 'px'
      },'s': {height: Math.max((offsetY + modalData.h), minHeight) + 'px'
      },'se': {width: Math.max((offsetX + modalData.w), minWidth) + 'px',height: Math.max((offsetY + modalData.h), minHeight) + 'px'
      },'w': {width: Math.max((-offsetX + modalData.w), minWidth) + 'px',left: modalLeft + 'px'
      },'n': {height: Math.max((-offsetY + modalData.h), minHeight) + 'px',top: modalTop + 'px'
      },'nw': {width: Math.max((-offsetX + modalData.w), minWidth) + 'px',height: Math.max((-offsetY + modalData.h), minHeight) + 'px',top: modalTop + 'px',left: modalLeft + 'px'
      },'ne': {width: Math.max((offsetX + modalData.w), minWidth) + 'px',height: Math.max((-offsetY + modalData.h), minHeight) + 'px',top: modalTop + 'px'
      },'sw': {width: Math.max((-offsetX + modalData.w), minWidth) + 'px',height: Math.max((offsetY + modalData.h), minHeight) + 'px',left: modalLeft + 'px'
      }};return opts[dir];};// image CSS options
  var getImageOpts = function (dir, offsetX, offsetY) {// Image should not move when modal width to the min width
    // The minwidth is modal width, so we should clac the stage minwidth
    var widthDiff = (offsetX + modalData.w) > minWidth ? (stageData.w - imgWidth + offsetX - δ) : (minWidth - (modalData.w - stageData.w) - imgWidth - δ),heightDiff = (offsetY + modalData.h) > minHeight ? (stageData.h - imgHeight + offsetY + δ) : (minHeight - (modalData.h - stageData.h) - imgHeight + δ),widthDiff2 = (-offsetX + modalData.w) > minWidth ? (stageData.w - imgWidth - offsetX - δ) : (minWidth - (modalData.w - stageData.w) - imgWidth - δ),heightDiff2 = (-offsetY + modalData.h) > minHeight ? (stageData.h - imgHeight - offsetY + δ) : (minHeight - (modalData.h - stageData.h) - imgHeight + δ);// Get image position in dragging
    var imgLeft = $(image).position().left - δ,imgTop = $(image).position().top + δ;var opts = {'e': {left: widthDiff >= -δ ? ((widthDiff - δ) / 2 + 'px') : (imgLeft > widthDiff ? (imgLeft + 'px') : (widthDiff + 'px'))},'s': {top: heightDiff >= δ ? ((heightDiff + δ) / 2 + 'px') : (imgTop > heightDiff ? (imgTop + 'px') : (heightDiff + 'px'))},'se': {top: heightDiff >= δ ? ((heightDiff + δ) / 2 + 'px') : (imgTop > heightDiff ? (imgTop + 'px') : (heightDiff + 'px')),left: widthDiff >= -δ ? ((widthDiff - δ) / 2 + 'px') : (imgLeft > widthDiff ? (imgLeft + 'px') : (widthDiff + 'px'))},'w': {left: widthDiff2 >= -δ ? ((widthDiff2 - δ) / 2 + 'px') : (imgLeft > widthDiff2 ? (imgLeft + 'px') : (widthDiff2 + 'px'))},'n': {top: heightDiff2 >= δ ? ((heightDiff2 + δ) / 2 + 'px') : (imgTop > heightDiff2 ? (imgTop + 'px') : (heightDiff2 + 'px'))},'nw': {top: heightDiff2 >= δ ? ((heightDiff2 + δ) / 2 + 'px') : (imgTop > heightDiff2 ? (imgTop + 'px') : (heightDiff2 + 'px')),left: widthDiff2 >= -δ ? ((widthDiff2 - δ) / 2 + 'px') : (imgLeft > widthDiff2 ? (imgLeft + 'px') : (widthDiff2 + 'px'))},'ne': {top: heightDiff2 >= δ ? ((heightDiff2 + δ) / 2 + 'px') : (imgTop > heightDiff2 ? (imgTop + 'px') : (heightDiff2 + 'px')),left: widthDiff >= -δ ? ((widthDiff - δ) / 2 + 'px') : (imgLeft > widthDiff ? (imgLeft + 'px') : (widthDiff + 'px'))},'sw': {top: heightDiff >= δ ? ((heightDiff + δ) / 2 + 'px') : (imgTop > heightDiff ? (imgTop + 'px') : (heightDiff + 'px')),left: widthDiff2 >= -δ ? ((widthDiff2 - δ) / 2 + 'px') : (imgLeft > widthDiff2 ? (imgLeft + 'px') : (widthDiff2 + 'px'))}};return opts[dir];};var dragStart = function (dir, e) {var e = e || window.event;e.preventDefault();isDragging = true;isResizing = true;startX = e.type === 'touchstart' ? e.originalEvent.targetTouches[0].pageX : e.clientX;startY = e.type === 'touchstart' ? e.originalEvent.targetTouches[0].pageY : e.clientY;// Reclac the modal data when mousedown
    modalData = {w: $(modal).width(),h: $(modal).height(),l: $(modal).offset().left,t: $(modal).offset().top
    };stageData = {w: $(stage).width(),h: $(stage).height(),l: $(stage).offset().left,t: $(stage).offset().top
    };imageData = {w: $(image).width(),h: $(image).height(),l: $(image).position().left,t: $(image).position().top
    };// δ is the difference between image width and height
    δ = !self.isRotated ? 0 : (imageData.w - imageData.h) / 2;imgWidth = !self.isRotated ? imageData.w : imageData.h;imgHeight = !self.isRotated ? imageData.h : imageData.w;direction = dir;// Add resizable cursor
    $('html,body,.magnify-modal,.magnify-stage,.magnify-button').css('cursor', dir + '-resize');$D.on(TOUCH_MOVE_EVENT + EVENT_NS, dragMove).on(TOUCH_END_EVENT + EVENT_NS, dragEnd);};var dragMove = function (e) {var e = e || window.event;e.preventDefault();if (isDragging && !self.isMaximized) {var endX = e.type === 'touchmove' ? e.originalEvent.targetTouches[0].pageX : e.clientX,endY = e.type === 'touchmove' ? e.originalEvent.targetTouches[0].pageY : e.clientY,relativeX = endX - startX,relativeY = endY - startY;var modalOpts = getModalOpts(direction, relativeX, relativeY);$(modal).css(modalOpts);var imageOpts = getImageOpts(direction, relativeX, relativeY);$(image).css(imageOpts);}};var dragEnd = function (e) {$D.off(TOUCH_MOVE_EVENT + EVENT_NS, dragMove).off(TOUCH_END_EVENT + EVENT_NS, dragEnd);// Set grab cursor
    if (isResizing) {setGrabCursor({ w: imgWidth, h: imgHeight }, { w: $(stage).width(), h: $(stage).height() },stage);}isDragging = false;isResizing = false;// Remove resizable cursor
    $('html,body,.magnify-modal,.magnify-stage,.magnify-button').css('cursor', '');};$.each(resizableHandles, function (dir, handle) {handle.on(TOUCH_START_EVENT + EVENT_NS, function (e) {dragStart(dir, e);});});};// Add to Magnify Prototype
$.extend(Magnify.prototype, {resizable: resizable
});/**
 * Private Functions
 */

/**
 * [throttle]
 * @param  {Function} fn    [description]
 * @param  {[Number]} delay [description]
 * @return {Function}       [description]
 */
function throttle(fn, delay) {var timer = null;return function() {var context = this,args = arguments;clearTimeout(timer);timer = setTimeout(function() {fn.apply(context, args);}, delay);};}/**
 * [preloadImg]
 * @param  {[String]}  src      [image src]
 * @param  {Function}  success  [callbacks]
 * @param  {Function}  error    [callbacks]
 */
function preloadImg(src, success, error) {var img = new Image();img.onload = function() {success(img);};img.onerror = function() {error(img);};img.src = src;}/**
 * [requestFullscreen]
 * @param  {[type]} element [description]
 */
function requestFullscreen(element) {if (element.requestFullscreen) {element.requestFullscreen();} else if (element.mozRequestFullScreen) {element.mozRequestFullScreen();} else if (element.webkitRequestFullscreen) {element.webkitRequestFullscreen();} else if (element.msRequestFullscreen) {element.msRequestFullscreen();}
}/**
 * [exitFullscreen]
 */
function exitFullscreen() {if (document.exitFullscreen) {document.exitFullscreen();} else if (document.mozCancelFullScreen) {document.mozCancelFullScreen();} else if (document.webkitExitFullscreen) {document.webkitExitFullscreen();}
}/**
 * [getImageNameFromUrl]
 * @param  {[String]} url [description]
 * @return {[String]}     [description]
 */
function getImageNameFromUrl(url) {var reg = /^.*?\/*([^/?]*)\.[a-z]+(\?.+|$)/ig,txt = url.replace(reg, '$1');return txt;
}/**
 * [getNumFromCSSValue]
 * @param  {[String]} value [description]
 * @return {[Number]}       [description]
 */
function getNumFromCSSValue(value) {var reg = /\d+/g,arr = value.match(reg),num = parseFloat(arr[0]);return num;
}/**
 * [hasScrollbar]
 * @return {[Boolean]}       [description]
 */
function hasScrollbar() {return document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight);
}/**
 * [getScrollbarWidth]
 * @return {[Number]}       [description]
 */
function getScrollbarWidth() {var scrollDiv = document.createElement('div');scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';document.body.appendChild(scrollDiv);var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;document.body.removeChild(scrollDiv);return scrollbarWidth;}/**
 * [setGrabCursor]
 * @param {[Object]}  imageData    [description]
 * @param {[Object]}  stageData    [description]
 * @param {[Object]}  stage        [description]
 * @param {[Boolean]} isRotate     [description]
 */
function setGrabCursor(imageData, stageData, stage, isRotated) {var imageWidth = !isRotated ? imageData.w : imageData.h,imageHeight = !isRotated ? imageData.h : imageData.w;if (imageHeight > stageData.h || imageWidth > stageData.w) {stage.addClass('is-grab');}if (imageHeight <= stageData.h && imageWidth <= stageData.w) {stage.removeClass('is-grab');}
}/**
 * [supportTouch]
 * @return {[Boolean]}     [description]
 */
function supportTouch(){return !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch);
}//显示放大镜效果
var showMagnify = function (stage, image) {// The native width and height of the image.
    var defaults = {scaling: 0.3
    };// Combines object defaults and options.
    var options = $.extend(defaults, options),native_width = 0,native_height = 0,current_width = 0,current_height = 0,$small = stage,$large = $(".magnify-large");//stage新增一个largediv标签
    if($large.length<1){$small.append("<div  class='magnify-large'></div>");}var $large = $(".magnify-large");//large赋背景图
    $large.css("background-image","url("+image.attr('src')+")");$large.css("background-repeat","no-repeat");$(".magnify-modal").mousemove(function (e) {/* Act on the event */
        if (!native_width && !native_height) {var image_object = new Image();image_object.src = image.attr('src');// Gets the image native height and width.
            native_height = image_object.height;native_width = image_object.width;// Gets the image current height and width.
            current_height = $small.height();current_width = $small.width();} else {// Gets .maginfy offset coordinates.
            var magnify_offset = $(this).offset(),// Gets coordinates within .maginfy.
                mx = e.pageX - magnify_offset.left,my = e.pageY - magnify_offset.top;// Checks the mouse within .maginfy or not.
            if (mx < $(this).width() && my < $(this).height() && mx >0 && my > 0) {$large.fadeIn(100);} else {$large.fadeOut(100);} if ($large.is(":visible")) {/* Gets the large image coordinate by ratio
               small.x / small.width = large.x / large.width
               small.y / small.height = large.y / large.height
               then we need to keep pointer in the centre,
               so deduct the half of .large width and height.
            */
                var rx = Math.round(mx / $small.width() * native_width - $large.width() /2) * -1,ry = Math.round(my / $small.height() * native_height - $large.height()/2 ) * -1,bgp = rx + "px " + ry + "px",px = mx - $large.width() / 2,py = my - $large.height() / 2;$large.css({left: px,top: py,backgroundPosition: bgp
                });}}});};// Add to Magnify Prototype
  $.extend(Magnify.prototype, {showMagnify: showMagnify
  });/*是否显示放大镜效果*/
  function supportShowMagnify(flag){$(".magnify-large").css("display",function(flag){return flag ? "":"none";});}});

3.不足之处,目前只对maximize、prev、next三个按钮的操作进行放大镜的优化,其他按钮项目没有使用,各位猿友们用的时候需要优化一下就是放大镜只在小尺寸的界面显示,全屏或放大的时候就不需要用放大镜了,而且插件自带zoomIn,zoomOut,很方便;看一下完成后的效果如下:





http://chatgpt.dhexx.cn/article/rlrLVflH.shtml

相关文章

matlab利用magnify作图

首先&#xff0c;在命令窗口输入magnify&#xff1b; 然后&#xff0c;按住ctrl鼠标左键&#xff0c;选中要看的区域&#xff1b;想要放大局部图片时&#xff0c;我们可以放开ctrl,去点击键&#xff0c;进行放大&#xff1b; 最后&#xff0c;可以放开鼠标左键&#xff0c;点击…

Matlab制作局部放大图——magnify源码

Matlab制作局部放大图——magnify源码 写论文时会遇到需要用matlab做局部放大图的问题&#xff0c;好在matlab给出了magnify局部放大函数。下面是我做的一个小例子。 步骤&#xff1a; 1、先将magnify.m函数复制到包含图片的文件夹下。 2、plot出你要做局部放大图的图片&am…

VBA入门到进阶常用知识代码总结77

第77集 API基础 367、 API概述 API&#xff08;Application Programming Interface,应用程序编程接口&#xff09;是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力&#xff0c;而又无需访问源码&#xff0c;或理解内部工作机制的细节…

认识VBA------------------VBA基础

一、前言 在最近的工作中&#xff0c;有幸了解到VBA相关的知识&#xff0c;它主要是被应用于我们平时所使用的word和Excel中&#xff0c;主要用VBA代码来进行数据处理&#xff0c;在办公领域使用的比较广泛。通过一段时间的学习&#xff0c;总结了一些自己的理解和所学&#xf…

vba set语句_零基础学VBA编程06:什么是变量?

每天一篇原创Excel图文 微信公众号&#xff1a;Excel星球 NO.81-什么是变量&#xff1f; 作者&#xff1a;看见星光 微博&#xff1a;EXCELers / 知识星球&#xff1a;Excel 哈罗&#xff0c;大家好&#xff0c;我是星光&#xff0c;今天给大家聊一下编程中一个非常重要的概念—…

Excel VBA使用总结

Excel VBA 1.入门1.1开启VBA之旅 2.语法2.1清除单元格内容2.2vba设密码2.3以前的代码2.4使用正则2.5使用stack 都说世界上最好的语言就是PPT,工作报告&#xff0c;年度总结。。。。 到处都有它的身影&#xff0c;更是被高手设计的惟妙惟肖。 今天&#xff0c;我们不争第一&…

VBA录制宏知识整理

XIWENJIE_VBA基础简介之录制宏 A.录制宏的使用 一、什么是宏 VBA是 [Visual Basic](https://baike.baidu.com/item/Visual Basic)的一种宏语言,是在其桌面应用程序中执行通用的自动化(OLE)任务的编程语言。主要能用来扩展Windows的应用程序功能,特别是[Microsoft Office](…

excel VBA编程入门,自定义excel数据库模板生成sql语句

文章目录 VBA基础一.了解VBA1.进入vba2.认识宏 二. VBA编程1.hello world2.调出立即窗口和本地窗口3.debug显示4.注释5.数据类型5.变量的生命周期和定义域6.判断语句7.不等于<> , switch case 条件判断8.循环do while退出循环的语句 exit for退出循环的语句 exit do 9.数…

Excel Vba编程初探一

【场景】对EXCEL表格批量添加公式 【分析】 1、如何给单元格写值/公式 2、公式如何带变量 【Excel设置】 【实现】 0&#xff09;代码书写的地方 1&#xff09;代码 Sheet1被激活时触发 Private Sub Worksheet_Activate() Call SetFormula Call TestSetA1ToA10 End Sub函…

二 详解VBA编程是什么

详解VBA编程是什么 直到 90 年代早期,使应用程序自动化还是充满挑战性的领域.对每个需要自动化的应用程序,人们不得不学习一种不同的自动化语言.例如:可以用EXCEL的宏语言来使EXCEL自动化,使用WORD BASIC使WORD自动化,等等.微软决定让它开发出来的应用程序共享一种通用的自动化…

CSS入门(二)

CSS入门&#xff08;一&#xff09; https://blog.csdn.net/Veer_c/article/details/103882856 CSS文本属性和值&#xff1a; <style type"text/css"> div{/*设置字符间距*/letter-spacing:4px;/*设置文本的位置*/text-align:center;/*给文本设置上划/下划/中…

【前端学习】CSS入门

前端学习&#xff1a;CSS入门 文章目录 前端学习&#xff1a;CSS入门前言1、class011.我的第一个CSS2.导入方式3.基本选择器(1)ID选择器(2)标签选择器(3)类选择器 4.层次选择器5.结构伪类选择器6.属性选择器 2、class021.span/div2.字体样式3.文本样式4.超链接伪类5.列表 3、cl…

CSS入门必备基础(适合小白)

CSS入门必备基础&#xff08;适合小白&#xff09; 一、CSS是什么&#xff1f;1、什么是CSS&#xff1f;2、CSS有什么作用&#xff1f; 二、CSS核心基础1、CSS样式规则2、引入CSS的方法1)、行内式2)、内嵌式3)、链入式 2、CSS选择器1)、基础选择器2)、后代选择器3)、并集选择器…

网页搭建入门---CSS入门

目录 CSS基础语法 CSS选择器 选择器 基于关系的选择器 伪类 伪元素 优先级别 CSS样式 背景 文本 ​ 字体 链接 列表 表格 ​ CSS布局 CSS盒子模型 边框 内边距 外边距 CSS基础语法 为什么要使用CSS 样式定义如何显示HTML元素是为了解决内容与表现分离的问…

postcss入门

无需安装任何环境&#xff0c;即可在线体验未来的css生态系统。 一、什么是postcss 一个用 JavaScript 工具和插件转换 CSS 代码的工具&#xff0c;一套css的生态系统&#xff0c;通过组合插件的形式让我们更舒适的编写css。 二、它能做什么&#xff1f; 1.增强代码兼容性 …

CSS基础入门(详细总结笔记)

目录 1、CSS介绍 2、CSS引入方式 2.1、行内样式 2.2、内联样式 2.3、外联样式 2.4、样式的优先级 2.5、样式选择 3、CSS选择器 3.1、基本选择器 3.2、属性选择器 3.3、层级选择器 3.4、组合选择器 3.5、伪类选择器 3.6、通配符 3.7、选择器优先级 4、CSS盒子模…

CSS入门。(仅供参考)

文档出处部分Coogle和《原创》&#xff0c;如有雷同纯属巧合 《仅供参考》 首先说明以下内容是本人自己整理&#xff08;仅供参考&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff09; 首先浏览器我建议使用Googl…

零基础CSS入门教程(17)–表格样式

点此查看 所有教程、项目、源码导航 本文目录 1. 题外话2. 前言3. HTML表格边框4. CSS设定表格边框5. 设定列边框6. 折叠边框7. 表格尺寸8. 表格内边距9. 表格背景色10. 小结 1. 题外话 不知不觉&#xff0c;写到第40篇了。 可能已经是我写过的最长的系列文章了&#xff0c;虽…

一套完整的CSS入门教程

最近花了点时间&#xff0c;整理了一下之前的CSS博客文章&#xff0c;完成了这个CSS教程。也为我的个人网站&#xff0c;增加了一个教程模块。教程模块地址&#xff1a;请点击这里。教程地址&#xff1a;请点击这里。 该教程是一套完整的CSS入门教程&#xff0c;看了绝对不会…

CSS入门基础详解——笔记、案例

CSS入门学习 一、CSS简介 1、什么是css css:层叠样式表(英文全称&#xff1a;Cascading Style Sheets)是一种用来表现HTML&#xff08;标准通用标记语言的一个应用&#xff09;或XML&#xff08;标准通用标记语言的一个子集&#xff09;等文件样式的计算机语言。 2、CSS的作…