1

I am currently using a combination of fancybox thumbnails and buttons (only the toggle size button). By default, the buttons appear in the centre of the viewport, I would like to move this to the bottom right hand corner of the image, essentially appearing attached in the same way the close button is or just below the right corner would also be fine.

I have tried space it relative to the viewport width but it doesn't work. Is there a way to position it relative to the image?

I apologise for the abundance of code - I have no idea what to include and what to disregard, so I've put it all in.

If you look at my website (unfinished but I've uploaded it to help) you can see the issue on gallery one.

Shereewalker.com

Any help would be very much appreciated.

Here is my css

    #fancybox-buttons {
    position: fixed;
    left: 0;
    width: 100%;
    z-index: 8050;}


#fancybox-buttons.top {top: 10px;}

#fancybox-buttons.bottom {bottom: 10px;}

.fancybox-close {
    position: absolute;
    top: -18px;
    right: -18px;
    width: 36px;
    height: 36px;
    cursor: pointer;
    z-index: 8040; }

#fancybox-buttons ul {
    width: 36px;
    height: 36px;
    cursor: pointer;
    margin: 0 auto;
    list-style: none;}


#fancybox-buttons ul li {
    float: left;
    margin: 0;
    padding: 0;}

And my javascript

    jQuery(document).ready(function ($) {
   $(".fancybox").fancybox({
    prevEffect  : 'none',
        nextEffect  : 'none',

       // API options
       helpers : {
                title   : {
                type: 'outside'
                            },

           buttons: {},
           thumbs: {
            width   : 10,
                height  : 10

           }
       }
   }); // fancybox
}); // ready

And even more javascript

(function ($) {
    //Shortcut for fancyBox object
    var F = $.fancybox;

    //Add helper object
    F.helpers.buttons = {
        defaults : {
            skipSingle : false, // disables if gallery contains single image
            position   : 'top', // 'top' or 'bottom'
            tpl        : '<div id="fancybox-buttons"><ul><li><a class="btnToggle" title="Toggle size" href="javascript:;"></a></li></ul></div>'
        },

        list : null,
        buttons: null,

        beforeLoad: function (opts, obj) {
            //Remove self if gallery do not have at least two items

            if (opts.skipSingle && obj.group.length < 2) {
                obj.helpers.buttons = false;
                obj.closeBtn = true;

                return;
            }

            //Increase top margin to give space for buttons
            obj.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30;
        },

        onPlayStart: function () {
            if (this.buttons) {
                this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn');
            }
        },

        onPlayEnd: function () {
            if (this.buttons) {
                this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn');
            }
        },

        afterShow: function (opts, obj) {
            var buttons = this.buttons;

            if (!buttons) {
                this.list = $(opts.tpl).addClass(opts.position).appendTo('body');

                buttons = {
                    prev   : this.list.find('.btnPrev').click( F.prev ),
                    next   : this.list.find('.btnNext').click( F.next ),
                    play   : this.list.find('.btnPlay').click( F.play ),
                    toggle : this.list.find('.btnToggle').click( F.toggle ),
                    close  : this.list.find('.btnClose').click( F.close )
                }
            }

            //Prev
            if (obj.index > 0 || obj.loop) {
                buttons.prev.removeClass('btnDisabled');
            } else {
                buttons.prev.addClass('btnDisabled');
            }

            //Next / Play
            if (obj.loop || obj.index < obj.group.length - 1) {
                buttons.next.removeClass('btnDisabled');
                buttons.play.removeClass('btnDisabled');

            } else {
                buttons.next.addClass('btnDisabled');
                buttons.play.addClass('btnDisabled');
            }

            this.buttons = buttons;

            this.onUpdate(opts, obj);
        },

        onUpdate: function (opts, obj) {
            var toggle;

            if (!this.buttons) {
                return;
            }

            toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn');

            //Size toggle button
            if (obj.canShrink) {
                toggle.addClass('btnToggleOn');

            } else if (!obj.canExpand) {
                toggle.addClass('btnDisabled');
            }
        },

        beforeClose: function () {
            if (this.list) {
                this.list.remove();
            }

            this.list    = null;
            this.buttons = null;
        }
    };

}(jQuery));
Mr Toad
  • 202
  • 2
  • 12
  • 41
  • 1
    This is challenging because the fancybox thumbnails are not in the same container as the image. This means the thumbs are not aware of the image width as it changes so they wouldn't be able to align properly – zgood Jul 11 '15 at 01:11
  • Sorry I was looking at the thumbnails when I wrote that comment, but the same applys to the toggle button – zgood Jul 11 '15 at 01:27
  • 1
    I do have an idea... this line (`this.list = $(opts.tpl).addClass(opts.position).appendTo('body');`) in your fancybox helper config for the `afterShow` event ... see if you can `.appendTo('.fancybox-wrap')` instead of `body`. If you get the button in the same container then you can align it no problem – zgood Jul 11 '15 at 01:37
  • This worked! It didn't at first but then I realised that the containing ul had a fixed position which was the reason it wasn't moving. Took it away and bingo! Thanks :) – Mr Toad Jul 12 '15 at 00:52
  • no prob! I'll post it as an answer since it worked so it may help others in the future. – zgood Jul 12 '15 at 02:16

2 Answers2

1

If you want to move the toggle button only, you actually need to clone it rather than moving it.

Based on this answer https://stackoverflow.com/a/17888534/1055987, we could tweak it into this :

CSS

/* hide the actual buttons helper */
 #fancybox-buttons {
    display: none;
}
/* position the clone : notice the class "clone" */
 .clone {
    position: absolute;
    top: 5px;
    right: 0;
}
.btnToggle.clone {
    background-position: 3px -60px;
    border-left: 1px solid #111;
    border-right: 1px solid #3e3e3e;
    width: 35px;
    height: 35px;
    background-image: url("{your path}/helpers/fancybox_buttons.png");
    background-color: #333;
}
.clone.btnToggleOn {
    background-position: -27px -60px;
}

Then the jQuery code :

jQuery(document).ready(function ($) {
    $(".fancybox").fancybox({
        helpers: {
            title: {
                type: 'inside'
            },
            buttons: {} // we need this to clone
        },
        afterLoad: function () {
            // make sure we have a title
            this.title = this.title ? this.title : "&nbsp;";
        },
        afterShow: function () {
            // wait for the buttons helper
            setTimeout(function () {
                $("#fancybox-buttons")
                .find(".btnToggle")
                .clone(true, true) // clone with data and events
                .addClass("clone") // add class "clone"
                .appendTo(".fancybox-title") // append it to the title
                .fadeIn(); // show it nicely
            }, 100); //setTimeout
        }, // afterShow
        onUpdate: function () {
            var toggle = $(".btnToggle.clone").removeClass('btnDisabled btnToggleOn');
            if (this.canShrink) {
                toggle.addClass('btnToggleOn');
            } else if (!this.canExpand) {
                toggle.addClass('btnDisabled');
            }
        }
    }); // fancybox
}); // ready

See JSFIDDLE

Community
  • 1
  • 1
JFK
  • 40,963
  • 31
  • 133
  • 306
  • JFK - I am confused, why do you need a clone? Sorry if that's a stupid question but I don't understand why you would manipulate a clone rather than the original? I removed the other buttons in the jquery and have managed to position it correctly but it only works on the initial slide. Thanks again for your help – Mr Toad Jul 12 '15 at 19:27
  • that's why you clone it, to inherit the original functionality and keep consistency through your whole gallery (as in my example http://jsfiddle.net/pyqsdLbm/) this way I don't have to add the functionality to my new element (this is where the issues start as in your own solution ;) – JFK Jul 12 '15 at 20:56
  • Well JFK, I ended up scrapping all my fiddles and starting over with your code and suprise suprise, voilà... it started working. I added the thumbs into the Javascript from a previous post you answered which worked exactly how I wanted but for some reason, while the expand toggle works to open, it does not work to close (after the first time)? Also - (Sorry!) but is there a way to disable the swipe out effect of the slide and return it to the simple image change style I had prior to adding the button helper? All my progress is on my site Shereewalker.com Thanks so much!! – Mr Toad Jul 14 '15 at 21:50
  • @ShereeWalker : I don't have too much time right now but after quick look, I guess you need to add a `padding-bottom` (at least `35px`) to you `.fancybox-title-outside-wrap` element, otherwise the title overlaps the fancybox thumbs (or thumbs are actually overlaping the title where the toggle button is), hence being inaccessible (rather than not working). You could also increase the height of the title to make room for the toggle button. You can do that in your own custom CSS – JFK Jul 14 '15 at 23:33
  • @ShereeWalker to eliminate the "swipe" effect, add the API options `nextEffect` and `prevEffect` and set both to `fade` in your fancybox code – JFK Jul 14 '15 at 23:37
  • Can the thumbnails just be turned off on zoom? – Mr Toad Jul 15 '15 at 01:54
0

The toggle size button (and thumbnails) and hard to align because they are in separate full-width containers. This markup is generated by FancyBox for the gallery slideshow.

It looks like this:

<body>
    <div class="fancybox-wrap">
    <div class="fancybox-overlay">
    <div id="fancybox-buttons">
    <div id="fancybox-thumbs"> 

The .fancybox-wrap contains the gallery image and #fancybox-buttons contains the toggle size button.

Luckily, the OP was creating a template (tpl) for the toggle size button... but was injecting it into the <body> so it was unaware of the content of the .fancybox-wrap.

To fix this just change this line:

this.list = $(opts.tpl).addClass(opts.position).appendTo('body');

To this:

this.list = $(opts.tpl).addClass(opts.position).appendTo('.fancybox-wrap');

This just puts the buttons inside the same container as the gallery image (which is what we want to align too).

zgood
  • 12,181
  • 2
  • 25
  • 26
  • Okay so I have made some progress. I started by removing the list item and just making it a div as after removing the other buttons, there was no need for a unordered list. I changed it in the javascript aswell as it works great but only on the first slide. Any following slides (including the first slide when it comes back around) have no button. Basically it works on the initial load, but not after. Any ideas? I have uploaded the new site so you can see... shereewalker.com – Mr Toad Jul 12 '15 at 19:14