jquery.photo.gallery.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. /*
  2. * AppGo使用的 图片查看插件
  3. * Author : lufeng@bingosoft.net
  4. * Version: 1.0.0
  5. * Date : 2015/11/17
  6. */
  7. (function($) {
  8. var windowMargin = 8; // 加多边距的宽高,使得图片看起来有边框效果
  9. // 图片查看器
  10. $.fn.extend({
  11. photoGallery : function(options) {
  12. var isFirefox = navigator.userAgent.indexOf("Firefox") > -1;
  13. var MOUSEWHEEL_EVENT = isFirefox ? "DOMMouseScroll" : "mousewheel";
  14. var defaults = {
  15. // 图片缩放倍率
  16. ratio : 1.2,
  17. // 右下角缩略图宽度
  18. thumbnailsWidth : 180,
  19. // 右下角缩略图高度
  20. thumbnailsHeight : 120,
  21. // HTML模版
  22. template : {
  23. // 操作工具
  24. OPERTATION : '<div class="oper">' + '<span class="prev"><i class="icon_tool-prev"></i></span>' + '<span class="next"><i class="icon_tool-next"></i></span>' + '</div>' + '<div class="tool">' + '<div class="toolct">' + '<span class="oper_fullscreen" title="查看全屏"><i class="icon_tool-fullscreen"></i></span>' + '<span class="oper_bigger" title="放大图片"><i class="icon_tool-bigger"></i></span>' + '<span class="oper_smaller" title="缩小图片"><i class="icon_tool-smaller"></i></span>' + '<span class="oper_rotate" title="向右旋转"><i class="icon_tool-rotate"></i></span>' + '<span class="oper_download" title="关闭图片"><i class="icon_tool-download"></i></span>' + '</div>' + '</div>',
  25. // 缩略图
  26. THUMBNAILS : "<div class='thumbnails'>" + '<span class="thumbClose" title="关闭缩略图"><i class="icon_close-small"></i></span>' + '<img ondragstart="return false;"/>' + '<div class="thumbDrag"><span></span></div>' + "</div>",
  27. // 大图
  28. IMAGE : '<img class="image" ondragstart="return false;"/>'
  29. }
  30. };
  31. var o = $.extend(defaults, options), $gallery = $(this);
  32. $gallery.append(o.template.OPERTATION).append(o.template.THUMBNAILS);
  33. var $tool = $(this).find(".tool"), $fullscreen = $(this).find(".oper_fullscreen"), $bigger = $(this).find(".oper_bigger"), $smaller = $(this).find(".oper_smaller"), $rotate = $(this).find(".oper_rotate"), $download = $(this).find(".oper_download"), $prev = $(this).find(".prev"), $next = $(this).find(".next"), $thumbnails = $(this).find(".thumbnails"), $image, $thumbImg, imageWidth, imageHeight, imgRatio, dragX, dragY, cW, cH, w, h, isVertical, thumbX, thumbY;
  34. // 上一张
  35. $prev.on('click', function() {
  36. if (o.activeIndex > 0)
  37. o.activeIndex--;
  38. toggleImage();
  39. });
  40. // 下一张
  41. $next.on('click', function() {
  42. if (o.activeIndex < o.imgs.length - 1)
  43. o.activeIndex++;
  44. toggleImage();
  45. });
  46. // 缩略图
  47. $thumbnails.css({
  48. height : o.thumbnailsHeight,
  49. width : o.thumbnailsWidth
  50. }).on("mouseenter", function(e) {
  51. thumbX = -1;
  52. }).on("mousedown", function(e) {
  53. thumbX = e.pageX || e.clientX;
  54. thumbY = e.pageY || e.clientY;
  55. cW = document.body.clientWidth;
  56. cH = document.body.clientHeight;
  57. e.stopPropagation();
  58. }).on("mousemove", function(e) {
  59. if (thumbX > 0) {
  60. var nextDragX = e.pageX || e.clientX;
  61. var nextDragY = e.pageY || e.clientY;
  62. var $td = $(this).find(".thumbDrag"), imageWidth = $image.width(), imageHeight = $image.height(), thumbImgWidth = $thumbImg.width(), thumbImgHeight = $thumbImg.height(), left = parseFloat($td.css("left")) + (nextDragX - thumbX), top = parseFloat($td.css("top")) + (nextDragY - thumbY), w = $td.width(), h = $td.height(), it, il, maxL, maxT;
  63. if (isVertical) {
  64. thumbImgWidth = [ thumbImgHeight, thumbImgHeight = thumbImgWidth ][0];
  65. imageWidth = [ imageHeight, imageHeight = imageWidth ][0];
  66. }
  67. it = (o.thumbnailsHeight - thumbImgHeight) / 2, il = (o.thumbnailsWidth - thumbImgWidth) / 2, maxL = o.thumbnailsWidth - w - il - 2, // 减去2像素边框部分
  68. maxT = o.thumbnailsHeight - h - it - 2;
  69. if (left < il)
  70. left = il;
  71. else if (left > maxL)
  72. left = maxL;
  73. if (top < it)
  74. top = it;
  75. else if (top > maxT)
  76. top = maxT;
  77. $td.css({
  78. left : left,
  79. top : top
  80. })
  81. thumbX = nextDragX;
  82. thumbY = nextDragY;
  83. if (imageWidth < cW)
  84. left = (cW - imageWidth) / 2;
  85. else
  86. left = -imageWidth * (left - il) / thumbImgWidth;
  87. if (imageHeight < cH)
  88. top = (cH - imageHeight) / 2;
  89. else
  90. top = -imageHeight * (top - it) / thumbImgHeight;
  91. $image.offset({
  92. left : left,
  93. top : top
  94. });
  95. }
  96. }).on("mouseup", function(e) {
  97. thumbX = -1;
  98. });
  99. $thumbnails.find(".thumbClose").on("click", function() {
  100. $thumbnails.hide();
  101. });
  102. // 显示工具栏
  103. $gallery.on("mouseover", function(e) {
  104. $tool.show();
  105. }).on("mouseenter", function(e) {
  106. dragX = -1;
  107. }).on("mouseout", function(e) {
  108. $tool.hide();
  109. }).on("mousedown", function(e) {
  110. dragX = e.pageX || e.clientX;
  111. dragY = e.pageY || e.clientY;
  112. cW = document.body.clientWidth;
  113. cH = document.body.clientHeight;
  114. e.stopPropagation();
  115. }).on("mousemove", function(e) {
  116. if (dragX > 0) {
  117. var nextDragX = e.pageX || e.clientX;
  118. var nextDragY = e.pageY || e.clientY;
  119. var o = $image.offset(), left = o.left + (nextDragX - dragX), top = o.top + (nextDragY - dragY), w = $image.width(), h = $image.height();
  120. if (isVertical) {
  121. w = [ h, h = w ][0];
  122. }
  123. if (w > cW) {
  124. if (left > 0) {
  125. left = 0;
  126. } else if (left < cW - w) {
  127. left = cW - w;
  128. }
  129. } else {
  130. left = o.left;
  131. }
  132. if (h > cH) {
  133. if (top > 0) {
  134. top = 0;
  135. } else if (top < cH - h) {
  136. top = cH - h;
  137. }
  138. } else {
  139. top = o.top;
  140. }
  141. $image.offset({
  142. left : left,
  143. top : top
  144. });
  145. dragX = nextDragX;
  146. dragY = nextDragY;
  147. setThumbnails(); // 缩略图拖拽点
  148. }
  149. }).on("mouseup", function(e) {
  150. dragX = -1;
  151. });
  152. // 全屏
  153. var isMax, preWidth, preHeight, preTop, preLeft;
  154. $fullscreen.on("click", function() {
  155. var parentD = window.parent.document, J = $(parentD.getElementById("J_pg"));
  156. if (!isMax) {
  157. isMax = true;
  158. preWidth = document.body.clientWidth;
  159. preHeight = document.body.clientHeight;
  160. preTop = J.css("top");
  161. preLeft = J.css("left");
  162. J.css({
  163. top : 0,
  164. left : 0,
  165. width : parentD.body.clientWidth,
  166. height : parentD.body.clientHeight,
  167. });
  168. } else {
  169. isMax = false;
  170. J.css({
  171. top : preTop,
  172. left : preLeft,
  173. width : preWidth,
  174. height : preHeight
  175. });
  176. }
  177. });
  178. // 放大图片
  179. $bigger.on("click", function() {
  180. biggerImage();
  181. });
  182. // 缩小图片
  183. $smaller.on("click", function() {
  184. smallerImage();
  185. });
  186. // 旋转
  187. $rotate.on("click", function() {
  188. var rotateClass = $image.attr("class").match(/(rotate)(\d*)/);
  189. if (rotateClass) {
  190. var nextDeg = (rotateClass[2] * 1 + 90) % 360;
  191. $image.removeClass(rotateClass[0]).addClass("rotate" + nextDeg);
  192. $thumbImg.removeClass(rotateClass[0]).addClass("rotate" + nextDeg);
  193. resizeImage(nextDeg);
  194. resizeThumbImg(nextDeg);
  195. isVertical = nextDeg == 90 || nextDeg == 270;
  196. } else {
  197. $image.addClass("rotate90");
  198. $thumbImg.addClass("rotate90");
  199. resizeImage("90");
  200. resizeThumbImg("90");
  201. isVertical = true;
  202. }
  203. });
  204. // 下载
  205. $download.on("click", function() {
  206. var _parent = window.parent || window.top, _jg = _parent.document.getElementById("J_pg");
  207. $(_jg).remove();
  208. });
  209. $(window).on("resize", function() {
  210. setImagePosition();
  211. });
  212. if (document.attachEvent) {
  213. document.attachEvent("on" + MOUSEWHEEL_EVENT, function(e) {
  214. mouseWheelScroll(e);
  215. });
  216. } else if (document.addEventListener) {
  217. document.addEventListener(MOUSEWHEEL_EVENT, function(e) {
  218. mouseWheelScroll(e);
  219. }, true);
  220. }
  221. function mouseWheelScroll(e) {
  222. //var _delta = parseInt(e.wheelDelta || -e.detail);
  223. var _delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
  224. //阻止向上冒泡
  225. //e.stopPropagation();
  226. e.preventDefault();
  227. // 向上滚动
  228. if (_delta > 0) {
  229. biggerImage();
  230. }
  231. // 向下滚动
  232. else {
  233. smallerImage();
  234. }
  235. }
  236. // 键盘左右键
  237. document.onkeydown = function(e) {
  238. e = e || window.event;
  239. if (e.keyCode) {
  240. if (e.keyCode == 37) { // left
  241. if (o.activeIndex > 0)
  242. o.activeIndex--;
  243. toggleImage();
  244. }
  245. if (e.keyCode == 39) { // right
  246. if (o.activeIndex < o.imgs.length - 1)
  247. o.activeIndex++;
  248. toggleImage();
  249. }
  250. }
  251. };
  252. document.onmouseup = function(oEvent) {
  253. if (!oEvent)
  254. oEvent = window.event;
  255. if (oEvent.button == 2) {
  256. var _parent = window.parent || window.top, _jg = _parent.document.getElementById("J_pg");
  257. $(_jg).remove();
  258. }
  259. }
  260. function init() {
  261. toggleImage();
  262. $(o.imgs).each(function(i, img) {
  263. $(o.template.IMAGE).appendTo($gallery).attr("src", img.url).attr("index", i).css({
  264. width : img.imgWidth,
  265. height : img.imgHeight,
  266. left : (cW - img.imgWidth) / 2,
  267. top : (cH - img.imgHeight) / 2
  268. }).on("dblclick", function() {
  269. });
  270. ;
  271. });
  272. $image = $(".image[index='" + o.activeIndex + "']", $gallery).addClass("active");
  273. }
  274. function toggleImage() {
  275. imageWidth = o.imgs[o.activeIndex].imgWidth;
  276. imageHeight = o.imgs[o.activeIndex].imgHeight;
  277. imgRatio = imageWidth / imageHeight;
  278. cW = document.body.clientWidth;
  279. cH = document.body.clientHeight;
  280. $(".image", $gallery).removeClass("active");
  281. $image = $(".image[index='" + o.activeIndex + "']", $gallery).addClass("active").css({
  282. width : imageWidth,
  283. height : imageHeight
  284. }).removeClass("rotate0 rotate90 rotate180 rotate270");
  285. $thumbImg = $thumbnails.find("img").attr("src", o.imgs[o.activeIndex].url);
  286. $thumbnails.find("img").removeAttr("class").removeAttr("style");
  287. isVertical = false;
  288. $thumbnails.hide();
  289. $prev.addClass("active");
  290. $next.addClass("active");
  291. setImagePosition();
  292. }
  293. function biggerImage() {
  294. var w = $image.width(), h = $image.height(), nextW = w * o.ratio, nextH = h * o.ratio;
  295. if (nextW - w < 1)
  296. nextW = Math.ceil(nextW);
  297. var percent = (nextW / imageWidth * 100).toFixed(0);
  298. if (percent > 90 && percent < 110) {
  299. percent = 100;
  300. nextW = imageWidth;
  301. nextH = imageHeight;
  302. } else if (percent > 1600) {
  303. percent = 1600;
  304. nextW = imageWidth * 16;
  305. nextH = imageHeight * 16;
  306. }
  307. $image.width(nextW).height(nextH);
  308. setImagePosition();
  309. showPercentTip(percent);
  310. showThumbnails(nextW, nextH);
  311. }
  312. function smallerImage() {
  313. var w = $image.width(), h = $image.height(), nextW, nextH;
  314. var percent = (w / o.ratio / imageWidth * 100).toFixed(0);
  315. if (percent < 5) {
  316. percent = 5;
  317. nextW = imageWidth / 20;
  318. nextH = imageHeight / 20;
  319. } else if (percent > 90 && percent < 110) {
  320. percent = 100;
  321. nextW = imageWidth;
  322. nextH = imageHeight;
  323. } else {
  324. nextW = w / o.ratio;
  325. nextH = h / o.ratio;
  326. }
  327. $image.width(nextW).height(nextH);
  328. setImagePosition();
  329. showPercentTip(percent);
  330. showThumbnails(nextW, nextH);
  331. }
  332. // 显示缩略图
  333. function showThumbnails(width, height) {
  334. if (isVertical)
  335. width = [ height, height = width ][0];
  336. if (width > document.body.clientWidth || height > document.body.clientHeight) {
  337. $thumbnails.show();
  338. setThumbnails();
  339. } else {
  340. $thumbnails.hide();
  341. }
  342. }
  343. // 重置图片宽高
  344. function resizeImage(rotateDeg) {
  345. var mH = document.body.clientHeight - windowMargin, mW = document.body.clientWidth - windowMargin;
  346. if (rotateDeg == '90' || rotateDeg == '270') {
  347. mW = [ mH, mH = mW ][0];
  348. }
  349. var width, height;
  350. width = Math.min(imageWidth, mW);
  351. height = Math.min(imageHeight, mH);
  352. if (width / height > imgRatio) {
  353. width = height * imgRatio;
  354. } else {
  355. height = width / imgRatio;
  356. }
  357. $image.css({
  358. width : width,
  359. height : height
  360. });
  361. setImagePosition();
  362. }
  363. function resizeThumbImg(rotateDeg) {
  364. var maxW = o.thumbnailsWidth, maxH = o.thumbnailsHeight;
  365. if (rotateDeg == '90' || rotateDeg == '270') {
  366. maxW = [ maxH, maxH = maxW ][0];
  367. }
  368. $thumbImg.css({
  369. maxWidth : maxW,
  370. maxHeight : maxH
  371. });
  372. $thumbnails.hide();
  373. }
  374. // 显示百分比提示
  375. function showPercentTip(percent) {
  376. $gallery.find(".percentTip").remove();
  377. $("<div class='percentTip'><span>" + percent + "%</span></div>").appendTo($gallery).fadeOut(1500);
  378. }
  379. // 设置图片位置
  380. function setImagePosition() {
  381. var w = $image.width(), h = $image.height(), cW = document.body.clientWidth, cH = document.body.clientHeight;
  382. var left = (cW - w) / 2, top = (cH - h) / 2;
  383. $image.css("left", left + "px").css("top", top + "px");
  384. }
  385. // 设置缩略图拖拽区域
  386. function setThumbnails() {
  387. var $img = $thumbnails.find("img"), sW = $img.width(), sH = $img.height(), w = $image.width(), h = $image.height(), imf = $image.offset(), imfl = imf.left, imft = imf.top, cW = document.body.clientWidth, cH = document.body.clientHeight, tW, tH, tl, tt;
  388. if (isVertical) {
  389. sW = [ sH, sH = sW ][0];
  390. w = [ h, h = w ][0];
  391. }
  392. tW = sW / (w / cW);
  393. if (w < cW)
  394. tW = sW;
  395. tH = sH / (h / cH);
  396. if (h < cH)
  397. tH = sH;
  398. tl = (o.thumbnailsWidth - sW) / 2 + -imfl / w * sW;
  399. if (w < cW)
  400. tl = (o.thumbnailsWidth - sW) / 2;
  401. tt = (o.thumbnailsHeight - sH) / 2 + -imft / h * sH;
  402. if (h < cH)
  403. tt = (o.thumbnailsHeight - sH) / 2;
  404. $thumbnails.find(".thumbDrag").css({
  405. width : tW,
  406. height : tH,
  407. left : tl,
  408. top : tt
  409. });
  410. }
  411. init();
  412. return this;
  413. }
  414. });
  415. $.extend({
  416. // 打开图片查看器
  417. openPhotoGallery : function(obj) {
  418. var $img = $(obj), imgUrl = $img[0].src;
  419. if (!imgUrl)
  420. return;
  421. // HTML5提供了一个新属性naturalWidth/naturalHeight可以直接获取图片的原始宽高
  422. var img = $img[0], imgHeight = img.naturalHeight, imgWidth = img.naturalWidth, ratio = imgWidth / imgHeight, wH = 415, wW = 615, winHeight, winWidth, maxHeight = document.body.clientHeight - windowMargin * 2, maxWidth = document.body.clientWidth - windowMargin;
  423. winWidth = Math.max(wW, imgWidth);
  424. winHeight = Math.max(wH, imgHeight);
  425. if (winWidth > maxWidth) {
  426. winWidth = maxWidth;
  427. winHeight = Math.max(wH, Math.ceil(winWidth / ratio));
  428. if (imgWidth > winWidth) {
  429. imgWidth = winWidth;
  430. imgHeight = Math.ceil(imgWidth / ratio);
  431. }
  432. }
  433. if (winHeight > maxHeight) {
  434. winHeight = maxHeight;
  435. winWidth = Math.max(wW, Math.ceil(winHeight * ratio));
  436. if (imgHeight > winHeight) {
  437. imgHeight = winHeight;
  438. imgWidth = Math.ceil(imgHeight * ratio);
  439. }
  440. }
  441. var $gallerys = $(obj).closest(".gallerys"), activeIndex = 0, imgs = [];
  442. $(".gallery-pic").each(function(i, elem) {
  443. var url = this.src, img = $(this)[0], nH = img.naturalHeight, nW = img.naturalWidth, ratio = nW / nH, w = nW, h = nH;
  444. if (url == imgUrl) {
  445. activeIndex = i;
  446. w = imgWidth;
  447. h = imgHeight;
  448. } else {
  449. if (nW > winWidth) {
  450. w = winWidth;
  451. nH = h = Math.ceil(w / ratio);
  452. if (h > winHeight) {
  453. nH = h = winHeight;
  454. w = Math.ceil(h * ratio);
  455. }
  456. }
  457. if (nH > winHeight) {
  458. h = winHeight;
  459. w = Math.ceil(h * ratio);
  460. if (w > winWidth) {
  461. w = winWidth;
  462. h = Math.ceil(w / ratio);
  463. }
  464. }
  465. }
  466. imgs.push({
  467. url : url,
  468. imgHeight : h,
  469. imgWidth : w
  470. });
  471. });
  472. localStorage["photoGalleryImgs"] = JSON.stringify(imgs); // 因为此字符串可能是base64字符,appgo无法传
  473. localStorage["photoGalleryActiveIndex"] = activeIndex;
  474. $("#J_pg").remove();
  475. $("<iframe></iframe").appendTo("body").attr("id", "J_pg").attr("src", "lib/jquery-photo-gallery/gallery.html").css({
  476. position : "absolute",
  477. left : (document.body.clientWidth - winWidth) / 2,
  478. top : (document.body.clientHeight - winHeight) / 2 + $(window).scrollTop(),
  479. width : winWidth,
  480. height : winHeight,
  481. background : 'rgba(177, 178, 179, 1.0)',
  482. border : '1px solid #6D6D6D',
  483. 'border-radius' : '4px',
  484. 'z-index' : 9999
  485. });
  486. },
  487. // 做初始化
  488. initGallery : function() {
  489. var activeIndex = localStorage["photoGalleryActiveIndex"], imgs = JSON.parse(localStorage["photoGalleryImgs"]);
  490. localStorage.removeItem("photoGalleryActiveIndex");
  491. localStorage.removeItem("photoGalleryImgs");
  492. $("#mask").hide();
  493. $(".gallery").photoGallery({
  494. imgs : imgs,
  495. activeIndex : activeIndex
  496. });
  497. $(".closeWin").click(function() {
  498. var _parent = window.parent || window.top, _jg = _parent.document.getElementById("J_pg");
  499. $(_jg).remove();
  500. });
  501. }
  502. });
  503. })(jQuery);