/* Simple function to improve browsing by mobile devices. * Resizes images too large for the iPhone. * Copyright 2009 Jonathan Head of NimbleHost.com http://themes.nimblehost.com */ function mobileImageResize() { $nh('.imageStyle').each(function(){ if($nh(this).width() > 280){ $nh(this).width(280); } }); } /* Simple Drop Down Menu using only CSS and jQuery. * Degrades gracefully for browsers with no javascript support. * Based on the tutorial at http://kriesi.at - rewritten and customized by * Jonathan Head of NimbleHost.com for use with RapidWeaver Themes. * http://themes.nimblehost.com */ var $nh = jQuery.noConflict(); function ddmenu() { $nh(".menu ul ul").parent().addClass("ddarrow"); $nh(".menu ul ul").parent().append(""); $nh(".menu ul ul").css({display: "none"}); //Opera fix $nh(".menu li").hover(function(){ $nh(this).find('ul:first').css({visibility: "visible",display: "none"}).show(400); },function(){ $nh(this).find('ul:first').fadeOut(150); }); } /* Based on the script by Cabel Sasser and ported to jQuery by Steve Smith of OrderedList.com. Rewritten for use with RapidWeaver Themes by Jonathan Head * of NimbleHost.com - http://themes.nimblehost.com */ jQuery.fn.fancyZoom = function(options){ var options = options || {}; var directory = options && options.directory ? options.directory : jsPathto + 'fancyzoom_images'; var zooming = false; if ($fz('#zoom').length == 0) { var ext = $fz.browser.msie ? 'gif' : 'png'; var html = ''; $fz('body').append(html); $fz('html').click(function(e){if($fz(e.target).parents('#zoom:visible').length == 0) hide();}); $fz(document).keyup(function(event){ if (event.keyCode == 27 && $fz('#zoom:visible').length > 0) hide(); }); $fz('#zoom_close').click(hide); } var zoom = $fz('#zoom'); var zoom_table = $fz('#zoom_table'); var zoom_close = $fz('#zoom_close'); var zoom_content = $fz('#zoom_content'); var middle_row = $fz('td.ml,td.mm,td.mr'); this.each(function(i) { $fz($fz(this).attr('href')).hide(); $fz(this).click(show); }); return this; function show(e) { if (zooming) return false; zooming = true; var content_div = $fz($fz(this).attr('href')); var zoom_width = options.width; var zoom_height = options.height; var width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth); var height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight); var x = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft); var y = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop); var window_size = {'width':width, 'height':height, 'x':x, 'y':y} var width = (zoom_width || content_div.width()) + 60; var height = (zoom_height || content_div.height()) + 60; var d = window_size; // ensure that newTop is at least 0 so it doesn't hide close button var newTop = Math.max((d.height/2) - (height/2) + y, 0); var newLeft = (d.width/2) - (width/2); var curTop = e.pageY; var curLeft = e.pageX; zoom_close.attr('curTop', curTop); zoom_close.attr('curLeft', curLeft); zoom_close.attr('scaleImg', options.scaleImg ? 'true' : 'false'); $fz('#zoom').hide().css({ position : 'absolute', top : curTop + 'px', left : curLeft + 'px', width : '1px', height : '1px' }); fixBackgroundsForIE(); zoom_close.hide(); if (options.closeOnClick) { $fz('#zoom').click(hide); } if (options.scaleImg) { zoom_content.html(content_div.html()); $fz('#zoom_content img').css('width', '100%'); } else { zoom_content.html(''); } $fz('#zoom').animate({ top : newTop + 'px', left : newLeft + 'px', opacity : "show", width : width, height : height }, 500, null, function() { if (options.scaleImg != true) { zoom_content.html(content_div.html()); } unfixBackgroundsForIE(); zoom_close.show(); zooming = false; }) return false; } function hide() { if (zooming) return false; zooming = true; $fz('#zoom').unbind('click'); fixBackgroundsForIE(); if (zoom_close.attr('scaleImg') != 'true') { zoom_content.html(''); } zoom_close.hide(); $fz('#zoom').animate({ top : zoom_close.attr('curTop') + 'px', left : zoom_close.attr('curLeft') + 'px', opacity : "hide", width : '1px', height : '1px' }, 500, null, function() { if (zoom_close.attr('scaleImg') == 'true') { zoom_content.html(''); } unfixBackgroundsForIE(); zooming = false; }); return false; } function switchBackgroundImagesTo(to) { $fz('#zoom_table td').each(function(i) { var bg = $fz(this).css('background-image').replace(/\.(png|gif|none)\"\)$fz/, '.' + to + '")'); $fz(this).css('background-image', bg); }); var close_img = zoom_close.children('img'); var new_img = close_img.attr('src').replace(/\.(png|gif|none)$fz/, '.' + to); close_img.attr('src', new_img); } function fixBackgroundsForIE() { if ($fz.browser.msie && parseFloat($fz.browser.version) >= 7) { switchBackgroundImagesTo('gif'); } } function unfixBackgroundsForIE() { if ($fz.browser.msie && $fz.browser.version >= 7) { switchBackgroundImagesTo('png'); } } } /* * The scripts below have been tested and packaged by Jonathan Head of NimbleHost.com - http://themes.nimblehost.com * for use with RapidWeaver Themes. */ /* * Copyright 2007-2009 by Tobia Conforto * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along with this program; if not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Versions: 0.1 2007-08-19 Initial release * 2008-08-21 Re-released under GPL v2 * 0.1.1 2008-09-18 Compatibility with prototype.js * 0.2 2008-10-15 Linkable images, contributed by Tim Rainey * 0.3 2008-10-22 Added option to repeat the animation a number of times, then stop * 0.3.1 2008-11-11 Better error messages * 0.3.2 2008-11-11 Fixed a couple of CSS bugs, contributed by Erwin Bot * 0.3.3 2008-12-14 Added onclick option * 0.3.4 2009-03-12 Added shuffle option, contributed by Ralf Santbergen * 0.3.5 2009-03-12 Fixed usage of href parameter in 'Ken Burns' mode * 0.3.6 2009-04-16 Added alt option * 0.3.7 2009-05-14 Fixed bug when container div doesn't have a position CSS attribute */ jQuery.fn.crossSlide = function(opts, plan) { var self = this, self_width = this.width(), self_height = this.height(); // generic utilities function format(str) { for (var i = 1; i < arguments.length; i++) str = str.replace(new RegExp('\\{' + (i-1) + '}', 'g'), arguments[i]); return str; } function abort() { arguments[0] = 'crossSlide: ' + arguments[0]; throw format.apply(null, arguments); } // first preload all the images, while getting their actual width and height (function(proceed) { var n_loaded = 0; function loop(i, img) { // for (i = 0; i < plan.length; i++) but with independent var i, img (for the closures) img.onload = function(e) { n_loaded++; plan[i].width = img.width; plan[i].height = img.height; if (n_loaded == plan.length) proceed(); } img.src = plan[i].src; if (i + 1 < plan.length) loop(i + 1, new Image()); } loop(0, new Image()); })(function() { // then proceed // utility to parse "from" and "to" parameters function parse_position_param(param) { var zoom = 1; var tokens = param.replace(/^\s*|\s*$/g, '').split(/\s+/); if (tokens.length > 3) throw new Error(); if (tokens[0] == 'center') if (tokens.length == 1) tokens = ['center', 'center']; else if (tokens.length == 2 && tokens[1].match(/^[\d.]+x$/i)) tokens = ['center', 'center', tokens[1]]; if (tokens.length == 3) zoom = parseFloat(tokens[2].match(/^([\d.]+)x$/i)[1]); var pos = tokens[0] + ' ' + tokens[1]; if (pos == 'left top' || pos == 'top left') return { xrel: 0, yrel: 0, zoom: zoom }; if (pos == 'left center' || pos == 'center left') return { xrel: 0, yrel: .5, zoom: zoom }; if (pos == 'left bottom' || pos == 'bottom left') return { xrel: 0, yrel: 1, zoom: zoom }; if (pos == 'center top' || pos == 'top center') return { xrel: .5, yrel: 0, zoom: zoom }; if (pos == 'center center') return { xrel: .5, yrel: .5, zoom: zoom }; if (pos == 'center bottom' || pos == 'bottom center') return { xrel: .5, yrel: 1, zoom: zoom }; if (pos == 'right top' || pos == 'top right') return { xrel: 1, yrel: 0, zoom: zoom }; if (pos == 'right center' || pos == 'center right') return { xrel: 1, yrel: .5, zoom: zoom }; if (pos == 'right bottom' || pos == 'bottom right') return { xrel: 1, yrel: 1, zoom: zoom }; return { xrel: parseInt(tokens[0].match(/^(\d+)%$/)[1]) / 100, yrel: parseInt(tokens[1].match(/^(\d+)%$/)[1]) / 100, zoom: zoom }; } // utility to compute the css for a given phase between p.from and p.to // phase = 1: begin fade-in, 2: end fade-in, 3: begin fade-out, 4: end fade-out function position_to_css(p, phase) { switch (phase) { case 1: var pos = 0; break; case 2: var pos = fade_ms / (p.time_ms + 2 * fade_ms); break; case 3: var pos = 1 - fade_ms / (p.time_ms + 2 * fade_ms); break; case 4: var pos = 1; break; } return { left: Math.round(p.from.left + pos * (p.to.left - p.from.left )), top: Math.round(p.from.top + pos * (p.to.top - p.from.top )), width: Math.round(p.from.width + pos * (p.to.width - p.from.width )), height: Math.round(p.from.height + pos * (p.to.height - p.from.height)) }; } // check global params if (! opts.fade) abort('missing fade parameter.'); if (opts.speed && opts.sleep) abort('you cannot set both speed and sleep at the same time.'); // conversion from sec to ms; from px/sec to px/ms var fade_ms = Math.round(opts.fade * 1000); if (opts.sleep) var sleep = Math.round(opts.sleep * 1000); if (opts.speed) var speed = opts.speed / 1000, fade_px = Math.round(fade_ms * speed); // set container css self.empty().css({ overflow: 'hidden', padding: 0 }); if (! /^(absolute|relative|fixed)$/.test(self.css('position'))) self.css({ position: 'relative' }); if (! self.width() || ! self.height()) abort('container element does not have its own width and height'); // random sorting if (opts.shuffle) plan.sort(function() { return Math.random() - 0.5; }); // prepare each image for (var i = 0; i < plan.length; ++i) { var p = plan[i]; if (! p.src) abort('missing src parameter in picture {0}.', i + 1); if (speed) { // speed/dir mode // check parameters and translate speed/dir mode into full mode (from/to/time) switch (p.dir) { case 'up': p.from = { xrel: .5, yrel: 0, zoom: 1 }; p.to = { xrel: .5, yrel: 1, zoom: 1 }; var slide_px = p.height - self_height - 2 * fade_px; break; case 'down': p.from = { xrel: .5, yrel: 1, zoom: 1 }; p.to = { xrel: .5, yrel: 0, zoom: 1 }; var slide_px = p.height - self_height - 2 * fade_px; break; case 'left': p.from = { xrel: 0, yrel: .5, zoom: 1 }; p.to = { xrel: 1, yrel: .5, zoom: 1 }; var slide_px = p.width - self_width - 2 * fade_px; break; case 'right': p.from = { xrel: 1, yrel: .5, zoom: 1 }; p.to = { xrel: 0, yrel: .5, zoom: 1 }; var slide_px = p.width - self_width - 2 * fade_px; break; default: abort('missing or malformed "dir" parameter in picture {0}.', i + 1); } if (slide_px <= 0) abort('picture number {0} is too short for the desired fade duration.', i + 1); p.time_ms = Math.round(slide_px / speed); } else if (! sleep) { // full mode // check and parse parameters if (! p.from || ! p.to || ! p.time) abort('missing either speed/sleep option, or from/to/time params in picture {0}.', i + 1); try { p.from = parse_position_param(p.from) } catch (e) { abort('malformed "from" parameter in picture {0}.', i + 1); } try { p.to = parse_position_param(p.to) } catch (e) { abort('malformed "to" parameter in picture {0}.', i + 1); } if (! p.time) abort('missing "time" parameter in picture {0}.', i + 1); p.time_ms = Math.round(p.time * 1000) } // precalculate left/top/width/height bounding values if (p.from) jQuery.each([ p.from, p.to ], function(i, from_to) { from_to.width = Math.round(p.width * from_to.zoom); from_to.height = Math.round(p.height * from_to.zoom); from_to.left = Math.round((self_width - from_to.width) * from_to.xrel); from_to.top = Math.round((self_height - from_to.height) * from_to.yrel); }); // append the image (or anchor) element to the container var elm; if (p.href) elm = jQuery(format('', p.href, p.src)); else elm = jQuery(format('', p.src)); if (p.onclick) elm.click(p.onclick); if (p.alt) elm.find('img').attr('alt', p.alt); elm.appendTo(self); } speed = undefined; // speed mode has now been translated to full mode // find images to animate and set initial css attributes var imgs = self.find('img').css({ position: 'absolute', visibility: 'hidden', top: 0, left: 0, border: 0 }); // show first image imgs.eq(0).css({ visibility: 'visible' }); if (! sleep) imgs.eq(0).css(position_to_css(plan[0], 2)); // create animation chain var countdown = opts.loop; function create_chain(i, chainf) { // building the chain backwards, or inside out if (i % 2 == 0) { if (sleep) { // still image sleep var i_sleep = i / 2, i_hide = (i_sleep - 1 + plan.length) % plan.length, img_sleep = imgs.eq(i_sleep), img_hide = imgs.eq(i_hide); var newf = function() { img_hide.css('visibility', 'hidden'); setTimeout(chainf, sleep); }; } else { // single image slide var i_slide = i / 2, i_hide = (i_slide - 1 + plan.length) % plan.length, img_slide = imgs.eq(i_slide), img_hide = imgs.eq(i_hide), time = plan[i_slide].time_ms, slide_anim = position_to_css(plan[i_slide], 3); var newf = function() { img_hide.css('visibility', 'hidden'); img_slide.animate(slide_anim, time, 'linear', chainf); }; } } else { if (sleep) { // still image cross-fade var i_from = Math.floor(i / 2), i_to = Math.ceil(i / 2) % plan.length, img_from = imgs.eq(i_from), img_to = imgs.eq(i_to), from_anim = {}, to_init = { visibility: 'visible' }, to_anim = {}; if (i_to > i_from) { to_init.opacity = 0; to_anim.opacity = 1; } else { from_anim.opacity = 0; } var newf = function() { img_to.css(to_init); if (from_anim.opacity != undefined) img_from.animate(from_anim, fade_ms, 'linear', chainf); else img_to.animate(to_anim, fade_ms, 'linear', chainf); }; } else { // cross-slide + cross-fade var i_from = Math.floor(i / 2), i_to = Math.ceil(i / 2) % plan.length, img_from = imgs.eq(i_from), img_to = imgs.eq(i_to), from_anim = position_to_css(plan[i_from], 4), to_init = position_to_css(plan[i_to], 1), to_anim = position_to_css(plan[i_to], 2); if (i_to > i_from) { to_init.opacity = 0; to_anim.opacity = 1; } else { from_anim.opacity = 0; } to_init.visibility = 'visible'; var newf = function() { img_from.animate(from_anim, fade_ms, 'linear'); img_to.css(to_init); img_to.animate(to_anim, fade_ms, 'linear', chainf); }; } } // if the loop option was requested, push a countdown check if (opts.loop && i == plan.length * 2 - 2) { var newf_orig = newf; newf = function() { if (--countdown) newf_orig(); } } if (i > 0) return create_chain(i - 1, newf); else return newf; } var animation = create_chain(plan.length * 2 - 1, function() { return animation(); }); // start animation animation(); }); return self; }; /** * jQuery.pulse * Copyright (c) 2008 James Padolsey - jp(at)qd9(dot)co.uk | http://james.padolsey.com / http://enhance.qd-creative.co.uk * Dual licensed under MIT and GPL. * Date: 05/11/08 * * @projectDescription Applies a continual pulse to any element specified * http://enhance.qd-creative.co.uk/demos/pulse/ * Tested successfully with jQuery 1.2.6. On FF 2/3, IE 6/7, Opera 9.5 and Safari 3. on Windows XP. * * @author James Padolsey * @version 1.11 * * @id jQuery.pulse * @id jQuery.recover * @id jQuery.fn.pulse * @id jQuery.fn.recover */ (function($){ $.fn.recover = function() { /* Empty inline styles - i.e. set element back to previous state */ /* Note, the recovery might not work properly if you had inline styles set before pulse initiation */ return this.each(function(){$(this).stop().css({backgroundColor:'',color:'',borderLeftColor:'',borderRightColor:'',borderTopColor:'',borderBottomColor:'',opacity:1});}); } $.fn.pulse = function(options){ var defaultOptions = { textColors: [], backgroundColors: [], borderColors: [], opacityPulse: true, opacityRange: [], speed: 1000, duration: false, runLength: false }, o = $.extend(defaultOptions,options); /* Validate custom options */ if(o.textColors.length===1||o.backgroundColors.length===1||o.borderColors.length===1) {return false;} /* Begin: */ return this.each(function(){ var $t = $(this), pulseCount=1, pulseLimit = (o.runLength&&o.runLength>0) ? o.runLength*largestArrayLength([o.textColors.length,o.backgroundColors.length,o.borderColors.length,o.opacityRange.length]) : false; clearTimeout(recover); if(o.duration) { setTimeout(recover,o.duration); } function nudgePulse(textColorIndex,bgColorIndex,borderColorIndex,opacityIndex) { if(pulseLimit&&pulseCount===pulseLimit) { return $t.recover(); } pulseCount++; /* Initiate color change - on callback continue */ return $t.animate(getColorsAtIndex(textColorIndex,bgColorIndex,borderColorIndex,opacityIndex),o.speed,function(){ /* Callback of each step */ nudgePulse( getNextIndex(o.textColors,textColorIndex), getNextIndex(o.backgroundColors,bgColorIndex), getNextIndex(o.borderColors,borderColorIndex), getNextIndex(o.opacityRange,opacityIndex) ); }); } /* Set CSS to first step (no animation) */ $t.css(getColorsAtIndex(0,0,0,0)); /* Then animate to second step */ nudgePulse(1,1,1,1); function getColorsAtIndex(textColorIndex,bgColorIndex,borderColorIndex,opacityIndex) { /* Prepare animation object - get's all property names/values from passed indexes */ var params = {}; if(o.backgroundColors.length) { params['backgroundColor'] = o.backgroundColors[bgColorIndex]; } if(o.textColors.length) { params['color'] = o.textColors[textColorIndex]; } if(o.borderColors.length) { params['borderLeftColor'] = o.borderColors[borderColorIndex]; params['borderRightColor'] = o.borderColors[borderColorIndex]; params['borderTopColor'] = o.borderColors[borderColorIndex]; params['borderBottomColor'] = o.borderColors[borderColorIndex]; } if(o.opacityPulse&&o.opacityRange.length) { params['opacity'] = o.opacityRange[opacityIndex]; } return params; } function getNextIndex(property,currentIndex) { if (property.length>currentIndex+1) {return currentIndex+1;} else {return 0;} } function largestArrayLength(arrayOfArrays) { return Math.max.apply( Math, arrayOfArrays ); } function recover() { $t.recover(); } }); } })(jQuery); /* The below code extends the animate function so that it works with color animations */ /* By John Resig */ (function(jQuery){ jQuery.each(['backgroundColor','borderBottomColor','borderLeftColor','borderRightColor','borderTopColor','color','outlineColor'],function(i,attr){jQuery.fx.step[attr]=function(fx){if(fx.state==0){fx.start=getColor(fx.elem,attr);fx.end=getRGB(fx.end)}fx.elem.style[attr]="rgb("+[Math.max(Math.min(parseInt((fx.pos*(fx.end[0]-fx.start[0]))+fx.start[0]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[1]-fx.start[1]))+fx.start[1]),255),0),Math.max(Math.min(parseInt((fx.pos*(fx.end[2]-fx.start[2]))+fx.start[2]),255),0)].join(",")+")"}}); function getRGB(color){var result;if(color&&color.constructor==Array&&color.length==3)return color;if(result=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)){return[parseInt(result[1]),parseInt(result[2]),parseInt(result[3])]}if(result=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)){return[parseFloat(result[1])*2.55,parseFloat(result[2])*2.55,parseFloat(result[3])*2.55]}if(result=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)){return[parseInt(result[1],16),parseInt(result[2],16),parseInt(result[3],16)]}if(result=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)){return[parseInt(result[1]+result[1],16),parseInt(result[2]+result[2],16),parseInt(result[3]+result[3],16)]}return colors[jQuery.trim(color).toLowerCase()]} function getColor(elem,attr){var color;do{color=jQuery.curCSS(elem,attr);if(color!=''&&color!='transparent'||jQuery.nodeName(elem,"body")){break}attr="backgroundColor"}while(elem=elem.parentNode);return getRGB(color)}; var colors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}; })(jQuery);