I found a solution combining several solutions I found on StackOverflow and GitHub:
jQuery(function($) {
var config = {
maxWidth: 0.95,
maxHeight: 0.95
}
// Contao default code
$('a[data-lightbox]').map(function() {
$(this).colorbox({
rel: $(this).attr('data-lightbox'),
maxWidth: (config.maxWidth * 100).toString() + '%',
maxHeight: (config.maxHeight * 100).toString() + '%',
fixed: true
});
});
// Yousef Altaf 's solution
var resizeTimer = null;
var resizeTimeout = 300;
function resizeColorBox()
{
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
if ($('#cboxOverlay').is(':visible')) {
$.colorbox.resize({
maxWidth: config.maxWidth * 100 + '%',
maxHeight: config.maxHeight * 100 + '%'
});
// my addition:
// get the original size of the image
var photo = $('.cboxPhoto');
var imgWidth = photo.prop('naturalWidth');
var imgHeight = photo.prop('naturalHeight');
if (!(isNaN(imgWidth) || isNaN(imgHeight))) { // only if its an image and HTML5 properties work as expected
var windowWidth = $(window).width();
var windowHeight = $(window).height();
// get the max available space for the image content
// -> substract border width (2*5px)
// -> substract title column height (20px)
var maxWidth = Math.round((windowWidth * config.maxWidth) - 10);
var maxHeight = Math.round((windowHeight * config.maxHeight) - 30);
// Calculate aspect ratio for available space and original image size
var contentAspect = maxWidth / maxHeight;
var photoAspect = imgWidth / imgHeight;
var height;
var width;
if (photoAspect > contentAspect) {
// max out new width, use image width if its less than max available width
var size = maxWidth > imgWidth ? imgWidth : maxWidth;
var width = size + 'px';
var height = size / photoAspect + 'px';
} else {
// max out new height, use image height if its smaller than max available height
var size = maxHeight > imgHeight ? imgHeight : maxHeight;
var height = size + 'px';
var width = size * photoAspect + 'px';
}
// set the new dimensions as inner size
$.colorbox.resize({
innerHeight: height,
innerWidth: width
});
// scale the photo as this is not done by colorbox when resizing
$('.cboxPhoto').css({
width: width,
height: height
})
}
}
}, resizeTimeout)
}
// Resize Colorbox when resizing window or changing mobile device orientation
$(window).resize(resizeColorBox);
window.addEventListener("orientationchange", resizeColorBox, false);
});
This code originates fom the Contao j_colorbox
template. I customized this code with the proposed solution of Yousef Altaf but wasn't satisfied with the image sizing, though it solved the problem with the colorbox getting stuck at the edge of the screen.
To fix the issue with the image not benefiting from increased space/not respecting reduced space I added some code to resize the box again according to maximum available size and image aspect ratio. However, this relies on HTM5 properties, as described here, so I added a guard to prevent issues on older browsers.
Edit:
I found this one useful too: https://stackoverflow.com/a/8697415/12390988https://stackoverflow.com/a/8697415/12390988
Also i included a fullscreen-mode on mobile devices:
$('a[data-lightbox]').map(function() {
// Not 100% reliable but ok for the usecase i think
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
var fullscreenActiveBeforeOpen = false;
$(this).colorbox({
rel: $(this).attr('data-lightbox'),
maxWidth: (config.maxWidth * 100).toString() + '%',
maxHeight: (config.maxHeight * 100).toString() + '%',
fixed: true,
loop: false,
onLoad: function() {
$('html, body').css('overflow', 'hidden'); // page scrollbars off
// On mobile devices, enter fullscreen
if (isMobile) {
// Remember fullscreen state before opening
fullscreenActiveBeforeOpen = !!document.fullscreenElement;
document.documentElement.requestFullscreen();
}
},
onClosed: function() {
$('html, body').css('overflow', ''); // page scrollbars on
// On mobile devices and if fullscreen has not been active before, end fullscreen
if (isMobile && !fullscreenActiveBeforeOpen) {
document.exitFullscreen();
}
}
});
});
Edit 2:
I found that the fullscreen-code breaks on at least some IOS devices because requestFullscreen
is missing. Wrapping the fullscreen API with try/catch prevents the colorbox from breaking/freezing; Using webkitRequestFullscreen
, webkitFullscreenEnabled
and webkitExitFullscreen
enables fullscreen on Safari:
// snip...
var fullscreenBroken = false;
$(this).colorbox({
rel: $(this).attr('data-lightbox'),
maxWidth: (config.maxWidth * 100).toString() + '%',
maxHeight: (config.maxHeight * 100).toString() + '%',
fixed: true,
loop: false,
onLoad: function() {
$('html, body').css('overflow', 'hidden'); // page scrollbars off
if (isMobile && !fullscreenBroken) {
try {
fullscreenActiveBeforeOpen = typeof document.webkitFullscreenEnabled === 'boolean'
? document.webkitFullscreenEnabled
: !!document.fullscreenEnabled;
typeof document.documentElement.webkitRequestFullscreen === 'function'
? document.documentElement.webkitRequestFullscreen()
: document.documentElement.requestFullscreen();
} catch (e) {
fullscreenBroken = true
}
}
},
onClosed: function() {
$('html, body').css('overflow', ''); // page scrollbars on
if (isMobile && !fullscreenActiveBeforeOpen && !fullscreenBroken) {
try {
typeof document.webkitExitFullscreen === 'function'
? document.webkitExitFullscreen()
: document.exitFullscreen();
} catch (e) {
fullscreenBroken = true
}
}
}
});
// snip...