Related
I have following JS code (found here, on stackoverflow, and a little-bit modded), which resize image on client side using canvas.
function FileListItem(a) {
// Necesary to proper-work of CatchFile function (especially image-resizing).
// Code by Jimmy Wärting (https://github.com/jimmywarting)
a = [].slice.call(Array.isArray(a) ? a : arguments)
for (var c, b = c = a.length, d = !0; b-- && d;) d = a[b] instanceof File
if (!d) throw new TypeError('expected argument to FileList is File or array of File objects')
for (b = (new ClipboardEvent('')).clipboardData || new DataTransfer; c--;) b.items.add(a[c])
return b.files
}
function CatchFile(obj) {
// Based on ResizeImage function.
// Original code by Jimmy Wärting (https://github.com/jimmywarting)
var file = obj.files[0];
// Check that file is image (regex)
var imageReg = /[\/.](gif|jpg|jpeg|tiff|png|bmp)$/i;
if (!file) return
var uploadButtonsDiv = document.getElementById('upload_buttons_area');
// Check, that it is first uploaded file, or not
// If first, draw a div for showing status
var uploadStatusDiv = document.getElementById('upload_status_area');
if (!uploadStatusDiv) {
var uploadStatusDiv = document.createElement('div');
uploadStatusDiv.setAttribute('class', 'upload-status-area');
uploadStatusDiv.setAttribute('id', 'upload_status_area');
uploadButtonsDiv.parentNode.insertBefore(uploadStatusDiv, uploadButtonsDiv.nextSibling);
// Draw sub-div for each input field
var i;
for (i = 0; i < 3; i++) {
var uploadStatus = document.createElement('div');
uploadStatus.setAttribute('class', 'upload-status');
uploadStatus.setAttribute('id', ('upload_status_id_commentfile_set-' + i + '-file'));
uploadStatusDiv.append(uploadStatus);
}
}
var canvasDiv = document.getElementById('canvas-area');
var currField = document.getElementById(obj.id);
var currFieldLabel = document.getElementById(('label_' + obj.id));
// Main image-converting procedure
if (imageReg.test(file.name)) {
file.image().then(img => {
const canvas = document.createElement('canvas')
canvas.setAttribute('id', ('canvas_' + obj.id));
const ctx = canvas.getContext('2d')
const maxWidth = 1600
const maxHeight = 1200
// Calculate new size
const ratio = Math.min(maxWidth / img.width, maxHeight / img.height)
const width = img.width * ratio + .5|0
const height = img.height * ratio + .5|0
// Resize the canvas to the new dimensions
canvas.width = width
canvas.height = height
// Drawing canvas-object is necessary to proper-work
// on mobile browsers.
// In this case, canvas is inserted to hidden div (display: none)
ctx.drawImage(img, 0, 0, width, height)
canvasDiv.appendChild(canvas)
// Get the binary (aka blob)
canvas.toBlob(blob => {
const resizedFile = new File([blob], file.name, file)
const fileList = new FileListItem(resizedFile)
// Temporary remove event listener since
// assigning a new filelist to the input
// will trigger a new change event...
obj.onchange = null
obj.files = fileList
obj.onchange = CatchFile
}, 'image/jpeg', 0.70)
}
)
// If file is image, during conversion show status
function ShowConvertConfirmation() {
if (document.getElementById('canvas_' + obj.id)) {
document.getElementById(('upload_status_' + obj.id)).innerHTML =
'<font color="#4CAF50">Konwertowanie pliku ' + file.name + ' zakończone!</font>';
return true;
}
else {
document.getElementById(('upload_status_' + obj.id)).innerHTML =
'<font color="#4CAF50">Konwertowanie pliku ' + file.name + ' zakończone!</font>';
return false;
}
}
// Loop ShowConvertConfirmation function untill return true (file is converted)
var convertConfirmationLoop = setInterval(function() {
var isConfirmed = ShowConvertConfirmation();
if (!isConfirmed) {
ShowConvertConfirmation();
}
else {
// Break loop
clearInterval(convertConfirmationLoop);
}
}, 2000); // Check every 2000ms
}
// If file is not an image, show status with filename
else {
document.getElementById(('upload_status_' + obj.id)).innerHTML =
'<font color="#4CAF50">Dodano plik ' + file.name + '</font>';
//uploadStatusDiv.append(uploadStatus);
}
}
Canvas is drawn in hidden div:
<div id="canvas-area" style="overflow: hidden; height: 0;"></div>
I am only detect, that div canvas-area is presented and basing on this, JS append another div with status.
Unfortunatelly on some mobile devices (mid-range smartphones), message will be showed before finish of drawing (it is wrong). Due to this, some uploaded images are corrupted or stay in original size.
How to prevent this?
Everything that should happen after the image has loaded, should be executed within the then callback, or called from within it.
It is important to realise that the code that is not within that callback will execute immediately, well before the drawing has completed.
I have a class, that is supposed to display grey overlay over page and display text and loading gif. Code looks like this:
function LoadingIcon(imgSrc) {
var elem_loader = document.createElement('div'),
elem_messageSpan = document.createElement('span'),
loaderVisible = false;
elem_loader.style.position = 'absolute';
elem_loader.style.left = '0';
elem_loader.style.top = '0';
elem_loader.style.width = '100%';
elem_loader.style.height = '100%';
elem_loader.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
elem_loader.style.textAlign = 'center';
elem_loader.appendChild(elem_messageSpan);
elem_loader.innerHTML += '<br><img src="' + imgSrc + '">';
elem_messageSpan.style.backgroundColor = '#f00';
this.start = function () {
document.body.appendChild(elem_loader);
loaderVisible = true;
};
this.stop = function() {
if (loaderVisible) {
document.body.removeChild(elem_loader);
loaderVisible = false;
}
};
this.setText = function(text) {
elem_messageSpan.innerHTML = text;
};
this.getElems = function() {
return [elem_loader, elem_messageSpan];
};
}
Problem is, when I use setText method, it sets innerHTML of elem_messageSpan, but it doesn't reflect to the span, that was appended to elem_loader. You can use getElems method to find out what both elements contains.
Where is the problem? Because I don't see single reason why this shouldn't work.
EDIT:
I call it like this:
var xml = new CwgParser('cwg.geog.cz/cwg.xml'),
loader = new LoadingIcon('./ajax-loader.gif');
xml.ondataparse = function() {
loader.stop();
document.getElementById('cover').style.display = 'block';
};
loader.setText('Loading CWG list...');
loader.start();
xml.loadXML();
xml.loadXML() is function that usually takes 3 - 8 seconds to execute (based on download speed of client), thats why I'm displaying loading icon.
So, I've been working on an mp3 player that doesn't use Flash, just JS, HTML, and CSS. I took some open source code and have been playing with it, however I had to edit it when I started using JSONP to get the "link" of the MP3 file from another website. I had issues getting any of the JS function calls in the HTML to work, so I used JQUERY bind and that fixed everything but duration function and clientx issues. link = foo.mp3
function writePlayer(link){
$('<div id=\"main\"><h2>Episode</h2><div id=\"player\"><input id=\"playButton\" class=\'player_control\' type=\"button\" onClick=\"playClicked(this);\" value=\">\"><div id=\"duration\" class=\'player_control\' ><div id=\"duration_background\" onClick=\"durationClicked(event);\"><div id=\"duration_bar\" class=\'duration_bar\'></div></div></div><div id=\"volume_control\" class=\'player_control\' onClick=\"volumeChangeClicked(event);\"><div id=\"volume_background\"><div id=\"volume_bar\"></div></div></div><input type=\"button\" class=\'player_control\' id=\"volume_button\" onClick=\"volumeClicked();\" value=\"Vol\"></div><audio id=\"aplayer\" src='+ link +' type=\"audio/mp3\" onTimeUpdate=\"update();\" onEnded=\"trackEnded();\"><b>Your browser does not support the <code>audio</code> element. </b></audio><div id=\"msg\" class=\'output\'></div><div id=\"content\"><p></p></div></div></div>').appendTo('body');
$(document).ready(pageLoaded)
$("#playButton").bind('click',playClicked(this))
$("#duration_background").bind('click',durationClicked(event))
$("#volume_control").bind('click',volumeChangeClicked(event))
$("#volume_button").bind('click',volumeClicked(event))
$("#aplayer").bind('timeUpdate',update())
$("#aplayer").bind('ended',trackEnded())
};
var audio_duration;
var audio_player;
var volume_button;
var volume_control;
function pageLoaded()
{
audio_player = document.getElementById("aplayer");
alert(audio_player);
volume_button = document.getElementById('volume_button');
volume_control = document.getElementById('volume_control');
//get the duration
audio_duration = audio_player.duration;
//set the volume
set_volume(0.7);
}
function set_volume(new_volume)
{
audio_player.volume = new_volume;
update_volume_bar();
volume_button.value = "Volume: "+parseInt(new_volume*100);
}
function update_volume_bar()
{
new_top = volume_button.offsetHeight - volume_control.offsetHeight;
volume_control.style.top = new_top+"px";
volume = audio_player.volume;
//change the size of the volume bar
wrapper = document.getElementById("volume_background");
wrapper_height = wrapper.offsetHeight;
wrapper_top = wrapper.offsetTop;
new_height= wrapper_height*volume;
volume_bar = document.getElementById("volume_bar");
volume_bar.style.height=new_height+"px";
new_top = wrapper_top + ( wrapper_height - new_height );
volume_bar.style.top=new_top+"px";
}
function update(audio_player)
{
//get the duration of the player
dur = audio_player.duration;
time = audio_player.currentTime;
fraction = time/dur;
percent = (fraction*100);
wrapper = document.getElementById("duration_background");
new_width = wrapper.offsetWidth*fraction;
document.getElementById("duration_bar").style.width=new_width+"px";
}
function playClicked(element)
{
//get the state of the player
if(audio_player.paused)
{
audio_player.play();
newdisplay = "| |";
}else{
audio_player.pause();
newdisplay = ">";
}
element.value=newdisplay;
}
function trackEnded()
{
//reset the playControl to 'play'
document.getElementById("playButton").value=">";
}
function volumeClicked(event)
{
control = document.getElementById('volume_control');
if(control.style.display=="block")
{
control.style.display="None";
}else{
control.style.display="Block";
update_volume_bar();
}
}
function volumeChangeClicked(event)
{
//get the position of the event
clientY = event.clientY;
offset = event.currentTarget.offsetTop + event.currentTarget.offsetHeight - clientY;
volume = offset/event.currentTarget.offsetHeight;
set_volume(volume);
update_volume_bar();
}
function durationClicked(event)
{
//get the position of the event
clientX = event.clientX;
left = event.currentTarget.offsetLeft;
clickoffset = clientX - left;
percent = clickoffset/event.currentTarget.offsetWidth;
duration_seek = percent*audio_duration;
document.getElementById("aplayer").currentTime=duration_seek;
};
</script>
Thank you very much for your help!
I've got a little problem here. I've been trying to do an image gallery with JavaScript but there's something that I got a problem with. I can get the image to resize when the first image load, but as soon as I load another image, it won't resize anymore! Since the user will be able to upload a lot of different size pictures, I really need to make it work.
I've checked for ready-to-use image gallery and such and nothing was doing what I need to do.
Here's my javascript:
function changeCurrentImage(conteneur)
{
var img = conteneur.getElementsByTagName("img");
var imgUrl = img[0].src;
var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9);
var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.'));
var currentImg = document.getElementById('currentImage');
currentImg.src = imgFirstPart + "borne" + imgLastPart;
resize(document.getElementById('currentImage'), 375, 655);
}
function resize(img, maxh, maxw) {
var ratio = maxh/maxw;
if (img.height/img.width > ratio){
// height is the problem
if (img.height > maxh){
img.width = Math.round(img.width*(maxh/img.height));
img.height = maxh;
}
} else {
// width is the problem
if (img.width > maxw){
img.height = Math.round(img.height*(maxw/img.width));
img.width = maxw;
}
}
};
Here's the HTML (using ASP.Net Repeater):
<asp:Repeater ID="rptImages" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<a href="#">
<div id="thumbnailImageContainer1" onclick="changeCurrentImage(this)">
<div id="thumbnailImageContainer2">
<img id="thumbnailImage" src="<%# SiteUrl + Eval("ImageThumbnailPath")%>?rn=<%=Random()%>" alt="Photo" onload="resize(this, 60, 105)" />
</div>
</div>
</a>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
Most likely the image is not yet downloaded so img.height and img.width are not yet there. Technically you don't need to wait till the whole image is downloaded, you can poll the image in a timer until width and height are non-zero. This sounds messy but can be done nicely if you take the time to do it right. (I have an ImageLoader utility I made for this purpose....has only one timer even if it is handling multiple images at once, and calls a callback function when it has the sizes) I have to disagree with Marcel....client side works great for this sort of thing, and can work even if the images are from a source other than your server.
Edit: add ImageLoader utility:
var ImageLoader = {
maxChecks: 1000,
list: [],
intervalHandle : null,
loadImage : function (callback, url, userdata) {
var img = new Image ();
img.src = url;
if (img.width && img.height) {
callback (img.width, img.height, url, 0, userdata);
}
else {
var obj = {image: img, url: url, callback: callback,
checks: 1, userdata: userdata};
var i;
for (i=0; i < this.list.length; i++) {
if (this.list[i] == null)
break;
}
this.list[i] = obj;
if (!this.intervalHandle)
this.intervalHandle = setInterval(this.interval, 30);
}
},
// called by setInterval
interval : function () {
var count = 0;
var list = ImageLoader.list, item;
for (var i=0; i<list.length; i++) {
item = list[i];
if (item != null) {
if (item.image.width && item.image.height) {
item.callback (item.image.width, item.image.height,
item.url, item.checks, item.userdata);
ImageLoader.list[i] = null;
}
else if (item.checks > ImageLoader.maxChecks) {
item.callback (0, 0, item.url, item.checks, item.userdata);
ImageLoader.list[i] = null;
}
else {
count++;
item.checks++;
}
}
}
if (count == 0) {
ImageLoader.list = [];
clearInterval (ImageLoader.intervalHandle);
delete ImageLoader.intervalHandle;
}
}
};
Example usage:
var callback = function (width, height, url, checks, userdata) {
// show stuff in the title
document.title = "w: " + width + ", h:" + height +
", url:" + url + ", checks:" + checks + ", userdata: " + userdata;
var img = document.createElement("IMG");
img.src = url;
// size it to be 100 px wide, and the correct
// height for its aspect ratio
img.style.width = "100px";
img.style.height = ((height/width)*100) + "px";
document.body.appendChild (img);
};
ImageLoader.loadImage (callback,
"http://upload.wikimedia.org/wikipedia/commons/thumb/" +
"1/19/Caerulea3_crop.jpg/800px-Caerulea3_crop.jpg", 1);
ImageLoader.loadImage (callback,
"http://upload.wikimedia.org/wikipedia/commons/thumb/" +
"8/85/Calliphora_sp_Portrait.jpg/402px-Calliphora_sp_Portrait.jpg", 2);
With the way you have your code setup, I would try and call your resize function from an onload event.
function resize() {
var img = document.getElementById('currentImage');
var maxh = 375;
var maxw = 655;
var ratio = maxh/maxw;
if (img.height/img.width > ratio){
// height is the problem
if (img.height > maxh){
img.width = Math.round(img.width*(maxh/img.height));
img.height = maxh;
}
} else {
// width is the problem
if (img.width > maxw){
img.height = Math.round(img.height*(maxw/img.width));
img.width = maxw;
}
}
};
function changeCurrentImage(conteneur)
{
var img = conteneur.getElementsByTagName("img");
img.onload = resize;
var imgUrl = img[0].src;
var imgFirstPart = imgUrl.substring(0, imgUrl.lastIndexOf('.') - 9);
var imgLastPart = imgUrl.substring(imgUrl.lastIndexOf('.'));
var currentImg = document.getElementById('currentImage');
currentImg.src = imgFirstPart + "borne" + imgLastPart;
}
I would play around with that. Maybe use global variables for your maxH/W and image ID(s);
#Comments: No, I can't do that server side since it would refresh the page everytime someone click on a new image. That would be way too bothersome and annoying for the users.
As for the thumbnails, those image are already saved in the appropriate size. Only the big image that shows is about 33% of its size. Since we already have 3 images PER uploaded images, I didn't want to upload a 4th one for each upload, that would take too much server space!
As for the "currentImage", I forgot to add it, so that might be helful lol:
<div id="currentImageContainer">
<div id="currentImageContainer1">
<div id="currentImageContainer2">
<img id="currentImage" src="#" alt="" onload="resize(this, 375, 655)" />
</div>
</div>
</div>
#rob: I'll try the ImageLoader class, that might do the trick.
I found an alternative that is working really well. Instead of changing that IMG width and height, I delete it and create a new one:
function changeCurrentImage(conteneur)
{
var thumbnailImg = conteneur.getElementsByTagName("img");
var thumbnailImgUrl = thumbnailImg[0].src;
var newImgUrl = thumbnailImgUrl.replace("thumbnail", "borne");
var currentImgDiv = document.getElementById('currentImageContainer2');
var currentImg = currentImgDiv.getElementById("currentImage");
if (currentImg != null)
{
currentImgDiv.removeChild(currentImg);
}
var newImg = document.createElement("img");
newImageDiv = document.getElementById('currentImageContainer2');
newImg.id = "currentImage";
newImg.onload = function() {
Resize(newImg, 375, 655);
newImageDiv.appendChild(newImg);
}
newImg.src = newImgUrl;
}
Also, in case people wonder, you MUST put the .onload before the .src when assigning an a new source for an image!
Yesterday a nice stack overflow user helped me to trigger the Jquery Prettyphoto Lightbox from a DIV element rather than an A element.
You can find that solution here
This works... Almost.
Pretty Photo looks for all the links that reference it and then compiles them into a slideshow of iframes. Normally when you click on a link it will open up the iframe lightbox corresponding to the link i clicked on.
However with this new DIV solution it is opening up to the first iframe link it finds on the page, rather than the link I click on.
This must obviously be happening because I have altered the javascript call code from
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$("a[rel^='prettyPhoto[iframes]']").prettyPhoto();
});
</script>
to
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$("div[class^='prettyphoto[iframes]']").prettyPhoto();
});
</script>
I have been going through the other JS files but I am not a javascript programmer.
I am going to post the entire JS file. Maybe someone can see what javascript I need to change to make this DIV element work like an A element.
(function($) {
$.prettyPhoto = {version: '2.5.4'};
$.fn.prettyPhoto = function(settings) {
settings = jQuery.extend({
animationSpeed: 'normal', /* fast/slow/normal */
padding: 40, /* padding for each side of the picture */
opacity: 0.80, /* Value between 0 and 1 */
showTitle: true, /* true/false */
allowresize: true, /* true/false */
counter_separator_label: '/', /* The separator for the gallery counter 1 "of" 2 */
theme: 'light_rounded', /* light_rounded / dark_rounded / light_square / dark_square */
hideflash: false, /* Hides all the flash object on a page, set to TRUE if flash appears over prettyPhoto */
modal: false, /* If set to true, only the close button will close the window */
changepicturecallback: function(){}, /* Called everytime an item is shown/changed */
callback: function(){} /* Called when prettyPhoto is closed */
}, settings);
// Fallback to a supported theme for IE6
if($.browser.msie && $.browser.version == 6){
settings.theme = "light_square";
}
if($('.pp_overlay').size() == 0) {
_buildOverlay(); // If the overlay is not there, inject it!
}else{
// Set my global selectors
$pp_pic_holder = $('.pp_pic_holder');
$ppt = $('.ppt');
}
// Global variables accessible only by prettyPhoto
var doresize = true, percentBased = false, correctSizes,
// Cached selectors
$pp_pic_holder, $ppt,
// prettyPhoto container specific
pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth, pp_type = 'image',
//Gallery specific
setPosition = 0,
// Global elements
$scrollPos = _getScroll();
// Window/Keyboard events
$(window).scroll(function(){ $scrollPos = _getScroll(); _centerOverlay(); _resizeOverlay(); });
$(window).resize(function(){ _centerOverlay(); _resizeOverlay(); });
$(document).keydown(function(e){
if($pp_pic_holder.is(':visible'))
switch(e.keyCode){
case 37:
$.prettyPhoto.changePage('previous');
break;
case 39:
$.prettyPhoto.changePage('next');
break;
case 27:
if(!settings.modal)
$.prettyPhoto.close();
break;
};
});
// Bind the code to each links
$(this).each(function(){
$(this).bind('click',function(){
link = this; // Fix scoping
// Find out if the picture is part of a set
theRel = $(this).attr('rel');
galleryRegExp = /\[(?:.*)\]/;
theGallery = galleryRegExp.exec(theRel);
// Build the gallery array
var images = new Array(), titles = new Array(), descriptions = new Array();
if(theGallery){
$('a[rel*='+theGallery+']').each(function(i){
if($(this)[0] === $(link)[0]) setPosition = i; // Get the position in the set
images.push($(this).attr('href'));
titles.push($(this).find('img').attr('alt'));
descriptions.push($(this).attr('title'));
});
}else{
images = $(this).attr('href');
titles = ($(this).find('img').attr('alt')) ? $(this).find('img').attr('alt') : '';
descriptions = ($(this).attr('title')) ? $(this).attr('title') : '';
}
$.prettyPhoto.open(images,titles,descriptions);
return false;
});
});
/**
* Opens the prettyPhoto modal box.
* #param image {String,Array} Full path to the image to be open, can also be an array containing full images paths.
* #param title {String,Array} The title to be displayed with the picture, can also be an array containing all the titles.
* #param description {String,Array} The description to be displayed with the picture, can also be an array containing all the descriptions.
*/
$.prettyPhoto.open = function(gallery_images,gallery_titles,gallery_descriptions) {
// To fix the bug with IE select boxes
if($.browser.msie && $.browser.version == 6){
$('select').css('visibility','hidden');
};
// Hide the flash
if(settings.hideflash) $('object,embed').css('visibility','hidden');
// Convert everything to an array in the case it's a single item
images = $.makeArray(gallery_images);
titles = $.makeArray(gallery_titles);
descriptions = $.makeArray(gallery_descriptions);
if($('.pp_overlay').size() == 0) {
_buildOverlay(); // If the overlay is not there, inject it!
}else{
// Set my global selectors
$pp_pic_holder = $('.pp_pic_holder');
$ppt = $('.ppt');
}
$pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
isSet = ($(images).size() > 0) ? true : false; // Find out if it's a set
_getFileType(images[setPosition]); // Set the proper file type
_centerOverlay(); // Center it
// Hide the next/previous links if on first or last images.
_checkPosition($(images).size());
$('.pp_loaderIcon').show(); // Do I need to explain?
// Fade the content in
$('div.pp_overlay').show().fadeTo(settings.animationSpeed,settings.opacity, function(){
$pp_pic_holder.fadeIn(settings.animationSpeed,function(){
// Display the current position
$pp_pic_holder.find('p.currentTextHolder').text((setPosition+1) + settings.counter_separator_label + $(images).size());
// Set the description
if(descriptions[setPosition]){
$pp_pic_holder.find('.pp_description').show().html(unescape(descriptions[setPosition]));
}else{
$pp_pic_holder.find('.pp_description').hide().text('');
};
// Set the title
if(titles[setPosition] && settings.showTitle){
hasTitle = true;
$ppt.html(unescape(titles[setPosition]));
}else{
hasTitle = false;
};
// Inject the proper content
if(pp_type == 'image'){
// Set the new image
imgPreloader = new Image();
// Preload the neighbour images
nextImage = new Image();
if(isSet && setPosition > $(images).size()) nextImage.src = images[setPosition + 1];
prevImage = new Image();
if(isSet && images[setPosition - 1]) prevImage.src = images[setPosition - 1];
pp_typeMarkup = '<img id="fullResImage" src="" />';
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = pp_typeMarkup;
$pp_pic_holder.find('.pp_content').css('overflow','hidden');
$pp_pic_holder.find('#fullResImage').attr('src',images[setPosition]);
imgPreloader.onload = function(){
// Fit item to viewport
correctSizes = _fitToViewport(imgPreloader.width,imgPreloader.height);
_showContent();
};
imgPreloader.src = images[setPosition];
}else{
// Get the dimensions
movie_width = ( parseFloat(grab_param('width',images[setPosition])) ) ? grab_param('width',images[setPosition]) : "425";
movie_height = ( parseFloat(grab_param('height',images[setPosition])) ) ? grab_param('height',images[setPosition]) : "344";
// If the size is % based, calculate according to window dimensions
if(movie_width.indexOf('%') != -1 || movie_height.indexOf('%') != -1){
movie_height = ($(window).height() * parseFloat(movie_height) / 100) - 100;
movie_width = ($(window).width() * parseFloat(movie_width) / 100) - 100;
percentBased = true;
}
movie_height = parseFloat(movie_height);
movie_width = parseFloat(movie_width);
if(pp_type == 'quicktime') movie_height+=15; // Add space for the control bar
// Fit item to viewport
correctSizes = _fitToViewport(movie_width,movie_height);
if(pp_type == 'youtube'){
pp_typeMarkup = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+correctSizes['width']+'" height="'+correctSizes['height']+'"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://www.youtube.com/v/'+grab_param('v',images[setPosition])+'" /><embed src="http://www.youtube.com/v/'+grab_param('v',images[setPosition])+'" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="'+correctSizes['width']+'" height="'+correctSizes['height']+'"></embed></object>';
}else if(pp_type == 'quicktime'){
pp_typeMarkup = '<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/qtactivex/qtplugin.cab" height="'+correctSizes['height']+'" width="'+correctSizes['width']+'"><param name="src" value="'+images[setPosition]+'"><param name="autoplay" value="true"><param name="type" value="video/quicktime"><embed src="'+images[setPosition]+'" height="'+correctSizes['height']+'" width="'+correctSizes['width']+'" autoplay="true" type="video/quicktime" pluginspage="http://www.apple.com/quicktime/download/"></embed></object>';
}else if(pp_type == 'flash'){
flash_vars = images[setPosition];
flash_vars = flash_vars.substring(images[setPosition].indexOf('flashvars') + 10,images[setPosition].length);
filename = images[setPosition];
filename = filename.substring(0,filename.indexOf('?'));
pp_typeMarkup = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+correctSizes['width']+'" height="'+correctSizes['height']+'"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="'+filename+'?'+flash_vars+'" /><embed src="'+filename+'?'+flash_vars+'" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="'+correctSizes['width']+'" height="'+correctSizes['height']+'"></embed></object>';
}else if(pp_type == 'iframe'){
movie_url = images[setPosition];
movie_url = movie_url.substr(0,movie_url.indexOf('iframe')-1);
pp_typeMarkup = '<iframe src ="'+movie_url+'" width="'+(correctSizes['width']-10)+'" height="'+(correctSizes['height']-10)+'" frameborder="no"></iframe>';
}
// Show content
_showContent();
}
});
});
};
/**
* Change page in the prettyPhoto modal box
* #param direction {String} Direction of the paging, previous or next.
*/
$.prettyPhoto.changePage = function(direction){
if(direction == 'previous') {
setPosition--;
if (setPosition < 0){
setPosition = 0;
return;
}
}else{
if($('.pp_arrow_next').is('.disabled')) return;
setPosition++;
};
// Allow the resizing of the images
if(!doresize) doresize = true;
_hideContent();
$('a.pp_expand,a.pp_contract').fadeOut(settings.animationSpeed,function(){
$(this).removeClass('pp_contract').addClass('pp_expand');
$.prettyPhoto.open(images,titles,descriptions);
});
};
/**
* Closes the prettyPhoto modal box.
*/
$.prettyPhoto.close = function(){
$pp_pic_holder.find('object,embed').css('visibility','hidden');
$('div.pp_pic_holder,div.ppt').fadeOut(settings.animationSpeed);
$('div.pp_overlay').fadeOut(settings.animationSpeed, function(){
$('div.pp_overlay,div.pp_pic_holder,div.ppt').remove();
// To fix the bug with IE select boxes
if($.browser.msie && $.browser.version == 6){
$('select').css('visibility','visible');
};
// Show the flash
if(settings.hideflash) $('object,embed').css('visibility','visible');
setPosition = 0;
settings.callback();
});
doresize = true;
};
/**
* Set the proper sizes on the containers and animate the content in.
*/
_showContent = function(){
$('.pp_loaderIcon').hide();
if($.browser.opera) {
windowHeight = window.innerHeight;
windowWidth = window.innerWidth;
}else{
windowHeight = $(window).height();
windowWidth = $(window).width();
};
// Calculate the opened top position of the pic holder
projectedTop = $scrollPos['scrollTop'] + ((windowHeight/2) - (correctSizes['containerHeight']/2));
if(projectedTop < 0) projectedTop = 0 + $pp_pic_holder.find('.ppt').height();
// Resize the content holder
$pp_pic_holder.find('.pp_content').animate({'height':correctSizes['contentHeight']},settings.animationSpeed);
// Resize picture the holder
$pp_pic_holder.animate({
'top': projectedTop,
'left': ((windowWidth/2) - (correctSizes['containerWidth']/2)),
'width': correctSizes['containerWidth']
},settings.animationSpeed,function(){
$pp_pic_holder.width(correctSizes['containerWidth']);
$pp_pic_holder.find('.pp_hoverContainer,#fullResImage').height(correctSizes['height']).width(correctSizes['width']);
// Fade the new image
$pp_pic_holder.find('#pp_full_res').fadeIn(settings.animationSpeed);
// Show the nav
if(isSet && pp_type=="image") { $pp_pic_holder.find('.pp_hoverContainer').fadeIn(settings.animationSpeed); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
$pp_pic_holder.find('.pp_details').fadeIn(settings.animationSpeed);
// Show the title
if(settings.showTitle && hasTitle){
$ppt.css({
'top' : $pp_pic_holder.offset().top - 20,
'left' : $pp_pic_holder.offset().left + (settings.padding/2),
'display' : 'none'
});
$ppt.fadeIn(settings.animationSpeed);
};
// Fade the resizing link if the image is resized
if(correctSizes['resized']) $('a.pp_expand,a.pp_contract').fadeIn(settings.animationSpeed);
// Once everything is done, inject the content if it's now a photo
if(pp_type != 'image') $pp_pic_holder.find('#pp_full_res')[0].innerHTML = pp_typeMarkup;
// Callback!
settings.changepicturecallback();
});
};
/**
* Hide the content...DUH!
*/
function _hideContent(){
// Fade out the current picture
$pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
$pp_pic_holder.find('.pp_hoverContainer,.pp_details').fadeOut(settings.animationSpeed);
$pp_pic_holder.find('#pp_full_res').fadeOut(settings.animationSpeed,function(){
$('.pp_loaderIcon').show();
});
// Hide the title
$ppt.fadeOut(settings.animationSpeed);
}
/**
* Check the item position in the gallery array, hide or show the navigation links
* #param setCount {integer} The total number of items in the set
*/
function _checkPosition(setCount){
// If at the end, hide the next link
if(setPosition == setCount-1) {
$pp_pic_holder.find('a.pp_next').css('visibility','hidden');
$pp_pic_holder.find('a.pp_arrow_next').addClass('disabled').unbind('click');
}else{
$pp_pic_holder.find('a.pp_next').css('visibility','visible');
$pp_pic_holder.find('a.pp_arrow_next.disabled').removeClass('disabled').bind('click',function(){
$.prettyPhoto.changePage('next');
return false;
});
};
// If at the beginning, hide the previous link
if(setPosition == 0) {
$pp_pic_holder.find('a.pp_previous').css('visibility','hidden');
$pp_pic_holder.find('a.pp_arrow_previous').addClass('disabled').unbind('click');
}else{
$pp_pic_holder.find('a.pp_previous').css('visibility','visible');
$pp_pic_holder.find('a.pp_arrow_previous.disabled').removeClass('disabled').bind('click',function(){
$.prettyPhoto.changePage('previous');
return false;
});
};
// Hide the bottom nav if it's not a set.
if(setCount > 1) {
$('.pp_nav').show();
}else{
$('.pp_nav').hide();
}
};
/**
* Resize the item dimensions if it's bigger than the viewport
* #param width {integer} Width of the item to be opened
* #param height {integer} Height of the item to be opened
* #return An array containin the "fitted" dimensions
*/
function _fitToViewport(width,height){
hasBeenResized = false;
_getDimensions(width,height);
// Define them in case there's no resize needed
imageWidth = width;
imageHeight = height;
windowHeight = $(window).height();
windowWidth = $(window).width();
if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allowresize && !percentBased) {
hasBeenResized = true;
notFitting = true;
while (notFitting){
if((pp_containerWidth > windowWidth)){
imageWidth = (windowWidth - 200);
imageHeight = (height/width) * imageWidth;
}else if((pp_containerHeight > windowHeight)){
imageHeight = (windowHeight - 200);
imageWidth = (width/height) * imageHeight;
}else{
notFitting = false;
};
pp_containerHeight = imageHeight;
pp_containerWidth = imageWidth;
};
_getDimensions(imageWidth,imageHeight);
};
return {
width:imageWidth,
height:imageHeight,
containerHeight:pp_containerHeight,
containerWidth:pp_containerWidth,
contentHeight:pp_contentHeight,
contentWidth:pp_contentWidth,
resized:hasBeenResized
};
};
/**
* Get the containers dimensions according to the item size
* #param width {integer} Width of the item to be opened
* #param height {integer} Height of the item to be opened
*/
function _getDimensions(width,height){
$pp_pic_holder.find('.pp_details').width(width).find('.pp_description').width(width - parseFloat($pp_pic_holder.find('a.pp_close').css('width'))); /* To have the correct height */
// Get the container size, to resize the holder to the right dimensions
pp_contentHeight = height + $pp_pic_holder.find('.pp_details').height() + parseFloat($pp_pic_holder.find('.pp_details').css('marginTop')) + parseFloat($pp_pic_holder.find('.pp_details').css('marginBottom'));
pp_contentWidth = width;
pp_containerHeight = pp_contentHeight + $pp_pic_holder.find('.ppt').height() + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
pp_containerWidth = width + settings.padding;
}
function _getFileType(itemSrc){
if (itemSrc.match(/youtube\.com\/watch/i)) {
pp_type = 'youtube';
}else if(itemSrc.indexOf('.mov') != -1){
pp_type = 'quicktime';
}else if(itemSrc.indexOf('.swf') != -1){
pp_type = 'flash';
}else if(itemSrc.indexOf('iframe') != -1){
pp_type = 'iframe'
}else{
pp_type = 'image';
};
};
function _centerOverlay(){
if($.browser.opera) {
windowHeight = window.innerHeight;
windowWidth = window.innerWidth;
}else{
windowHeight = $(window).height();
windowWidth = $(window).width();
};
if(doresize) {
$pHeight = $pp_pic_holder.height();
$pWidth = $pp_pic_holder.width();
$tHeight = $ppt.height();
projectedTop = (windowHeight/2) + $scrollPos['scrollTop'] - ($pHeight/2);
if(projectedTop < 0) projectedTop = 0 + $tHeight;
$pp_pic_holder.css({
'top': projectedTop,
'left': (windowWidth/2) + $scrollPos['scrollLeft'] - ($pWidth/2)
});
$ppt.css({
'top' : projectedTop - $tHeight,
'left' : (windowWidth/2) + $scrollPos['scrollLeft'] - ($pWidth/2) + (settings.padding/2)
});
};
};
function _getScroll(){
if (self.pageYOffset) {
scrollTop = self.pageYOffset;
scrollLeft = self.pageXOffset;
} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
scrollTop = document.documentElement.scrollTop;
scrollLeft = document.documentElement.scrollLeft;
} else if (document.body) {// all other Explorers
scrollTop = document.body.scrollTop;
scrollLeft = document.body.scrollLeft;
}
return {scrollTop:scrollTop,scrollLeft:scrollLeft};
};
function _resizeOverlay() {
$('div.pp_overlay').css({
'height':$(document).height(),
'width':$(window).width()
});
};
function _buildOverlay(){
toInject = "";
// Build the background overlay div
toInject += "<div class='pp_overlay'></div>";
// Basic HTML for the picture holder
toInject += '<div class="pp_pic_holder"><div class="pp_top"><div class="pp_left"></div><div class="pp_middle"></div><div class="pp_right"></div></div><div class="pp_content">Expand<div class="pp_loaderIcon"></div><div class="pp_hoverContainer"><a class="pp_next" href="#">next</a><a class="pp_previous" href="#">previous</a></div><div id="pp_full_res"></div><div class="pp_details clearfix"><a class="pp_close" href="#">Close</a><p class="pp_description"></p><div class="pp_nav">Previous<p class="currentTextHolder">0'+settings.counter_separator_label+'0</p>Next</div></div></div><div class="pp_bottom"><div class="pp_left"></div><div class="pp_middle"></div><div class="pp_right"></div></div></div>';
// Basic html for the title holder
toInject += '<div class="ppt"></div>';
$('body').append(toInject);
// So it fades nicely
$('div.pp_overlay').css('opacity',0);
// Set my global selectors
$pp_pic_holder = $('.pp_pic_holder');
$ppt = $('.ppt');
$('div.pp_overlay').css('height',$(document).height()).hide().bind('click',function(){
if(!settings.modal)
$.prettyPhoto.close();
});
$('a.pp_close').bind('click',function(){ $.prettyPhoto.close(); return false; });
$('a.pp_expand').bind('click',function(){
$this = $(this); // Fix scoping
// Expand the image
if($this.hasClass('pp_expand')){
$this.removeClass('pp_expand').addClass('pp_contract');
doresize = false;
}else{
$this.removeClass('pp_contract').addClass('pp_expand');
doresize = true;
};
_hideContent();
$pp_pic_holder.find('.pp_hoverContainer, .pp_details').fadeOut(settings.animationSpeed);
$pp_pic_holder.find('#pp_full_res').fadeOut(settings.animationSpeed,function(){
$.prettyPhoto.open(images,titles,descriptions);
});
return false;
});
$pp_pic_holder.find('.pp_previous, .pp_arrow_previous').bind('click',function(){
$.prettyPhoto.changePage('previous');
return false;
});
$pp_pic_holder.find('.pp_next, .pp_arrow_next').bind('click',function(){
$.prettyPhoto.changePage('next');
return false;
});
$pp_pic_holder.find('.pp_hoverContainer').css({
'margin-left': settings.padding/2
});
};
};
function grab_param(name,url){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( url );
if( results == null )
return "";
else
return results[1];
}
})(jQuery);
Here is the link to the lighbox.
All help is appreciated.
Thanks,
Tim
It looks like the pretty photos code is using the rel attribute explicitly, do your div's have rel? You are calling the code on $("div[class^='menuitem[iframes]']").prettyPhoto();
But then pretty photos is looking for theRel = $(this).attr('rel'); and running against that.