diff --git a/README.md b/README.md index 18bce7db..f772197f 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,9 @@ Airsonic is free software and licensed under the [GNU General Public License ver The [Subsonic source code](https://github.com/airsonic/subsonic-svn) was released under the GPLv3 through version 6.0-beta1. Beginning with 6.0-beta2, source is no longer provided. Binaries of Subsonic are only available under a commercial license. There is a [Subsonic Premium](http://www.subsonic.org/pages/premium.jsp) service which adds functionality not available in Airsonic. Subsonic also offers RPM, Deb, Exe, and other pre-built packages that Airsonic [currently does not](https://github.com/airsonic/airsonic/issues/65). +The cover zooming feature is provided by [jquery.fancyzoom](https://github.com/keegnotrub/jquery.fancyzoom), +released under [MIT License](http://www.opensource.org/licenses/mit-license.php). + Usage ----- diff --git a/airsonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp b/airsonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp index e3ecb3f8..1f7e79d1 100644 --- a/airsonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp +++ b/airsonic-main/src/main/webapp/WEB-INF/jsp/albumMain.jsp @@ -9,8 +9,7 @@ - - + @@ -24,7 +23,9 @@ - - + @@ -39,7 +38,9 @@ var topSongs; function init() { - setupZoom(''); + $("a.fancy").fancyZoom({ + minBorder: 30 + }); loadArtistInfo(); @@ -68,7 +69,10 @@ if (artistInfo.artistBio && artistInfo.artistBio.biography) { $("#artistBio").append(artistInfo.artistBio.biography); if (artistInfo.artistBio.largeImageUrl) { - $("#artistImage").attr("src", artistInfo.artistBio.largeImageUrl); + $("#artistImage").attr({ + "src": artistInfo.artistBio.largeImageUrl, + "class": "fancy" + }); $("#artistImageZoom").attr("href", artistInfo.artistBio.largeImageUrl); $("#artistImage").show(); $("#artistInfoTable").show(); diff --git a/airsonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp b/airsonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp index 7616e135..bf38cf32 100644 --- a/airsonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp +++ b/airsonic-main/src/main/webapp/WEB-INF/jsp/coverArt.jsp @@ -85,7 +85,7 @@ PARAMETERS - + diff --git a/airsonic-main/src/main/webapp/script/closebox.png b/airsonic-main/src/main/webapp/script/closebox.png new file mode 100644 index 00000000..a07d043e Binary files /dev/null and b/airsonic-main/src/main/webapp/script/closebox.png differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/FancyZoom.js b/airsonic-main/src/main/webapp/script/fancyzoom/FancyZoom.js deleted file mode 100644 index c98624fa..00000000 --- a/airsonic-main/src/main/webapp/script/fancyzoom/FancyZoom.js +++ /dev/null @@ -1,761 +0,0 @@ -// FancyZoom.js - v1.1 - http://www.fancyzoom.com -// -// Copyright (c) 2008 Cabel Sasser / Panic Inc -// All rights reserved. -// -// Requires: FancyZoomHTML.js -// Instructions: Include JS files in page, call setupZoom() in onLoad. That's it! -// Any links to images will be updated to zoom inline. -// Add rel="nozoom" to your to disable zooming for an image. -// -// Redistribution and use of this effect in source form, with or without modification, -// are permitted provided that the following conditions are met: -// -// * USE OF SOURCE ON COMMERCIAL (FOR-PROFIT) WEBSITE REQUIRES ONE-TIME LICENSE FEE PER DOMAIN. -// Reasonably priced! Visit www.fancyzoom.com for licensing instructions. Thanks! -// -// * Non-commercial (personal) website use is permitted without license/payment! -// -// * Redistribution of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution of source code and derived works cannot be sold without specific -// written prior permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -var includeCaption = true; // Turn on the "caption" feature, and write out the caption HTML -var zoomTime = 5; // Milliseconds between frames of zoom animation -var zoomSteps = 15; // Number of zoom animation frames -var includeFade = 1; // Set to 1 to fade the image in / out as it zooms -var minBorder = 90; // Amount of padding between large, scaled down images, and the window edges -var shadowSettings = '0px 5px 25px rgba(0, 0, 0, '; // Blur, radius, color of shadow for compatible browsers - -// Location of the zoom and shadow images -var zoomImagesURI; - -// Init. Do not add anything below this line, unless it's something awesome. - -var myWidth = 0, myHeight = 0, myScroll = 0; myScrollWidth = 0; myScrollHeight = 0; -var zoomOpen = false, preloadFrame = 1, preloadActive = false, preloadTime = 0, imgPreload = new Image(); -var preloadAnimTimer = 0; - -var zoomActive = new Array(); var zoomTimer = new Array(); -var zoomOrigW = new Array(); var zoomOrigH = new Array(); -var zoomOrigX = new Array(); var zoomOrigY = new Array(); - -var zoomID = "ZoomBox"; -var theID = "ZoomImage"; -var zoomCaption = "ZoomCaption"; -var zoomCaptionDiv = "ZoomCapDiv"; - -if (navigator.userAgent.indexOf("MSIE") != -1) { - var browserIsIE = true; -} - -// Zoom: Setup The Page! Called in your 's onLoad handler. - -function setupZoom(baseURI) { - zoomImagesURI = baseURI + 'script/fancyzoom/images/'; - - prepZooms(); - insertZoomHTML(); - zoomdiv = document.getElementById(zoomID); - zoomimg = document.getElementById(theID); -} - -// Zoom: Inject Javascript functions into hrefs with a "zoom" rel. -// This is done at page load time via an onLoad() handler. - -function prepZooms() { - if (! document.getElementsByTagName) { - return; - } - var links = document.getElementsByTagName("a"); - for (i = 0; i < links.length; i++) { - if (links[i].getAttribute("href")) { - if (links[i].getAttribute("rel") == "zoom") { - links[i].onclick = function (event) { return zoomClick(this, event); }; - links[i].onmouseover = function () { zoomPreload(this); }; - } - } - } -} - -// Zoom: Load an image into an image object. When done loading, function sets preloadActive to false, -// so other bits know that they can proceed with the zoom. -// Preloaded image is stored in imgPreload and swapped out in the zoom function. - -function zoomPreload(from) { - - var theimage = from.getAttribute("href"); - - // Only preload if we have to, i.e. the image isn't this image already - - if (imgPreload.src.indexOf(from.getAttribute("href").substr(from.getAttribute("href").lastIndexOf("/"))) == -1) { - preloadActive = true; - imgPreload = new Image(); - - // Set a function to fire when the preload is complete, setting flags along the way. - - imgPreload.onload = function() { - preloadActive = false; - } - - // Load it! - imgPreload.src = theimage; - } -} - -// Zoom: Start the preloading animation cycle. - -function preloadAnimStart() { - preloadTime = new Date(); - document.getElementById("ZoomSpin").style.left = (myWidth / 2) + 'px'; - document.getElementById("ZoomSpin").style.top = ((myHeight / 2) + myScroll) + 'px'; - document.getElementById("ZoomSpin").style.visibility = "visible"; - preloadFrame = 1; - document.getElementById("SpinImage").src = zoomImagesURI+'zoom-spin-'+preloadFrame+'.png'; - preloadAnimTimer = setInterval("preloadAnim()", 100); -} - -// Zoom: Display and ANIMATE the jibber-jabber widget. Once preloadActive is false, bail and zoom it up! - -function preloadAnim(from) { - if (preloadActive != false) { - document.getElementById("SpinImage").src = zoomImagesURI+'zoom-spin-'+preloadFrame+'.png'; - preloadFrame++; - if (preloadFrame > 12) preloadFrame = 1; - } else { - document.getElementById("ZoomSpin").style.visibility = "hidden"; - clearInterval(preloadAnimTimer); - preloadAnimTimer = 0; - zoomIn(preloadFrom); - } -} - -// ZOOM CLICK: We got a click! Should we do the zoom? Or wait for the preload to complete? -// todo?: Double check that imgPreload src = clicked src - -function zoomClick(from, evt) { - - var shift = getShift(evt); - - // Check for Command / Alt key. If pressed, pass them through -- don't zoom! - if (! evt && window.event && (window.event.metaKey || window.event.altKey)) { - return true; - } else if (evt && (evt.metaKey|| evt.altKey)) { - return true; - } - - // Get browser dimensions - getSize(); - - // If preloading still, wait, and display the spinner. - if (preloadActive == true) { - // But only display the spinner if it's not already being displayed! - if (preloadAnimTimer == 0) { - preloadFrom = from; - preloadAnimStart(); - } - } else { - // Otherwise, we're loaded: do the zoom! - zoomIn(from, shift); - } - - return false; - -} - -// Zoom: Move an element in to endH endW, using zoomHost as a starting point. -// "from" is an object reference to the href that spawned the zoom. - -function zoomIn(from, shift) { - - zoomimg.src = from.getAttribute("href"); - - // Determine the zoom settings from where we came from, the element in the . - // If there's no element in the , or we can't get the width, make stuff up - - if (from.childNodes[0].width) { - startW = from.childNodes[0].width; - startH = from.childNodes[0].height; - startPos = findElementPos(from.childNodes[0]); - } else { - startW = 50; - startH = 12; - startPos = findElementPos(from); - } - - hostX = startPos[0]; - hostY = startPos[1]; - - // Make up for a scrolled containing div. - // TODO: This HAS to move into findElementPos. - - if (document.getElementById('scroller')) { - hostX = hostX - document.getElementById('scroller').scrollLeft; - } - - // Determine the target zoom settings from the preloaded image object - - endW = imgPreload.width; - endH = imgPreload.height; - - // Start! But only if we're not zooming already! - - if (zoomActive[theID] != true) { - - // Clear everything out just in case something is already open - - if (document.getElementById("ShadowBox")) { - document.getElementById("ShadowBox").style.visibility = "hidden"; - } else if (! browserIsIE) { - - // Wipe timer if shadow is fading in still - if (fadeActive["ZoomImage"]) { - clearInterval(fadeTimer["ZoomImage"]); - fadeActive["ZoomImage"] = false; - fadeTimer["ZoomImage"] = false; - } - - document.getElementById("ZoomImage").style.webkitBoxShadow = shadowSettings + '0.0)'; - } - - document.getElementById("ZoomClose").style.visibility = "hidden"; - - // Setup the CAPTION, if existing. Hide it first, set the text. - - if (includeCaption) { - document.getElementById(zoomCaptionDiv).style.visibility = "hidden"; - if (from.getAttribute('title') && includeCaption) { - // Yes, there's a caption, set it up - document.getElementById(zoomCaption).innerHTML = from.getAttribute('title'); - } else { - document.getElementById(zoomCaption).innerHTML = ""; - } - } - - // Store original position in an array for future zoomOut. - - zoomOrigW[theID] = startW; - zoomOrigH[theID] = startH; - zoomOrigX[theID] = hostX; - zoomOrigY[theID] = hostY; - - // Now set the starting dimensions - - zoomimg.style.width = startW + 'px'; - zoomimg.style.height = startH + 'px'; - zoomdiv.style.left = hostX + 'px'; - zoomdiv.style.top = hostY + 'px'; - - // Show the zooming image container, make it invisible - - if (includeFade == 1) { - setOpacity(0, zoomID); - } - zoomdiv.style.visibility = "visible"; - - // If it's too big to fit in the window, shrink the width and height to fit (with ratio). - - sizeRatio = endW / endH; - if (endW > myWidth - minBorder) { - endW = myWidth - minBorder; - endH = endW / sizeRatio; - } - if (endH > myHeight - minBorder) { - endH = myHeight - minBorder; - endW = endH * sizeRatio; - } - - zoomChangeX = ((myWidth / 2) - (endW / 2) - hostX); - zoomChangeY = (((myHeight / 2) - (endH / 2) - hostY) + myScroll); - zoomChangeW = (endW - startW); - zoomChangeH = (endH - startH); - - // Shift key? - - if (shift) { - tempSteps = zoomSteps * 7; - } else { - tempSteps = zoomSteps; - } - - // Setup Zoom - - zoomCurrent = 0; - - // Setup Fade with Zoom, If Requested - - if (includeFade == 1) { - fadeCurrent = 0; - fadeAmount = (0 - 100) / tempSteps; - } else { - fadeAmount = 0; - } - - // Do It! - - zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+hostX+", "+zoomChangeX+", "+hostY+", "+zoomChangeY+", "+tempSteps+", "+includeFade+", "+fadeAmount+", 'zoomDoneIn(zoomID)')", zoomTime); - zoomActive[theID] = true; - } -} - -// Zoom it back out. - -function zoomOut(from, evt) { - - // Get shift key status. - // IE events don't seem to get passed through the function, so grab it from the window. - - if (getShift(evt)) { - tempSteps = zoomSteps * 7; - } else { - tempSteps = zoomSteps; - } - - // Check to see if something is happening/open - - if (zoomActive[theID] != true) { - - // First, get rid of the shadow if necessary. - - if (document.getElementById("ShadowBox")) { - document.getElementById("ShadowBox").style.visibility = "hidden"; - } else if (! browserIsIE) { - - // Wipe timer if shadow is fading in still - if (fadeActive["ZoomImage"]) { - clearInterval(fadeTimer["ZoomImage"]); - fadeActive["ZoomImage"] = false; - fadeTimer["ZoomImage"] = false; - } - - document.getElementById("ZoomImage").style.webkitBoxShadow = shadowSettings + '0.0)'; - } - - // ..and the close box... - - document.getElementById("ZoomClose").style.visibility = "hidden"; - - // ...and the caption if necessary! - - if (includeCaption && document.getElementById(zoomCaption).innerHTML != "") { - // fadeElementSetup(zoomCaptionDiv, 100, 0, 5, 1); - document.getElementById(zoomCaptionDiv).style.visibility = "hidden"; - } - - // Now, figure out where we came from, to get back there - - startX = parseInt(zoomdiv.style.left); - startY = parseInt(zoomdiv.style.top); - startW = zoomimg.width; - startH = zoomimg.height; - zoomChangeX = zoomOrigX[theID] - startX; - zoomChangeY = zoomOrigY[theID] - startY; - zoomChangeW = zoomOrigW[theID] - startW; - zoomChangeH = zoomOrigH[theID] - startH; - - // Setup Zoom - - zoomCurrent = 0; - - // Setup Fade with Zoom, If Requested - - if (includeFade == 1) { - fadeCurrent = 0; - fadeAmount = (100 - 0) / tempSteps; - } else { - fadeAmount = 0; - } - - // Do It! - - zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+startX+", "+zoomChangeX+", "+startY+", "+zoomChangeY+", "+tempSteps+", "+includeFade+", "+fadeAmount+", 'zoomDone(zoomID, theID)')", zoomTime); - zoomActive[theID] = true; - } -} - -// Finished Zooming In - -function zoomDoneIn(zoomdiv, theID) { - - // Note that it's open - - zoomOpen = true; - zoomdiv = document.getElementById(zoomdiv); - - // Position the table shadow behind the zoomed in image, and display it - - if (document.getElementById("ShadowBox")) { - - setOpacity(0, "ShadowBox"); - shadowdiv = document.getElementById("ShadowBox"); - - shadowLeft = parseInt(zoomdiv.style.left) - 13; - shadowTop = parseInt(zoomdiv.style.top) - 8; - shadowWidth = zoomdiv.offsetWidth + 26; - shadowHeight = zoomdiv.offsetHeight + 26; - - shadowdiv.style.width = shadowWidth + 'px'; - shadowdiv.style.height = shadowHeight + 'px'; - shadowdiv.style.left = shadowLeft + 'px'; - shadowdiv.style.top = shadowTop + 'px'; - - document.getElementById("ShadowBox").style.visibility = "visible"; - fadeElementSetup("ShadowBox", 0, 100, 5); - - } else if (! browserIsIE) { - // Or, do a fade of the modern shadow - fadeElementSetup("ZoomImage", 0, .8, 5, 0, "shadow"); - } - - // Position and display the CAPTION, if existing - - if (includeCaption && document.getElementById(zoomCaption).innerHTML != "") { - // setOpacity(0, zoomCaptionDiv); - zoomcapd = document.getElementById(zoomCaptionDiv); - zoomcapd.style.top = parseInt(zoomdiv.style.top) + (zoomdiv.offsetHeight + 15) + 'px'; - zoomcapd.style.left = (myWidth / 2) - (zoomcapd.offsetWidth / 2) + 'px'; - zoomcapd.style.visibility = "visible"; - // fadeElementSetup(zoomCaptionDiv, 0, 100, 5); - } - - // Display Close Box (fade it if it's not IE) - - if (!browserIsIE) setOpacity(0, "ZoomClose"); - document.getElementById("ZoomClose").style.visibility = "visible"; - if (!browserIsIE) fadeElementSetup("ZoomClose", 0, 100, 5); - - // Get keypresses - document.onkeypress = getKey; - -} - -// Finished Zooming Out - -function zoomDone(zoomdiv, theID) { - - // No longer open - - zoomOpen = false; - - // Clear stuff out, clean up - - zoomOrigH[theID] = ""; - zoomOrigW[theID] = ""; - document.getElementById(zoomdiv).style.visibility = "hidden"; - zoomActive[theID] == false; - - // Stop getting keypresses - - document.onkeypress = null; - -} - -// Actually zoom the element - -function zoomElement(zoomdiv, theID, zoomCurrent, zoomStartW, zoomChangeW, zoomStartH, zoomChangeH, zoomStartX, zoomChangeX, zoomStartY, zoomChangeY, zoomSteps, includeFade, fadeAmount, execWhenDone) { - - // console.log("Zooming Step #"+zoomCurrent+ " of "+zoomSteps+" (zoom " + zoomStartW + "/" + zoomChangeW + ") (zoom " + zoomStartH + "/" + zoomChangeH + ") (zoom " + zoomStartX + "/" + zoomChangeX + ") (zoom " + zoomStartY + "/" + zoomChangeY + ") Fade: "+fadeAmount); - - // Test if we're done, or if we continue - - if (zoomCurrent == (zoomSteps + 1)) { - zoomActive[theID] = false; - clearInterval(zoomTimer[theID]); - - if (execWhenDone != "") { - eval(execWhenDone); - } - } else { - - // Do the Fade! - - if (includeFade == 1) { - if (fadeAmount < 0) { - setOpacity(Math.abs(zoomCurrent * fadeAmount), zoomdiv); - } else { - setOpacity(100 - (zoomCurrent * fadeAmount), zoomdiv); - } - } - - // Calculate this step's difference, and move it! - - moveW = cubicInOut(zoomCurrent, zoomStartW, zoomChangeW, zoomSteps); - moveH = cubicInOut(zoomCurrent, zoomStartH, zoomChangeH, zoomSteps); - moveX = cubicInOut(zoomCurrent, zoomStartX, zoomChangeX, zoomSteps); - moveY = cubicInOut(zoomCurrent, zoomStartY, zoomChangeY, zoomSteps); - - document.getElementById(zoomdiv).style.left = moveX + 'px'; - document.getElementById(zoomdiv).style.top = moveY + 'px'; - zoomimg.style.width = moveW + 'px'; - zoomimg.style.height = moveH + 'px'; - - zoomCurrent++; - - clearInterval(zoomTimer[theID]); - zoomTimer[theID] = setInterval("zoomElement('"+zoomdiv+"', '"+theID+"', "+zoomCurrent+", "+zoomStartW+", "+zoomChangeW+", "+zoomStartH+", "+zoomChangeH+", "+zoomStartX+", "+zoomChangeX+", "+zoomStartY+", "+zoomChangeY+", "+zoomSteps+", "+includeFade+", "+fadeAmount+", '"+execWhenDone+"')", zoomTime); - } -} - -// Zoom Utility: Get Key Press when image is open, and act accordingly - -function getKey(evt) { - if (! evt) { - theKey = event.keyCode; - } else { - theKey = evt.keyCode; - } - - if (theKey == 27) { // ESC - zoomOut(this, evt); - } -} - -//////////////////////////// -// -// FADE Functions -// - -function fadeOut(elem) { - if (elem.id) { - fadeElementSetup(elem.id, 100, 0, 10); - } -} - -function fadeIn(elem) { - if (elem.id) { - fadeElementSetup(elem.id, 0, 100, 10); - } -} - -// Fade: Initialize the fade function - -var fadeActive = new Array(); -var fadeQueue = new Array(); -var fadeTimer = new Array(); -var fadeClose = new Array(); -var fadeMode = new Array(); - -function fadeElementSetup(theID, fdStart, fdEnd, fdSteps, fdClose, fdMode) { - - // alert("Fading: "+theID+" Steps: "+fdSteps+" Mode: "+fdMode); - - if (fadeActive[theID] == true) { - // Already animating, queue up this command - fadeQueue[theID] = new Array(theID, fdStart, fdEnd, fdSteps); - } else { - fadeSteps = fdSteps; - fadeCurrent = 0; - fadeAmount = (fdStart - fdEnd) / fadeSteps; - fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 15); - fadeActive[theID] = true; - fadeMode[theID] = fdMode; - - if (fdClose == 1) { - fadeClose[theID] = true; - } else { - fadeClose[theID] = false; - } - } -} - -// Fade: Do the fade. This function will call itself, modifying the parameters, so -// many instances can run concurrently. Can fade using opacity, or fade using a box-shadow. - -function fadeElement(theID, fadeCurrent, fadeAmount, fadeSteps) { - - if (fadeCurrent == fadeSteps) { - - // We're done, so clear. - - clearInterval(fadeTimer[theID]); - fadeActive[theID] = false; - fadeTimer[theID] = false; - - // Should we close it once the fade is complete? - - if (fadeClose[theID] == true) { - document.getElementById(theID).style.visibility = "hidden"; - } - - // Hang on.. did a command queue while we were working? If so, make it happen now - - if (fadeQueue[theID] && fadeQueue[theID] != false) { - fadeElementSetup(fadeQueue[theID][0], fadeQueue[theID][1], fadeQueue[theID][2], fadeQueue[theID][3]); - fadeQueue[theID] = false; - } - } else { - - fadeCurrent++; - - // Now actually do the fade adjustment. - - if (fadeMode[theID] == "shadow") { - - // Do a special fade on the webkit-box-shadow of the object - - if (fadeAmount < 0) { - document.getElementById(theID).style.webkitBoxShadow = shadowSettings + (Math.abs(fadeCurrent * fadeAmount)) + ')'; - } else { - document.getElementById(theID).style.webkitBoxShadow = shadowSettings + (100 - (fadeCurrent * fadeAmount)) + ')'; - } - - } else { - - // Set the opacity depending on if we're adding or subtracting (pos or neg) - - if (fadeAmount < 0) { - setOpacity(Math.abs(fadeCurrent * fadeAmount), theID); - } else { - setOpacity(100 - (fadeCurrent * fadeAmount), theID); - } - } - - // Keep going, and send myself the updated variables - clearInterval(fadeTimer[theID]); - fadeTimer[theID] = setInterval("fadeElement('"+theID+"', '"+fadeCurrent+"', '"+fadeAmount+"', '"+fadeSteps+"')", 15); - } -} - -//////////////////////////// -// -// UTILITY functions -// - -// Utility: Set the opacity, compatible with a number of browsers. Value from 0 to 100. - -function setOpacity(opacity, theID) { - - var object = document.getElementById(theID).style; - - // If it's 100, set it to 99 for Firefox. - - if (navigator.userAgent.indexOf("Firefox") != -1) { - if (opacity == 100) { opacity = 99.9999; } // This is majorly awkward - } - - // Multi-browser opacity setting - - object.filter = "alpha(opacity=" + opacity + ")"; // IE/Win - object.opacity = (opacity / 100); // Safari 1.2, Firefox+Mozilla - -} - -// Utility: Math functions for animation calucations - From http://www.robertpenner.com/easing/ -// -// t = time, b = begin, c = change, d = duration -// time = current frame, begin is fixed, change is basically finish - begin, duration is fixed (frames), - -function linear(t, b, c, d) -{ - return c*t/d + b; -} - -function sineInOut(t, b, c, d) -{ - return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; -} - -function cubicIn(t, b, c, d) { - return c*(t/=d)*t*t + b; -} - -function cubicOut(t, b, c, d) { - return c*((t=t/d-1)*t*t + 1) + b; -} - -function cubicInOut(t, b, c, d) -{ - if ((t/=d/2) < 1) return c/2*t*t*t + b; - return c/2*((t-=2)*t*t + 2) + b; -} - -function bounceOut(t, b, c, d) -{ - if ((t/=d) < (1/2.75)){ - return c*(7.5625*t*t) + b; - } else if (t < (2/2.75)){ - return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; - } else if (t < (2.5/2.75)){ - return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; - } else { - return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; - } -} - - -// Utility: Get the size of the window, and set myWidth and myHeight -// Credit to quirksmode.org - -function getSize() { - - // Window Size - - if (self.innerHeight) { // Everyone but IE - myWidth = window.innerWidth; - myHeight = window.innerHeight; - myScroll = window.pageYOffset; - } else if (document.documentElement && document.documentElement.clientHeight) { // IE6 Strict - myWidth = document.documentElement.clientWidth; - myHeight = document.documentElement.clientHeight; - myScroll = document.documentElement.scrollTop; - } else if (document.body) { // Other IE, such as IE7 - myWidth = document.body.clientWidth; - myHeight = document.body.clientHeight; - myScroll = document.body.scrollTop; - } - - // Page size w/offscreen areas - - if (window.innerHeight && window.scrollMaxY) { - myScrollWidth = document.body.scrollWidth; - myScrollHeight = window.innerHeight + window.scrollMaxY; - } else if (document.body.scrollHeight > document.body.offsetHeight) { // All but Explorer Mac - myScrollWidth = document.body.scrollWidth; - myScrollHeight = document.body.scrollHeight; - } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari - myScrollWidth = document.body.offsetWidth; - myScrollHeight = document.body.offsetHeight; - } -} - -// Utility: Get Shift Key Status -// IE events don't seem to get passed through the function, so grab it from the window. - -function getShift(evt) { - var shift = false; - if (! evt && window.event) { - shift = window.event.shiftKey; - } else if (evt) { - shift = evt.shiftKey; - if (shift) evt.stopPropagation(); // Prevents Firefox from doing shifty things - } - return shift; -} - -// Utility: Find the Y position of an element on a page. Return Y and X as an array - -function findElementPos(elemFind) -{ - var elemX = 0; - var elemY = 0; - do { - elemX += elemFind.offsetLeft; - elemY += elemFind.offsetTop; - } while ( elemFind = elemFind.offsetParent ) - - return Array(elemX, elemY); -} \ No newline at end of file diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/FancyZoomHTML.js b/airsonic-main/src/main/webapp/script/fancyzoom/FancyZoomHTML.js deleted file mode 100644 index 7644a9a8..00000000 --- a/airsonic-main/src/main/webapp/script/fancyzoom/FancyZoomHTML.js +++ /dev/null @@ -1,318 +0,0 @@ -// FancyZoomHTML.js - v1.0 -// Used to draw necessary HTML elements for FancyZoom -// -// Copyright (c) 2008 Cabel Sasser / Panic Inc -// All rights reserved. - -function insertZoomHTML() { - - // All of this junk creates the three
's used to hold the closebox, image, and zoom shadow. - - var inBody = document.getElementsByTagName("body").item(0); - - // WAIT SPINNER - - var inSpinbox = document.createElement("div"); - inSpinbox.setAttribute('id', 'ZoomSpin'); - inSpinbox.style.position = 'absolute'; - inSpinbox.style.left = '10px'; - inSpinbox.style.top = '10px'; - inSpinbox.style.visibility = 'hidden'; - inSpinbox.style.zIndex = '525'; - inBody.insertBefore(inSpinbox, inBody.firstChild); - - var inSpinImage = document.createElement("img"); - inSpinImage.setAttribute('id', 'SpinImage'); - inSpinImage.setAttribute('src', zoomImagesURI+'zoom-spin-1.png'); - inSpinbox.appendChild(inSpinImage); - - // ZOOM IMAGE - // - //
- // - //
- // - //
- //
- - var inZoombox = document.createElement("div"); - inZoombox.setAttribute('id', 'ZoomBox'); - - inZoombox.style.position = 'absolute'; - inZoombox.style.left = '10px'; - inZoombox.style.top = '10px'; - inZoombox.style.visibility = 'hidden'; - inZoombox.style.zIndex = '499'; - - inBody.insertBefore(inZoombox, inSpinbox.nextSibling); - - var inImage1 = document.createElement("img"); - inImage1.onclick = function (event) { zoomOut(this, event); return false; }; - inImage1.setAttribute('src',zoomImagesURI+'spacer.gif'); - inImage1.setAttribute('id','ZoomImage'); - inImage1.setAttribute('border', '0'); - // inImage1.setAttribute('onMouseOver', 'zoomMouseOver();') - // inImage1.setAttribute('onMouseOut', 'zoomMouseOut();') - - // This must be set first, so we can later test it using webkitBoxShadow. - inImage1.setAttribute('style', '-webkit-box-shadow: '+shadowSettings+'0.0)'); - inImage1.style.display = 'block'; - inImage1.style.width = '10px'; - inImage1.style.height = '10px'; - inImage1.style.cursor = 'pointer'; // -webkit-zoom-out? - inZoombox.appendChild(inImage1); - - var inClosebox = document.createElement("div"); - inClosebox.setAttribute('id', 'ZoomClose'); - inClosebox.style.position = 'absolute'; - - // In MSIE, we need to put the close box inside the image. - // It's 2008 and I'm having to do a browser detect? Sigh. - if (browserIsIE) { - inClosebox.style.left = '-1px'; - inClosebox.style.top = '0px'; - } else { - inClosebox.style.left = '-15px'; - inClosebox.style.top = '-15px'; - } - - inClosebox.style.visibility = 'hidden'; - inZoombox.appendChild(inClosebox); - - var inImage2 = document.createElement("img"); - inImage2.onclick = function (event) { zoomOut(this, event); return false; }; - inImage2.setAttribute('src',zoomImagesURI+'closebox.png'); - inImage2.setAttribute('width','30'); - inImage2.setAttribute('height','30'); - inImage2.setAttribute('border','0'); - inImage2.style.cursor = 'pointer'; - inClosebox.appendChild(inImage2); - - // SHADOW - // Only draw the table-based shadow if the programatic webkitBoxShadow fails! - // Also, don't draw it if we're IE -- it wouldn't look quite right anyway. - - if (! document.getElementById('ZoomImage').style.webkitBoxShadow && ! browserIsIE) { - - // SHADOW BASE - - var inFixedBox = document.createElement("div"); - inFixedBox.setAttribute('id', 'ShadowBox'); - inFixedBox.style.position = 'absolute'; - inFixedBox.style.left = '50px'; - inFixedBox.style.top = '50px'; - inFixedBox.style.width = '100px'; - inFixedBox.style.height = '100px'; - inFixedBox.style.visibility = 'hidden'; - inFixedBox.style.zIndex = '498'; - inBody.insertBefore(inFixedBox, inZoombox.nextSibling); - - // SHADOW - // Now, the shadow table. Skip if not compatible, or irrevelant with -box-shadow. - - //
X - // - // - // - // - // - - var inShadowTable = document.createElement("table"); - inShadowTable.setAttribute('border', '0'); - inShadowTable.setAttribute('width', '100%'); - inShadowTable.setAttribute('height', '100%'); - inShadowTable.setAttribute('cellpadding', '0'); - inShadowTable.setAttribute('cellspacing', '0'); - inFixedBox.appendChild(inShadowTable); - - var inShadowTbody = document.createElement("tbody"); // Needed for IE (for HTML4). - inShadowTable.appendChild(inShadowTbody); - - var inRow1 = document.createElement("tr"); - inRow1.style.height = '25px'; - inShadowTbody.appendChild(inRow1); - - var inCol1 = document.createElement("td"); - inCol1.style.width = '27px'; - inRow1.appendChild(inCol1); - var inShadowImg1 = document.createElement("img"); - inShadowImg1.setAttribute('src', zoomImagesURI+'zoom-shadow1.png'); - inShadowImg1.setAttribute('width', '27'); - inShadowImg1.setAttribute('height', '25'); - inShadowImg1.style.display = 'block'; - inCol1.appendChild(inShadowImg1); - - var inCol2 = document.createElement("td"); - inCol2.setAttribute('background', zoomImagesURI+'zoom-shadow2.png'); - inRow1.appendChild(inCol2); - // inCol2.innerHTML = ' - // - // - // - // - - inRow2 = document.createElement("tr"); - inShadowTbody.appendChild(inRow2); - - var inCol4 = document.createElement("td"); - inCol4.setAttribute('background', zoomImagesURI+'zoom-shadow4.png'); - inRow2.appendChild(inCol4); - // inCol4.innerHTML = ' '; - var inSpacer2 = document.createElement("img"); - inSpacer2.setAttribute('src',zoomImagesURI+'spacer.gif'); - inSpacer2.setAttribute('height', '1'); - inSpacer2.setAttribute('width', '1'); - inSpacer2.style.display = 'block'; - inCol4.appendChild(inSpacer2); - - var inCol5 = document.createElement("td"); - inCol5.setAttribute('bgcolor', '#ffffff'); - inRow2.appendChild(inCol5); - // inCol5.innerHTML = ' '; - var inSpacer3 = document.createElement("img"); - inSpacer3.setAttribute('src',zoomImagesURI+'spacer.gif'); - inSpacer3.setAttribute('height', '1'); - inSpacer3.setAttribute('width', '1'); - inSpacer3.style.display = 'block'; - inCol5.appendChild(inSpacer3); - - var inCol6 = document.createElement("td"); - inCol6.setAttribute('background', zoomImagesURI+'zoom-shadow5.png'); - inRow2.appendChild(inCol6); - // inCol6.innerHTML = ' '; - var inSpacer4 = document.createElement("img"); - inSpacer4.setAttribute('src',zoomImagesURI+'spacer.gif'); - inSpacer4.setAttribute('height', '1'); - inSpacer4.setAttribute('width', '1'); - inSpacer4.style.display = 'block'; - inCol6.appendChild(inSpacer4); - - // - // - // - // - //
 
   
- //  
- - var inRow3 = document.createElement("tr"); - inRow3.style.height = '26px'; - inShadowTbody.appendChild(inRow3); - - var inCol7 = document.createElement("td"); - inCol7.style.width = '27px'; - inRow3.appendChild(inCol7); - var inShadowImg7 = document.createElement("img"); - inShadowImg7.setAttribute('src', zoomImagesURI+'zoom-shadow6.png'); - inShadowImg7.setAttribute('width', '27'); - inShadowImg7.setAttribute('height', '26'); - inShadowImg7.style.display = 'block'; - inCol7.appendChild(inShadowImg7); - - var inCol8 = document.createElement("td"); - inCol8.setAttribute('background', zoomImagesURI+'zoom-shadow7.png'); - inRow3.appendChild(inCol8); - // inCol8.innerHTML = ' '; - var inSpacer5 = document.createElement("img"); - inSpacer5.setAttribute('src',zoomImagesURI+'spacer.gif'); - inSpacer5.setAttribute('height', '1'); - inSpacer5.setAttribute('width', '1'); - inSpacer5.style.display = 'block'; - inCol8.appendChild(inSpacer5); - - var inCol9 = document.createElement("td"); - inCol9.style.width = '27px'; - inRow3.appendChild(inCol9); - var inShadowImg9 = document.createElement("img"); - inShadowImg9.setAttribute('src', zoomImagesURI+'zoom-shadow8.png'); - inShadowImg9.setAttribute('width', '27'); - inShadowImg9.setAttribute('height', '26'); - inShadowImg9.style.display = 'block'; - inCol9.appendChild(inShadowImg9); - } - - if (includeCaption) { - - // CAPTION - // - //
- // - // - // - // - // - // - //
- //
- - var inCapDiv = document.createElement("div"); - inCapDiv.setAttribute('id', 'ZoomCapDiv'); - inCapDiv.style.position = 'absolute'; - inCapDiv.style.visibility = 'hidden'; - inCapDiv.style.marginLeft = 'auto'; - inCapDiv.style.marginRight = 'auto'; - inCapDiv.style.zIndex = '501'; - - inBody.insertBefore(inCapDiv, inZoombox.nextSibling); - - var inCapTable = document.createElement("table"); - inCapTable.setAttribute('border', '0'); - inCapTable.setAttribute('cellPadding', '0'); // Wow. These honestly need to - inCapTable.setAttribute('cellSpacing', '0'); // be intercapped to work in IE. WTF? - inCapDiv.appendChild(inCapTable); - - var inTbody = document.createElement("tbody"); // Needed for IE (for HTML4). - inCapTable.appendChild(inTbody); - - var inCapRow1 = document.createElement("tr"); - inTbody.appendChild(inCapRow1); - - var inCapCol1 = document.createElement("td"); - inCapCol1.setAttribute('align', 'right'); - inCapRow1.appendChild(inCapCol1); - var inCapImg1 = document.createElement("img"); - inCapImg1.setAttribute('src', zoomImagesURI+'zoom-caption-l.png'); - inCapImg1.setAttribute('width', '13'); - inCapImg1.setAttribute('height', '26'); - inCapImg1.style.display = 'block'; - inCapCol1.appendChild(inCapImg1); - - var inCapCol2 = document.createElement("td"); - inCapCol2.setAttribute('background', zoomImagesURI+'zoom-caption-fill.png'); - inCapCol2.setAttribute('id', 'ZoomCaption'); - inCapCol2.setAttribute('valign', 'middle'); - inCapCol2.style.fontSize = '14px'; - inCapCol2.style.fontFamily = 'Helvetica'; - inCapCol2.style.fontWeight = 'bold'; - inCapCol2.style.color = '#ffffff'; - inCapCol2.style.textShadow = '0px 2px 4px #000000'; - inCapCol2.style.whiteSpace = 'nowrap'; - inCapRow1.appendChild(inCapCol2); - - var inCapCol3 = document.createElement("td"); - inCapRow1.appendChild(inCapCol3); - var inCapImg2 = document.createElement("img"); - inCapImg2.setAttribute('src', zoomImagesURI+'zoom-caption-r.png'); - inCapImg2.setAttribute('width', '13'); - inCapImg2.setAttribute('height', '26'); - inCapImg2.style.display = 'block'; - inCapCol3.appendChild(inCapImg2); - } -} \ No newline at end of file diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/closebox.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/closebox.png deleted file mode 100644 index b3d65d0f..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/closebox.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/spacer.gif b/airsonic-main/src/main/webapp/script/fancyzoom/images/spacer.gif deleted file mode 100644 index 5bfd67a2..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/spacer.gif and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-fill.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-fill.png deleted file mode 100644 index 06fc1d69..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-fill.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-l.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-l.png deleted file mode 100644 index 390f23fa..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-l.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-r.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-r.png deleted file mode 100644 index 00333ba0..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-caption-r.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow1.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow1.png deleted file mode 100644 index e50b9b5e..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow1.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow2.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow2.png deleted file mode 100644 index 5424a4af..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow2.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow3.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow3.png deleted file mode 100644 index dbecd8b3..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow3.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow4.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow4.png deleted file mode 100644 index c553e5c6..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow4.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow5.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow5.png deleted file mode 100644 index 591d6ae5..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow5.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow6.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow6.png deleted file mode 100644 index a3aabca3..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow6.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow7.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow7.png deleted file mode 100644 index a46c804e..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow7.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow8.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow8.png deleted file mode 100644 index e6a3d411..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-shadow8.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-1.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-1.png deleted file mode 100644 index 4285fc3c..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-1.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-10.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-10.png deleted file mode 100644 index fc521122..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-10.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-11.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-11.png deleted file mode 100644 index bcfdfcb5..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-11.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-12.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-12.png deleted file mode 100644 index 8c7f230d..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-12.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-2.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-2.png deleted file mode 100644 index 767c1aa5..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-2.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-3.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-3.png deleted file mode 100644 index 1fa77ead..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-3.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-4.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-4.png deleted file mode 100644 index ac0f83a2..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-4.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-5.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-5.png deleted file mode 100644 index eb31e7f1..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-5.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-6.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-6.png deleted file mode 100644 index f0debd7e..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-6.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-7.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-7.png deleted file mode 100644 index 575dddd4..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-7.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-8.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-8.png deleted file mode 100644 index 5e7add01..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-8.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-9.png b/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-9.png deleted file mode 100644 index 1a6517db..00000000 Binary files a/airsonic-main/src/main/webapp/script/fancyzoom/images/zoom-spin-9.png and /dev/null differ diff --git a/airsonic-main/src/main/webapp/script/jquery.fancyzoom.js b/airsonic-main/src/main/webapp/script/jquery.fancyzoom.js new file mode 100644 index 00000000..c5a6474c --- /dev/null +++ b/airsonic-main/src/main/webapp/script/jquery.fancyzoom.js @@ -0,0 +1,230 @@ +/*! + * jQuery FancyZoom Plugin + * version: 1.0.1 (20-APR-2014) + * @requires jQuery v1.6.2 or later + * + * Examples and documentation at: http://github.com/keegnotrub/jquery.fancyzoom/ + * Licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +(function ($) { + "use strict"; + + $.extend(jQuery.easing, { + easeInOutCubic: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t + b; + return c/2*((t-=2)*t*t + 2) + b; + } + }); + + $.fn.fancyZoom = function(settings) { + var options = $.extend({ + minBorder: 90 + }, settings); + + var fz = new FancyZoom(options); + + this.each(function(e) { + var $this = $(this); + $this.mouseover(fz.preload); + $this.click(fz.show); + }); + + function elementGeometry(elemFind) { + var $elemFind = $(elemFind); + + if ($elemFind.children().length > 0) { + $elemFind = $elemFind.children(":first"); + } + + var elemX = $elemFind.offset().left; + var elemY = $elemFind.offset().top; + var elemW = $elemFind.width() || 50; + var elemH = $elemFind.height() || 12; + + return { left: elemX, top: elemY, width: elemW, height: elemH }; + } + + function windowGeometry() { + var $window = $(window); + var w = $window.width(); + var h = $window.height(); + var x = $window.scrollLeft(); + var y = $window.scrollTop(); + return { width: w, height: h, scrollX: x, scrollY: y }; + } + + function FancyZoom(opts) { + var options = opts; + var zooming = false; + var preloading = false; + var pImage = new Image(); + var pTimer = 0; + var pFrame = 0; + var eGeometry, wGeometry; + + var $zoom, $zoom_img, $zoom_close, $zoom_spin; + + var self = this; + + $zoom = $("#zoom"); + if ($zoom.length === 0) { + $zoom = $(document.createElement("div")); + $zoom.attr("id", "zoom"); + $("body").append($zoom); + } + + $zoom_img = $("#zoom_img"); + if ($zoom_img.length === 0) { + $zoom_img = $(document.createElement("img")); + $zoom_img.attr("id", "zoom_img"); + $zoom.append($zoom_img); + } + + $zoom_close = $("#zoom_close"); + if ($zoom_close.length === 0) { + $zoom_close = $(document.createElement("div")); + $zoom_close.attr("id", "zoom_close"); + $zoom.append($zoom_close); + } + + $zoom_spin = $("#zoom_spin"); + if ($zoom_spin.length === 0) { + $zoom_spin = $(document.createElement("div")); + $zoom_spin.attr("id", "zoom_spin"); + $("body").append($zoom_spin); + } + + this.preload = function(e) { + var href = this.getAttribute("href"); + + if (pImage.src !== href) { + preloading = true; + pImage = new Image(); + $(pImage).on('load', function() { + preloading = false; + }); + pImage.src = href; + } + }; + + this.show = function(e) { + wGeometry = windowGeometry(); + eGeometry = elementGeometry(this); + + self.preload.call(this, e); + + if (preloading) { + if (pTimer === 0) { + startSpinner(this); + } + } + else { + zoomIn(this); + } + + e.preventDefault(); + }; + + function runSpinner(from) { + if (preloading) { + $zoom_spin.css("backgroundPosition", "0px " + (pFrame * -50) + "px"); + pFrame = (pFrame + 1) % 12; + } + else { + clearInterval(pTimer); + pTimer = 0; + pFrame = 0; + $zoom_spin.hide(); + zoomIn(from); + } + } + + function startSpinner(from) { + $zoom_spin.css({ + left: ((wGeometry.width / 2) + wGeometry.scrollX) + "px", + top: ((wGeometry.height / 2) + wGeometry.scrollY) + "px", + backgroundPosition: "0px 0px", + display: "block" + }); + pFrame = 0; + pTimer = setInterval(function() { + runSpinner(from); + }, 100); + } + + function zoomIn(from) { + if (zooming) return false; + zooming = true; + + $zoom_img.attr("src", from.getAttribute("href")); + + var endW = pImage.width; + var endH = pImage.height; + + var sizeRatio = endW / endH; + if (endW > wGeometry.width - options.minBorder) { + endW = wGeometry.width - options.minBorder; + endH = endW / sizeRatio; + } + if (endH > wGeometry.height - options.minBorder) { + endH = wGeometry.height - options.minBorder; + endW = endH * sizeRatio; + } + + var endTop = (wGeometry.height/2) - (endH/2) + wGeometry.scrollY; + var endLeft = (wGeometry.width/2) - (endW/2) + wGeometry.scrollX; + + $zoom_close.hide(); + $zoom.hide().css({ + left : eGeometry.left + "px", + top : eGeometry.top + "px", + width : eGeometry.width + "px", + height : eGeometry.height + "px", + opacity : "hide" + }); + + $zoom.animate({ + left : endLeft + 'px', + top : endTop + 'px', + width : endW + "px", + height : endH + "px", + opacity : "show" + }, 200, "easeInOutCubic", function() { + $zoom_close.fadeIn(); + $zoom_close.click(zoomOut); + $zoom.click(zoomOut); + $(document).keyup(closeOnEscape); + zooming = false; + }); + } + + function zoomOut() { + if (zooming) return false; + zooming = true; + + $zoom_close.hide(); + $zoom.animate({ + left : eGeometry.left + "px", + top : eGeometry.top + "px", + opacity : "hide", + width : eGeometry.width + "px", + height : eGeometry.height + "px" + }, 200, "easeInOutCubic", function() { + zooming = false; + }); + + $zoom.unbind('click', zoomOut); + $zoom_close.unbind('click', zoomOut); + $(document).unbind('keyup', closeOnEscape); + } + + function closeOnEscape(event){ + if (event.keyCode == 27) { + zoomOut(); + } + } + } + }; + +})(jQuery); diff --git a/airsonic-main/src/main/webapp/script/spin.png b/airsonic-main/src/main/webapp/script/spin.png new file mode 100644 index 00000000..b9cc54b4 Binary files /dev/null and b/airsonic-main/src/main/webapp/script/spin.png differ diff --git a/airsonic-main/src/main/webapp/style/default-without-mediaelement.css b/airsonic-main/src/main/webapp/style/default-without-mediaelement.css index 8313f6be..447da44c 100644 --- a/airsonic-main/src/main/webapp/style/default-without-mediaelement.css +++ b/airsonic-main/src/main/webapp/style/default-without-mediaelement.css @@ -440,3 +440,9 @@ img { width : 200px; height : 4px; } + +/* Javascript-zoom related styles */ +#zoom { position: absolute; display: none; z-index: 499; -webkit-box-shadow: 0px 5px 25px #000; -moz-box-shadow: 0px 5px 25px #000; box-shadow: 0px 5px 25px #000; } +#zoom_img { display: block; cursor: pointer; width: 100%; border: 0; margin: 0; padding: 0; } +#zoom_close { position: absolute; display: none; cursor: pointer; left: -15px; top: -15px; width: 30px; height: 30px; background: url(/script/closebox.png) no-repeat; } +#zoom_spin { position: absolute; display: none; z-index: 525; width: 50px; height: 50px; background: url(/script/spin.png) no-repeat; }