Typora双击放大图片

news/2024/10/13 1:23:22
  1. 下载[lightbox2](lokesh/lightbox2: THE original Lightbox script (v2). (github.com)),将dist目录下的文件夹css,js,images拷贝到Typora安装目录下的resources目录下,可以新增若干级目录以保持resources内部清爽,这里加extensions/lightbox。

    image-20240730175215294 image-20240730175331313

    C:\Users\remotearn\AppData\Local\Programs\Typora\resources\extensions\lightbox

  2. 修改window.html文件
    此文件仍旧在resources目录下,C:\Users\remotearn\AppData\Local\Programs\Typora\resources\window.html

  3. image-20240730180010812
    • 引入css文件

      可以搜索</head>,在它的前面添加:

      <link rel="stylesheet" href="./extensions/lightbox/css/lightbox.min.css" crossorigin="anonymous">

      如下图

      image-20240730180302022

    • 引入js文件

      可以搜索<script src="./appsrc/window/frame.js" defer="defer"></script>在其后插入:

      <script type="text/javascript" src="./extensions/lightbox/js/lightbox.js" defer="defer"></script>

      如下图

      image-20240730180516429

  4. 用下面的代码片段覆盖lightbox.js文件,其路径是C:\Users\remotearn\AppData\Local\Programs\Typora\resources\extensions\lightbox\js\lightbox.js

    (function (root, factory) {if (typeof define === 'function' && define.amd) {// AMD. Register as an anonymous module.define(['jquery'], factory);} else if (typeof exports === 'object') {// Node. Does not work with strict CommonJS, but// only CommonJS-like environments that support module.exports,// like Node.module.exports = factory(require('jquery'));} else {// Browser globals (root is window)root.lightbox = factory(root.jQuery);}
    }(this, function ($) {function Lightbox(options) {this.album = [];this.currentImageIndex = void 0;this.init();// optionsthis.options = $.extend({}, this.constructor.defaults);this.option(options);}// Descriptions of all options available on the demo site:// http://lokeshdhakar.com/projects/lightbox2/index.html#optionsLightbox.defaults = {albumLabel: 'Image %1 of %2',alwaysShowNavOnTouchDevices: false,fadeDuration: 0,fitImagesInViewport: true,imageFadeDuration: 0,// maxWidth: 800,// maxHeight: 10,positionFromTop: 10,resizeDuration: 0,showImageNumberLabel: true,wrapAround: false,disableScrolling: false,/*Sanitize TitleIf the caption data is trusted, for example you are hardcoding it in, then leave this to false.This will free you to add html tags, such as links, in the caption.If the caption data is user submitted or from some other untrusted source, then set this to trueto prevent xss and other injection attacks.*/sanitizeTitle: false};Lightbox.prototype.option = function(options) {$.extend(this.options, options);};Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);};Lightbox.prototype.init = function() {var self = this;// Both enable and build methods require the body tag to be in the DOM.$(document).ready(function() {self.enable();self.build();});};// Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes// that contain 'lightbox'. When these are clicked, start lightbox.Lightbox.prototype.enable = function() {var self = this;$('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {self.start($(event.currentTarget));return false;});//为img绑定双击事件,但要排除本就是双击放大展示的图片$('body').on('dblclick', "img:not([class='lb-image'])", function(event) {self.start($(event.currentTarget));self.$image.css("zoom", "100%")return false;});};// Build html for the lightbox and the overlay.// Attach event handlers to the new DOM elements. click click clickLightbox.prototype.build = function() {if ($('#lightbox').length > 0) {// return;}var self = this;// The two root notes generated, #lightboxOverlay and #lightbox are given// tabindex attrs so they are focusable. We attach our keyboard event// listeners to these two elements, and not the document. Clicking anywhere// while Lightbox is opened will keep the focus on or inside one of these// two elements.//// We do this so we can prevent propogation of the Esc keypress when// Lightbox is open. This prevents it from intefering with other components// on the page below.//// Github issue: https://github.com/lokesh/lightbox2/issues/663$('<div id="lightboxOverlay" tabindex="-1" class="lightboxOverlay"></div><div id="lightbox" tabindex="-1" class="lightbox"><div class="lb-outerContainer" style="overflow:auto;"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt=""/><div class="lb-nav"><a class="lb-prev" aria-label="Previous image" href="" ></a><a class="lb-next" aria-label="Next image" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo($('body'));// Cache jQuery objectsthis.$lightbox       = $('#lightbox');this.$overlay        = $('#lightboxOverlay');this.$outerContainer = this.$lightbox.find('.lb-outerContainer');this.$container      = this.$lightbox.find('.lb-container');this.$image          = this.$lightbox.find('.lb-image');this.$nav            = this.$lightbox.find('.lb-nav');// Store css values for future lookupthis.containerPadding = {top: parseInt(this.$container.css('padding-top'), 10),right: parseInt(this.$container.css('padding-right'), 10),bottom: parseInt(this.$container.css('padding-bottom'), 10),left: parseInt(this.$container.css('padding-left'), 10)};this.imageBorderWidth = {top: parseInt(this.$image.css('border-top-width'), 10),right: parseInt(this.$image.css('border-right-width'), 10),bottom: parseInt(this.$image.css('border-bottom-width'), 10),left: parseInt(this.$image.css('border-left-width'), 10)};// Attach event handlers to the newly minted DOM elementsthis.$overlay.hide().on('click', function() {self.end();return false;});this.$lightbox.hide().on('click', function(event) {if ($(event.target).attr('id') === 'lightbox') {self.end();}});this.$outerContainer.on('click', function(event) {if ($(event.target).attr('id') === 'lightbox') {self.end();}return false;});this.$lightbox.find('.lb-prev').on('click', function() {if (self.currentImageIndex === 0) {self.changeImage(self.album.length - 1);} else {self.changeImage(self.currentImageIndex - 1);}return false;});this.$lightbox.find('.lb-next').on('click', function() {if (self.currentImageIndex === self.album.length - 1) {self.changeImage(0);} else {self.changeImage(self.currentImageIndex + 1);}return false;});/*Show context menu for image on right-clickThere is a div containing the navigation that spans the entire image and lives above of it. Ifyou right-click, you are right clicking this div and not the image. This prevents users fromsaving the image or using other context menu actions with the image.To fix this, when we detect the right mouse button is pressed down, but not yet clicked, weset pointer-events to none on the nav div. This is so that the upcoming right-click event onthe next mouseup will bubble down to the image. Once the right-click/contextmenu event occurswe set the pointer events back to auto for the nav div so it can capture hover and left-clickevents as usual.*/this.$nav.on('mousedown', function(event) {if (event.which === 3) {self.$nav.css('pointer-events', 'none');self.$lightbox.one('contextmenu', function() {setTimeout(function() {this.$nav.css('pointer-events', 'auto');}.bind(self), 0);});}});//给放大的图片另外绑定滚轮放大缩小事件this.$container.on('mousewheel', function(event) {event.delta = (event.originalEvent.wheelDelta) ? event.originalEvent.wheelDelta / 120 : -(event.originalEvent.detail || 0) / 3;var zoom = self.$image.css("zoom")zoom = zoom ? zoom * 100 : 100;zoom += event.delta*10;if(zoom > 0)self.$image.css("zoom",zoom + "%")console.log(self.$image.width(),self.$image.height())imageWidth = self.$image.width()imageHeight = self.$image.height()imageWidth = imageWidth*zoom*0.01imageHeight = imageHeight*zoom*0.01self.sizeContainer(imageWidth, imageHeight);return false;}); //给放大的图片另外绑定双击关闭事件this.$container.on('dblclick', function(event) {self.end();return false;}); this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {self.end();return false;});};// Show overlay and lightbox. If the image is part of a set, add siblings to album array.Lightbox.prototype.start = function($link) {var self    = this;var $window = $(window);$window.on('resize', $.proxy(this.sizeOverlay, this));this.sizeOverlay();this.album = [];var imageNumber = 0;function addToAlbum($link) {self.album.push({alt: $link.attr('data-alt') || $link.attr('alt'),link: $link.attr('href') || $link.attr('src'),title: $link.attr('data-title') || $link.attr('title')});}// Support both data-lightbox attribute and rel attribute implementationsvar dataLightboxValue = $link.attr('data-lightbox');var $links;if (dataLightboxValue) {$links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]');for (var i = 0; i < $links.length; i = ++i) {addToAlbum($($links[i]));if ($links[i] === $link[0]) {imageNumber = i;}}} else {
    /*       if ($link.attr('rel') === 'lightbox') {// If image is not part of a setaddToAlbum($link);} else {// If image is part of a set$links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');for (var j = 0; j < $links.length; j = ++j) {addToAlbum($($links[j]));if ($links[j] === $link[0]) {imageNumber = j;}}} */addToAlbum($link);}// Position Lightboxvar top  = $window.scrollTop() || 0 + this.options.positionFromTop;var left = $window.scrollLeft();this.$lightbox.css({top: top + 'px',left: left + 'px'}).fadeIn(this.options.fadeDuration);// Disable scrolling of the page while openif (this.options.disableScrolling) {$('body').addClass('lb-disable-scrolling');}this.changeImage(imageNumber);};// Hide most UI elements in preparation for the animated resizing of the lightbox.Lightbox.prototype.changeImage = function(imageNumber) {var self = this;var filename = this.album[imageNumber].link;var filetype = filename.split('.').slice(-1)[0];var $image = this.$lightbox.find('.lb-image');// Disable keyboard nav during transitionsthis.disableKeyboardNav();// Show loading statethis.$overlay.fadeIn(this.options.fadeDuration);$('.lb-loader').fadeIn('slow');this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();this.$outerContainer.addClass('animating');// When image to show is preloaded, we send the width and height to sizeContainer()var preloader = new Image();preloader.onload = function() {var $preloader;var imageHeight;var imageWidth;var maxImageHeight;var maxImageWidth;var windowHeight;var windowWidth;$image.attr({'alt': self.album[imageNumber].alt,'src': filename});$preloader = $(preloader);$image.width(preloader.width);$image.height(preloader.height);windowWidth = $(window).width();windowHeight = $(window).height();// Calculate the max image dimensions for the current viewport.// Take into account the border around the image and an additional 10px gutter on each side.maxImageWidth  = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20;maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - self.options.positionFromTop - 70;/*Since many SVGs have small intrinsic dimensions, but they support scalingup without quality loss because of their vector format, max out theirsize.*/if (filetype === 'svg') {$image.width(maxImageWidth);$image.height(maxImageHeight);}// Fit image inside the viewport.if (self.options.fitImagesInViewport) {// Check if image size is larger then maxWidth|maxHeight in settingsif (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {maxImageWidth = self.options.maxWidth;}if (self.options.maxHeight && self.options.maxHeight < maxImageHeight) {maxImageHeight = self.options.maxHeight;}} else {maxImageWidth = self.options.maxWidth || preloader.width || maxImageWidth;maxImageHeight = self.options.maxHeight || preloader.height || maxImageHeight;}// Is the current image's width or height is greater than the maxImageWidth or maxImageHeight// option than we need to size down while maintaining the aspect ratio.if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {imageWidth  = maxImageWidth;imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);$image.width(imageWidth);$image.height(imageHeight);} else {imageHeight = maxImageHeight;imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);$image.width(imageWidth);$image.height(imageHeight);}}self.sizeContainer($image.width(), $image.height());};// Preload image before showingpreloader.src = this.album[imageNumber].link;this.currentImageIndex = imageNumber;};// Stretch overlay to fit the viewportLightbox.prototype.sizeOverlay = function() {var self = this;/*We use a setTimeout 0 to pause JS execution and let the rendering catch-up.Why do this? If the `disableScrolling` option is set to true, a class is added to the bodytag that disables scrolling and hides the scrollbar. We want to make sure the scrollbar ishidden before we measure the document width, as the presence of the scrollbar will affect thenumber.*/setTimeout(function() {self.$overlay.width($(document).width()).height($(document).height());}, 0);};// Animate the size of the lightbox to fit the image we are showing// This method also shows the the image.Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {var self = this;var oldWidth  = this.$outerContainer.outerWidth();var oldHeight = this.$outerContainer.outerHeight();var newWidth  = imageWidth + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right;var newHeight = imageHeight + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom;//最大不超过屏幕宽高,若超过,滚动条出现windowWidth = $(window).width();windowHeight = $(window).height();if(newWidth > windowWidth){newWidth = windowWidth}if(newHeight+self.$lightbox.find('.lb-dataContainer').height() > windowHeight){newHeight = windowHeight - self.$lightbox.find('.lb-dataContainer').height()*2}function postResize() {self.$lightbox.find('.lb-dataContainer').width(newWidth);self.$lightbox.find('.lb-prevLink').height(newHeight);self.$lightbox.find('.lb-nextLink').height(newHeight);// Set focus on one of the two root nodes so keyboard events are captured.self.$overlay.focus();self.showImage();}if (oldWidth !== newWidth || oldHeight !== newHeight) {this.$outerContainer.animate({width: newWidth,height: newHeight}, this.options.resizeDuration, 'swing', function() {postResize();});} else {postResize();}};// Display the image and its details and begin preload neighboring images.Lightbox.prototype.showImage = function() {this.$lightbox.find('.lb-loader').stop(true).hide();this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration);this.updateNav();this.updateDetails();this.preloadNeighboringImages();this.enableKeyboardNav();};// Display previous and next navigation if appropriate.Lightbox.prototype.updateNav = function() {// Check to see if the browser supports touch events. If so, we take the conservative approach// and assume that mouse hover events are not supported and always show prev/next navigation// arrows in image sets.var alwaysShowNav = false;try {document.createEvent('TouchEvent');alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;} catch (e) {}this.$lightbox.find('.lb-nav').show();if (this.album.length > 1) {if (this.options.wrapAround) {if (alwaysShowNav) {this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');}this.$lightbox.find('.lb-prev, .lb-next').show();} else {if (this.currentImageIndex > 0) {this.$lightbox.find('.lb-prev').show();if (alwaysShowNav) {this.$lightbox.find('.lb-prev').css('opacity', '1');}}if (this.currentImageIndex < this.album.length - 1) {this.$lightbox.find('.lb-next').show();if (alwaysShowNav) {this.$lightbox.find('.lb-next').css('opacity', '1');}}}}};// Display caption, image number, and closing button.Lightbox.prototype.updateDetails = function() {var self = this;// Enable anchor clicks in the injected caption html.// Thanks Nate Wright for the fix. @https://github.com/NateWrif (typeof this.album[this.currentImageIndex].title !== 'undefined' &&this.album[this.currentImageIndex].title !== '') {var $caption = this.$lightbox.find('.lb-caption');if (this.options.sanitizeTitle) {$caption.text(this.album[this.currentImageIndex].title);} else {$caption.html(this.album[this.currentImageIndex].title);}$caption.fadeIn('fast');}if (this.album.length > 1 && this.options.showImageNumberLabel) {var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');} else {this.$lightbox.find('.lb-number').hide();}this.$outerContainer.removeClass('animating');this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {return self.sizeOverlay();});};// Preload previous and next images in set.Lightbox.prototype.preloadNeighboringImages = function() {if (this.album.length > this.currentImageIndex + 1) {var preloadNext = new Image();preloadNext.src = this.album[this.currentImageIndex + 1].link;}if (this.currentImageIndex > 0) {var preloadPrev = new Image();preloadPrev.src = this.album[this.currentImageIndex - 1].link;}};Lightbox.prototype.enableKeyboardNav = function() {this.$lightbox.on('keyup.keyboard', $.proxy(this.keyboardAction, this));this.$overlay.on('keyup.keyboard', $.proxy(this.keyboardAction, this));};Lightbox.prototype.disableKeyboardNav = function() {this.$lightbox.off('.keyboard');this.$overlay.off('.keyboard');};Lightbox.prototype.keyboardAction = function(event) {var KEYCODE_ESC        = 27;var KEYCODE_LEFTARROW  = 37;var KEYCODE_RIGHTARROW = 39;var keycode = event.keyCode;if (keycode === KEYCODE_ESC) {// Prevent bubbling so as to not affect other components on the page.event.stopPropagation();this.end();} else if (keycode === KEYCODE_LEFTARROW) {if (this.currentImageIndex !== 0) {this.changeImage(this.currentImageIndex - 1);} else if (this.options.wrapAround && this.album.length > 1) {this.changeImage(this.album.length - 1);}} else if (keycode === KEYCODE_RIGHTARROW) {if (this.currentImageIndex !== this.album.length - 1) {this.changeImage(this.currentImageIndex + 1);} else if (this.options.wrapAround && this.album.length > 1) {this.changeImage(0);}}};// Closing time. :-(Lightbox.prototype.end = function() {this.disableKeyboardNav();$(window).off('resize', this.sizeOverlay);this.$lightbox.fadeOut(this.options.fadeDuration);this.$overlay.fadeOut(this.options.fadeDuration);if (this.options.disableScrolling) {$('body').removeClass('lb-disable-scrolling');}};return new Lightbox();
    }));
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/70889.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

VLAN综合实验

需求:1.PC1和PC3所在接口为access接口;属于VLAN 2 PC2-4-5-6处于同一网段:其中PC2可以访间Pc4-5-6 PC4可以访间Pc5不能访间PC6 Pc5不能访问Pc6 3.PC1-Pc3---192.168.0.0 24与PC2-4-5-6不在一个网段--192.168.1.0 24 4.所有Pc均使用DHcp禁取IP地址,且PC1可以正常访间Pc2-4-5-6 …

Excel中实现当手动输入A列和B列的值时,C列自动计算A列和B列的和

要在Excel中实现当手动输入A列和B列的值时,C列自动计算A列和B列的和,可以使用Excel的“公式”和“事件”来完成。 由于Excel的普通单元格不能直接进行“自动执行计算”,需要借助VBA(Visual Basic for Applications)编写一个自动触发的脚本。 当A列或B列的值发生变化时,自…

VLAN-IP实验

需求:1.PC1和PC3所在接口为access接口;属于VLAN 2 PC2-4-5-6处于同一网段:其中PC2可以访间Pc4-5-6 PC4可以访间Pc5不能访间PC6 Pc5不能访问Pc6 3.PC1-Pc3---192.168.0.0 24与PC2-4-5-6不在一个网段--192.168.1.0 24 4.所有Pc均使用DHcp禁取IP地址,且PC1可以正常访间Pc2-4-5-6 …

mobaxterm隔一段时间就断开连接

【解决方法】点击setting,选中SSH Keepalive即可

【安全服务】2024年我国新一代网络安全服务代表性厂商:新华三

新华三是新华三技术有限公司的全资子公司,成立于2017年3月,为国内信息安全领域的领导企业,致力于为国家信息安全提供安全可信的领先产品与解决方案、专业的网络安全服务和优质的信息安全人才培养体系。 新华三拥有安全服务团队人员500+人,网络安全服务类型包括安全增值服务…

【安全服务】2024年我国新一代网络安全服务代表性厂商:中通服

中通服成立于2006年,是一家网络安全综合服务提供商,提供全生命周期的网络安全一体化综合服务,是国家重大活动安全保障和网信安全工程建设国家队。目前拥有安全服务团队人员1600+人,网络安全服务类型包括评估、咨询、设计、集成实施、涉密施工、监理、运维、应急和培训等。主…

《使用Gin框架构建分布式应用》阅读笔记:p1-p19

《使用Gin框架构建分布式应用》学习第1天,p1-p19总结,总计19页。 一、技术总结 1.go get & go install 执行go get 或者 go install 命令后package会被安装到哪里?参考:https://go.dev/ref/mod#go-install VSCode结合WSL使用后,路径把人绕晕了。 二、英语总结 1.evang…

华为交换机配置-STP

1.STP上述环境中,只对交换机3、4连接pc的端口设置为access模式,pc1和pc2可以通信,但是上图所示的网络中存在环路,所以需要开启STP 1.命令 交换机1 <Huawei>sy Enter system view, return user view with Ctrl+Z. [Huawei]sysname SW1 //开启全局STP [sw1]stp enable …