Skip to content

Fancybox now used for image handling

Announcements
  • On this site, I’ve added an animation (essentially, a link underline) that meant I needed to modify the Fancybox function. The new animation I mentioned above has an annoying artefact where it also applies on images where the fancybox class exists.

    This is not surprising, as the fancybox attribute adds a a href to all img tags. Based on this, it is necessary to add a noanimate class so that the link animation is not being applied. However, this isn’t such a simple affair. Due to the Lazy Load feature that NodeBB leverages, the images aren’t in the DOM until that specific chunk of data is loaded as the user scrolls through the post. To allow for this, we need to fire an event that selects each target image extension and then appends the existing classes with noanimate as desired. For this to work, we have to create a duplicate each function that uses the preexisting hook of action: posts.loaded.

    In usual cases of an entire page load, this could be quite greedy and have a significant impact on CPU cycles. Thankfully, the cost is in fact negated by the limited amount of data being pulled in each Ajax request using the post loaded feature.

    Below is the code I developed for that

    if (top.location.pathname !== '/login') {
    $(window).on('action:posts.loaded', function(data) {
    console.log("Loaded");
    $(document).ready(function() {
    $('a').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() {
    $('a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]').addClass("noanimate");
    });
    });
    });
    }
    if (top.location.pathname !== '/login') {
    $(document).ready(function() {
    $(window).on('action:ajaxify.end', function(data) {
    this.$('a').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() {
    $('a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]').addClass("noanimate");
    data.preventDefault()
    // Strip out the images contained inside blockquotes as this looks nasty :)
    $('blockquote img').remove();
    });
    Fancybox.bind(
    'a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]', {
    groupAll: true,
    }
    );
    });
    });
    }

    The specific CSS that defines the animated underline (which you can see for example by hovering over the usernames in each thread) is shown below - note how we exempt noanimate using the :not() class. Basically, apply this css to all a href except those that carry the appended class noanimate.

    It’s a bit of a bulldozer to break an egg, but it’s still efficient nonetheless.

    .content p a {
    position:relative;
    }
    .content p a:not(.noanimate):after {
    background: none repeat scroll 0 0 transparent;
    bottom: 0;
    content: "";
    display: block;
    height: 1px;
    left: 0%;
    position: absolute;
    background: var(--link);
    transition: width 0.3s ease 0s, left 0.3s ease 0s;
    width: 0;
    }
    .content p a:hover:after {
    width: 100%;
    left: 0;
    }
  • Thanks @phenomlab, are you still using Fancybox@4.0 on your site? I see v5.0 is available.

  • Thanks @phenomlab, are you still using Fancybox@4.0 on your site? I see v5.0 is available.

    @dave1904 Yes, currently, but will be upgrading soon!

    EDIT - I am using 5 🙂

  • Can’t see it working yet but I guess I have to rebuild/restart. Will do it later when less users are online. Already rebuilt and restarted a short time ago after deactivating the light box. 😄

    I’ll keep you updated.

  • Can’t see it working yet but I guess I have to rebuild/restart. Will do it later when less users are online. Already rebuilt and restarted a short time ago after deactivating the light box. 😄

    I’ll keep you updated.

    @dave1904 No need. Can you provide your Custom Header ?

  • @dave1904 No need. Can you provide your Custom Header ?

    @phenomlab Sure!

    <script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css"/>

    Edit: I should activate the header to get this working. 🤦 Thanks.

  • @phenomlab Sure!

    <script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css"/>
    

    Edit: I should activate the header to get this working. 🤦 Thanks.

    @dave1904 Working now?

  • Yes it is. 🙂

    no more need for the light box plugin if using this solution.

  • Yes it is. 🙂

    no more need for the light box plugin if using this solution.

    @dave1904 Yes, I put this together some time ago because it’s so much simpler.

  • And it seems to be less conflicting!



16/16

6 Oct 2023, 16:37


Threaded Replies

Related Topics
  • 15 Votes
    16 Posts
    757 Views
    @phenomlab of course, to be recognised is fantastic. @phenomlab said in Ch..ch..ch..ch..changes!: Sadly, no. Web crawlers and scrapers are often JS based and read text only, so styles don’t have any bearing. I’ve read mixed things about this, but no that does make sense, it was something I read a many years back when using Wordpress.
  • 0 Votes
    2 Posts
    145 Views
    @DownPW Technically, it should be possible with the addition of the below Toolbar: { display: { left: ["infobar"], middle: [ "zoomIn", "zoomOut", "toggle1to1", "rotateCCW", "rotateCW", "flipX", "flipY", ], right: ["slideshow", "thumbs", "close"], }, }, Meaning your code block becomes function fancybox() { if (top.location.pathname !== '/login') { $(document).ready(function() { $('a').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() { $('a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"], a[href*=".svg"]').addClass("noanimate"); }); }); Fancybox.bind( 'a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"], a[href*=".svg"]', { Toolbar: { display: { left: ["infobar"], middle: [ "zoomIn", "zoomOut", "toggle1to1", "rotateCCW", "rotateCW", "flipX", "flipY", ], right: ["slideshow", "thumbs", "close"], }, }, } ); } } Note, that you just need to add/remove the elements in the toolbar you do not need. Obviously, zoomIn and zoomOut are the ones you are specifically interested in. However, if Fancybox detects that the image has already been zoomed as far as possible, then this will not work. You’d need an external library such as zoom.js to add this functionality, or perhaps simpler https://www.jacklmoore.com/zoom/ A good example of how you’d make these two independent libraries work together is below https://codepen.io/ezra_siton/pen/VgrjKw It’s worth nothing that this specific code is based on Fancybox 3, so may need to be refactored to work with the latest version 5.
  • 7 Votes
    9 Posts
    871 Views
    @crazycells that’s as good a test as any
  • 16 Votes
    21 Posts
    2k Views
    I relented somewhat here and added another swatch - one I missed, which was previous called “blackout”. This specific one has been adapted to work on the new theming engine, but the others have been reclassified, and renamed to suit. [image: 1693924764891-d7f3a7a1-9702-4238-99bd-5c0e0d53f244-image.png] As a result, the theme you might have had will probably be reflecting something else, so you (might) need to change your themes accordingly. The changes are as follows Light -> No Change Cloudy -> Is now the old “Dim” Dim -> Is now the old “Dark” Dark -> Now a new theme based on the revamped “Blackout”
  • 2 Votes
    12 Posts
    894 Views
    @DownPW looks good to me.
  • 4 Votes
    3 Posts
    405 Views
    EDIT: Sorry all, I found a bug that causes Fancybox to be bound twice. Please remove the original functions I provided (the original post has been updated for anyone who did not use the original code and is new here) and replace with just this block // Chat fancybox - fires when chat module loaded and AJAX calls new chat $(document).ready(function() { $(window).on('action:chat.loaded', function(data) { this.$('img').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() { var newHref = $(this).attr("src"); $(this).wrap("<a class='fancybox' href='" + newHref + "'/>"); $('a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]').addClass("noanimate"); data.preventDefault(); // Strip out the images contained inside blockquotes as this looks nasty :) $('blockquote img').remove(); }); Fancybox.bind( 'a[href*=".jpg"], a[href*=".jpeg"], a[href*=".png"], a[href*=".gif"], a[href*=".webp"]', { groupAll: true, } ); }); });
  • 4 Votes
    8 Posts
    570 Views
    @Sampo2910 Here’s a demo of it from their blog [image: 1665047034755-skins.gif]
  • 5 Votes
    4 Posts
    552 Views