});
// ToDo: consider re-using existing popinOverlay div?
- $('body').append('<div id="zoomPopupOverlay"></div><div id="zoomPopupWrapper"><a href="#" class="zoomPopupClose">' + getSpriteIcon('interface-close') + '</a></div>');
+ $('body').append('<div id="zoomPopupOverlay"></div><div id="zoomPopupGroupWrapper"></div>');
$(document).on('click', '.zoomPopup', function (e) {
e.preventDefault();
$this.resize();
});
- $(document).on('click', '#zoomPopupOverlay, #zoomPopupWrapper, #zoomPopupClose', function (e) {
+ $(document).on('click', '#zoomPopupOverlay, .zoomPopupWrapper, .zoomPopupClose', function (e) {
$this.zoomLinkReset();
return false;
});
},
zoomLink: function (link) {
- var $this = this;
// If the interface is zoomed in, we must zoom out first
if (this.fluidbook.zoom.zoom > 1) {
$this.zoomLink(link);
});
-
// Zoom out
this.fluidbook.zoom.resetZoom();
return false;
}
- //this.zoomLinkReset();
- var z = $('#zoomPopupWrapper'),
+
+ var $this = this,
+ $link = $(link),
+ links = [],
zoomMargin = 50,
availableWidth = $(window).width() - (2 * zoomMargin),
- availableHeight = $(window).height() - (2 * zoomMargin),
- $link = $(link),
- box = $link[0].getBoundingClientRect(), // Should return full values without rounding
- parent = $link.closest('.link'),
- baseWidth = parseInt($link.data('width')), // Width of the original link from the editor
- baseHeight = parseInt($link.data('height')), // Height of the original link from the editor
- maxZoom = parseInt($link.data('maxzoom')) || 2, // The default value for this should match that of the compiler in zoomLink::generateImage()
- x,
- y,
- zoomWidth,
- zoomHeight,
- zoomScale;
-
- if ($(parent).length == 0) {
- return;
+ availableHeight = $(window).height() - (2 * zoomMargin);
+
+ // Add clicked zoom link to the collection
+ links.push($link);
+
+ // If there is a zoom group, we need to find the other zone it is linked to
+ // For now, only 2 zones maximum can be linked together so if we have more
+ // than one group (eg. for a shared zone), we should treat it as a standalone
+ // zone when clicked.
+ if ($link.data('group-count') == 1) {
+ // Find other zones in the same group
+ var $others = $('.zoom-group-' + $link.data('group')).not('#' + $link.attr('id'));
+
+ if ($others.length >= 1) {
+ links.push($others.first()); // Take the first because we only support 1 linked zone currently
+ }
}
- var linkId = $(parent).attr('id').split('_', 2)[1];
- var zoomImage = 'data/links/zoom_' + linkId + '.jpg';
+ links.forEach(function(zoomLink) {
+ // console.log('Found link with ID: ' + zoomLink.attr('id'));
+
+ var zoomID = zoomLink.attr('id');
+ // Add holder for each zoom zone
+ $('#zoomPopupGroupWrapper').append('<div class="zoomPopupWrapper" id="zoomPopup_'+ zoomID +'"><a href="#" class="zoomPopupClose">' + getSpriteIcon('interface-close') + '</a></div>');
- // TODO: In the compiler we should look at generating higher-res images to cater for hiDPI displays
- // TODO: It should be clearer what the sizes in the link editor really mean - due to screen size and scaling, a 100x100 link could appear as 150x150 in the player so if it we set a max zoom level of 2, it will only appear at 200x200, which is not much bigger than the embedded size. It's hard to handle max zoom levels while also working with a player that always scales the content to fit the screen. The most pragmatic approach probably is to generate higher res images.
+ var z = $('#zoomPopup_' + zoomID),
+ box = zoomLink[0].getBoundingClientRect(), // Should return full values without rounding
+ parent = zoomLink.closest('.link'),
+ baseWidth = parseInt(zoomLink.data('width')), // Width of the original link from the editor
+ baseHeight = parseInt(zoomLink.data('height')), // Height of the original link from the editor
+ maxZoom = parseInt(zoomLink.data('maxzoom')) || 2, // The default value for this should match that of the compiler in zoomLink::generateImage()
+ x,
+ y,
+ zoomWidth,
+ zoomHeight,
+ zoomScale;
+ if ($(parent).length == 0) {
+ return;
+ }
- // Due to the scaling done by the Fluidbook interface, the actual link size is likely to be different
- // to the original link editor width and height. Since the zoom image is generated based on the link editor
- // dimensions multiplied by the max zoom level, we need to be able to take that into account so we don't exceed
- // the resolution of the image in the popup. We can't use the fluidbook.resize.bookScale variable because it
- // measures the scaling of the high-res images. Instead, we work out the relative scaling by taking the
- // link editor width (baseWidth) and comparing it to the actual link width.
- //maxZoom = maxZoom / (box.width / baseWidth); // Adjusted maxZoom level...
+ var linkId = $(parent).attr('id').split('_', 2)[1];
+ var zoomImage = 'data/links/zoom_' + linkId + '.jpg';
- // Calculate best scale factor to fit and also to honour the maxZoom level
- zoomScale = Math.min((availableWidth / baseWidth), (availableHeight / baseHeight), maxZoom);
+ // TODO: In the compiler we should look at generating higher-res images to cater for hiDPI displays
+ // TODO: It should be clearer what the sizes in the link editor really mean - due to screen size and scaling, a 100x100 link could appear as 150x150 in the player so if it we set a max zoom level of 2, it will only appear at 200x200, which is not much bigger than the embedded size. It's hard to handle max zoom levels while also working with a player that always scales the content to fit the screen. The most pragmatic approach probably is to generate higher res images.
- // Dimensions of the final popup
- zoomWidth = baseWidth * zoomScale;
- zoomHeight = baseHeight * zoomScale;
- // Calculate translate co-ordinates so image is centred correctly
- // Values are rounded so we don't end up with image being positioned between pixels, which causes blurring
- x = Math.round((availableWidth / 2) - parent.offset().left - (zoomWidth / 2) + zoomMargin);
- y = Math.round((availableHeight / 2) - parent.offset().top - (zoomHeight / 2) + zoomMargin);
+ // Due to the scaling done by the Fluidbook interface, the actual link size is likely to be different
+ // to the original link editor width and height. Since the zoom image is generated based on the link editor
+ // dimensions multiplied by the max zoom level, we need to be able to take that into account so we don't exceed
+ // the resolution of the image in the popup. We can't use the fluidbook.resize.bookScale variable because it
+ // measures the scaling of the high-res images. Instead, we work out the relative scaling by taking the
+ // link editor width (baseWidth) and comparing it to the actual link width.
+ //maxZoom = maxZoom / (box.width / baseWidth); // Adjusted maxZoom level...
- // Keep starting scale with zoom element so it can be used when zooming back out
- z.data('starting-scale', box.width / zoomWidth);
+ // Calculate best scale factor to fit and also to honour the maxZoom level
+ zoomScale = Math.min((availableWidth / baseWidth), (availableHeight / baseHeight), maxZoom);
- // Initial position of the zoom box - should sit over the link and match
- // size and position so that the element appears to zoom from the link
- z.css({
+ // Dimensions of the final popup
+ zoomWidth = baseWidth * zoomScale;
+ zoomHeight = baseHeight * zoomScale;
+
+ // Calculate translate co-ordinates so image is centred correctly
+ // Values are rounded so we don't end up with image being positioned between pixels, which causes blurring
+ x = Math.round((availableWidth / 2) - parent.offset().left - (zoomWidth / 2) + zoomMargin);
+ y = Math.round((availableHeight / 2) - parent.offset().top - (zoomHeight / 2) + zoomMargin);
+
+ // Keep starting scale with zoom element so it can be used when zooming back out
+ z.data('starting-scale', box.width / zoomWidth);
+
+ // Initial position of the zoom box - should sit over the link and match
+ // size and position so that the element appears to zoom from the link
+ z.css({
transform: 'translateX(0) translateY(0) scale(' + z.data('starting-scale') + ')',
width: zoomWidth,
height: zoomHeight,
left: Math.round(box.left),
top: Math.round(box.top)
- });
- // z.find('img').remove();
+ });
+ // z.find('img').remove();
- // Load image before running zoom up animation
- this.fluidbook.displayLoader();
- loadImage(zoomImage, function (img) {
+ // Load image before running zoom up animation
+ this.fluidbook.displayLoader();
+ loadImage(zoomImage, function (img) {
//z.append(img);
// Image is set as a background for better scaling / fitting via CSS
// Trigger zoom up animation just after showing zoom element
setTimeout(function () {
- z.css({
- boxShadow: '0 0 100px rgba(0,0,0,0.3)',
- transform: 'translateX(' + x + 'px) translateY(' + y + 'px) scale(1)'
- });
+ z.css({
+ boxShadow: '0 0 100px rgba(0,0,0,0.3)',
+ transform: 'translateX(' + x + 'px) translateY(' + y + 'px) scale(1)'
+ });
}, 50);
// Hide close button initially so it only shows when zoom finishes.
// Display close button after zoom animation has finished
setTimeout(function () {
- $(".zoomPopupClose").css('opacity', 1);
+ $(".zoomPopupClose").css('opacity', 1);
}, 500);
+ });
+
});
},
},
zoomLinkReset: function (immediate) {
- if ($('#zoomPopupWrapper:visible').length == 0) {
+
+ var $this = this;
+
+ if ($('.zoomPopupWrapper:visible').length == 0) {
return;
}
immediate = false;
}
+ var $wrapper = $('#zoomPopupGroupWrapper');
- var z = $('#zoomPopupWrapper');
+ // Close each popup that is open
+ $wrapper.find('.zoomPopupWrapper').each(function() {
+ var z = $(this);
+ z.find('.zoomPopupClose').css('opacity', '0');
- $(".zoomPopupClose").css('opacity', '0');
+ if (immediate) {
+ $('.zoomPopupWrapper').hide();
+ $this.hideOverlay(1);
+ }
- z.css({
+ z.css({
transform: 'translate(0,0) scale(' + z.data('starting-scale') + ')',
boxShadow: '0 0 0 rgba(0,0,0,0.3)',
+ });
});
- if (immediate) {
- $('#zoomPopupWrapper').hide();
- this.hideOverlay(1);
- }
// Hide popup after transition completes
// ToDo: use CSS transition end event to do this without needing a timeout value (or use Web Animation API)
// ToDo: see https://davidwalsh.name/css-animation-callback
this.hideOverlay(500);
setTimeout(function () {
- $('#zoomPopupWrapper').hide();
+ $('.zoomPopupWrapper').hide();
+ $wrapper.html(''); // Empty group wrapper
}, 500);
return false;