CSS3 Shiney Shiney

#spinnerIcon img {
	background-repeat:no-repeat;
	background-position: center;
	-webkit-mask-position: 0 0;
	-webkit-mask-size: 215px 140px;

	-webkit-mask-image: -webkit-gradient(linear, left top, right bottom,
					color-stop(0.00,  rgba(0,0,0,1)),
					color-stop(0.25,  rgba(0,0,0,1)),
					color-stop(0.50,  rgba(0,0,0,0.65)),
					color-stop(0.75,  rgba(0,0,0,1)),
					color-stop(1.00,  rgba(0,0,0,1)));

	-webkit-mask-size: 430px 140px;

	-webkit-animation-name:             shinyshiny;
	-webkit-animation-duration:         3s;
	-webkit-animation-iteration-count:  infinite;
	-webkit-animation-timing-function:  linear;
        -webkit-animation-delay: 5s;

	-webkit-transform:translate3d(0,0,0);

}

@-webkit-keyframes shinyshiny {
	  0%   {-webkit-mask-position: -215px 0px;}
	  50%  {-webkit-mask-position: 0px 0px;}
	  100%   {-webkit-mask-position: 215px 0px;}
}
Posted in Development | Leave a comment

Love in an Elevator

There are many tabs, accordions, scrollers, carousels etc for jQuery but what if I fancy something different. Navigation along the left hand side with an arrow that scrolls between the options and content that slides up and down to match the selected tab. Simple.

Getting Started

A quick prototype sketch

A quick prototype sketch

The original idea was to use an unordered list, with list items as the titles and append an extra list item to act as the slider. An onclick event on each of the list items will then trigger a function to slide the appended list item over the top of the clicked element. Using CSS and images, the appended list item would be positioned absolutely to allow the movement up and down and give it a higher z-index than the other elements to overlay them. A background image of an arrow and slightly larger width would also help the effect.

Damn you IE7
So it almost works, only that creating an extra element at the start of the navigation and setting the z-index of a value between the other background li's and the anchor link doesn't work. It's something to do with the stacking order of IE7. Bugger. A quick change to use a div tag instead of a list doesn't help so a better solution is needed.

The solution
The final version moves the anchor link outside of the div and uses CSS to position it back over the its old parent. Although hacky, this fixes the z-index issue but now the css hover doesn't work as the div is covered by the anchor. An extra hover event is required on the anchor to find the div before it and add and remove a hover class to change the background image.

JavaScript

 
$(function() {
   var $menu   = $("#slidingMenu");
   var $moving = $('
<div></div>
 
').addClass('move').css({top:'0px'});
   $menu.append($moving)
      .find('div').each(function(){
             $(this).find('span')
                    .insertAfter($(this))
                    .bind('click',function(){
                        var $elem = $(this);
                        var i = $elem.attr('id').substr(2);
                        $moving.stop(true).animate({
                           top : ((i-1) * 78)+'px'
                        }, 400);
                        $('#slideyContent').stop(true).animate({
                           top : -((i-1)*233)+'px'
                        },400);
                     })
                     .hover(function(){ $(this).prev().addClass('hover'); },
                            function(){ $(this).prev().removeClass('hover');
                     });
        });
});
 

Demo

Here is a working, un-skinned demo of the JavaScript Elevator.

Posted in Development, jQuery | Tagged , | Leave a comment

HTML5 Canvas Timed Image Gallery

A simple use of the HTML Canvas Element to create a simple pie-chart timer to show when the next image in a gallery slide show will be displayed.

I will write more about how it works, when I get a free moment.

Yes, global variables are crap and shouldn't be used. But it was a quick 30 minute test :)

JavaScript

 
	var timeAngle = 0;
	var canvas;
	var ctx;
	var t;
	var timerColor = 'rgba( 204, 204, 204, 1 )';
	var c = 0;
	var pause = 8000;
 
	function setup(){
		canvas = document.getElementById('tutorial');
		if (canvas.getContext){
			ctx = canvas.getContext('2d');
			t = setInterval( 'updateTime()', pause/60 );
		}
	}
 
	function updateTime(){
		if(c<60){
			c = c + 1;
			currentMillisec = 0;
			drawSeconds();
		} else {
			clearTimeout(t);
			move();
		}
	}
 
	function drawSeconds(){
		timeAngle = 0.006 * ( c * 1000  );
		ctx.fillStyle = timerColor;
		ctx.beginPath();
		ctx.moveTo( 12, 20 );
		ctx.lineTo( 12, 5 );
		ctx.arc( 12, 12, 10, calcDeg( 0 ), calcDeg( timeAngle ), false );
		ctx.lineTo( 12, 12 );
		ctx.fill();
	} 
 
	function calcDeg( deg ){
		return (Math.PI/180) * (deg - 90);
	}
 
	function move(){
		ctx.clearRect ( 0 , 0 , 25 , 25 );
		$('#scroll').animate({top:'-=100px'},
							 function(){
								$(this).find('div:first').appendTo($(this));
								$(this).css({top:'0px'});
								c = 0;
								t = setInterval( 'updateTime()', pause/60 );
							 });
	}
	$(function(){
		   setup();
		   $('#james').hover(function(){
				ctx.clearRect ( 0 , 0 , 25 , 25 );
				clearTimeout(t);
		   },
		   function(){
				c = 0;
				t = setInterval( 'updateTime()', pause/60 );
		   })
	});
 

Demo

Posted in Development, jQuery | Tagged , , , | Leave a comment

Subliminal JavaScript

Ok. So this one's a little below the belt. Flashing a pop-up message very quickly to the user in an attempt to influence their behaviour. There's of course no evidence that it works but its fun to try at least...

 
 
var shown = false;
 
$(function(){
 
$('input:text').hover(function(){		   
 
if(!shown){
 
	var msg = "Buy me Beer";
 
	$('
<div>').css({position:'fixed',
					top:0,
                    left:0,
                    right:0,
                    bottom:0,
                    backgroundColor:'black',
                    color:'white',
                    fontSize:'100px',
                    textAlign:'center',
                    lineHeight:'400px'})
              .html(msg)
              .appendTo('body')
              .addClass('test');	
 
	setTimeout(function(){$('.test').remove()},20);
 
	shown = true;
 
	cls();
 
}
 
 });
 
});
 
function cls(){
 
	setTimeout(function(){ shown = false; },15000);	
 
}
 

In this example a black div is created, appended to the body and set to cover the content. The message is displayed in large white font, and a time-out set for 40 milliseconds to remove it again. A final time-out is set for 15 seconds to prevent the message from being triggered too often.

Here's a link if you're interested in running it, although I wouldn't follow it if you are sensitive to flashing images.
JS Subliminal Messages
I'll let you know how drunk I get off this.

Posted in Development, jQuery | Leave a comment

JavaScript and CSS Pie chart

This started off as an experiment with a combination JQuery and WordPress custom fields. The idea was to total up the distances of all the walks on my other site, a walking blog and make something a bit more interesting than a simple table.

An obvious choice would be to use the new HTML5 canvas element however there's a great plugin which allows elements to be rotated rather than using the Mozilla/Web-kit CSS rules.it uses a combination of images layered on top of each other to mask, and display the animation.

The Image

An image sprite to create a pie chart

An image sprite to create a pie chart

The HTML

  1.  
  2. <div id="walkDistanceFrame">
  3. <div id="walkDistanceMask"></div>
  4. <div id="walkArrowLine" style="display: block; -moz-transform: rotate(6.98421deg);"></div>
  5. <div id="walkArrowLineMask"></div>
  6. <div style="display: none;" id="walkArrowLine2"></div>
  7. <div id="walkArrow"></div>
  8. <h3 title="click me..." id="walkDistance">131.73
  9. <span>miles</span></h3>
  10.  
  11. <a href="/about/#distance">Explain?</a>
  12. </div>
  13.  

The Javascript

  1.  
  2. $(document).ready(function() {
  3. $('#walkDistance').click(function(){animateHowFar();});
  4. animateHowFar();
  5. });
  6. var randValue = -1;
  7.  
  8. function animateHowFar(){
  9. var animTime = 2000;
  10. var calcDistance = 0;
  11. var myLocations = ['far around the moon',
  12. 'far along the M25',
  13. 'far along the thames',
  14. 'many marathons',
  15. 'far round an olympic swimming pool',
  16. 'far from Lands End to John o\'Groats' ];
  17.  
  18. var myDistances = [6790,176,215,26.2, 0.093,874];
  19. var myImages = ['a','b','c','d','e','f'];
  20. randValue = randValue + 1;
  21. if(randValue >= myLocations.length){
  22. randValue = 0;
  23. }
  24. var target = myDistances[randValue];
  25. var remainder = 0;
  26. var circuits = 0;
  27.  
  28. if(!runningAnim) {
  29. runningAnim = true;
  30. $('#walkAroundLoc').html(myLocations[randValue]);
  31. $('#walkArrowLine').hide();
  32. $('#walkArrowLine2').hide();
  33. $('#walkCircuits').hide();
  34.  
  35. if(target < walkDistance){
  36. remainder = (walkDistance % target);
  37. circuits = ((walkDistance) / target).toFixed(2);
  38. calcDistance = remainder;
  39. $('#walkCircuits').html('<strong>Circuits:</strong> '+circuits).show();
  40. } else {
  41. calcDistance = walkDistance;
  42. }
  43.  
  44. var deg = ((calcDistance/target)*360);
  45. var walkPercentage = (calcDistance/target);
  46.  
  47. var time1 = (animTime/deg) * 180;
  48. var time2 = (animTime/deg) * (deg - 180);
  49.  
  50. $('#walkArrow').transform({rotate: 0});
  51. $('#walkArrowLine').transform({rotate: 0});
  52. $('#walkArrowLine2').transform({rotate: 0});
  53.  
  54. $('#walkArrow').animate({rotate: deg+'deg'},animTime, 'easeOutBounce',function(){
  55. if(deg <= 180){
  56. $('#walkArrowLine').transform({rotate: deg+"deg"}).show();
  57. runningAnim = false;
  58. } else {
  59. $('#walkArrowLine').transform({rotate: "180deg"}).show();
  60. $('#walkArrowLine2').transform({rotate: (deg-180)+"deg"}).show();
  61. runningAnim = false;
  62. }
  63. });
  64. }
  65. }
  66.  

A working demo can be seen on the homepage of MudWetandBeers.com.

Posted in Development, jQuery | Leave a comment

jQuery Regex Filter

As an alternative to a database auto suggest which often results in a lot of small database calls over a small period of time I decided to dump all results onto a page and use a combination of jQuery and Regex to filter out the results.

function escapeRegex(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&amp;")}
function filterLinks(){
   var t = escapeRegex($('#filterBox').val())
   var r=new RegExp(t,"i");
 
   $('a').each(function(){
      var a = $(this);
      if(a.text().match(r)){
         var matches = a.text().match(r);
         a.html(a.text().replace(r,"<strong>"+matches[0]+"</strong>"));
	 a.show();
      } else {
	 a.html(a.text());
	 a.hide();
      }
   });
}
 

This function can be called on a change event of a text box and escapes the content ready for inclusion in a regex. Any anchor link that matches the given pattern is displayed wrapped in '<b>' tags to highlight to found text, and shown remains on the page. Anything that doesn't match is hidden and'<b>' tags are removed.

Improvements

Obviously at the moment it searches for EVERY link on the page, which isn't good. The selector can be made more specific by selecting links within a given div, or links with a specific class. Also the link cannot contain any other HTML as this is stripped out with the '<b>' tags. A different solution would be to wrap the found text with a span with a specific class or ID that could be removed preserving the HTML in the link.

Finally selecting all the links on each key press isn't particularly good for performance and this will only get worse the larger the list of links. An alternative solution would be to preload each link into an array when the script first runs and then subsequent searches query the array rather than searching the DOM each time.

I have cobbled together a quick demo of JavaScript Regex searching which rather than showing and hiding links adds and removes a class to show which links it's removing.

Update:

I included this on a project I've been working on, Mobilevaluer.com and unfortunately it seems that Chrome seemed to struggle with the selectors and iterating through such a large amount of elements. Chrome would hang for several seconds, before announcing it had crashed. To fix this we decided to use a jQuery selector rather than selecting all links and checking them individually.

Posted in Development, jQuery | Leave a comment

Scrolling Data Tables

A screen shot of tables that scroll

A screen shot of tables that scroll

In the hostel section of my other site, MudWetandBeers.com, users can search for available hostels over a large date range, and displaying this data in a narrow page template creates a problem. As ever Internet Explorer isn't playing ball and ignoring the widths of my table cells and squashing them all to fit in the narrow space of the site template. Enter jQuery to add some extra HTML and CSS mark-up to create a dynamic scrolling table.

The basic functionality is to take an existing table and split it in two and wrap them in specific <div> tags with css rules to create the slide. All of my result tables use the same structure, with <th> running across the top and along the left hand side. My jQuery function finds all of the tables given a class and strips the first column creating a new table. This is my title table which is given a width, wrapped in a <div> and floated left. The remaining table is wrapped in a div, is given a fixed width to fit the template, and the CSS rule 'overflow:auto' added to create the scroll along the bottom and floated left to align it with my titles table.

So long as the cells in my table are given the same CSS properties for height and width, the rows in both the data table and the titles table should line up.

The JavaScript

 
$('.searchResults').each(function(){
	$(this).wrap("
<div class='wrapScrollDiv'></div>
 
");
	var _ct = $(this).parent();
	var _ht = $('
<table>');
	$(_ht).attr("id", "titleTable");
	$(this).find('th.hostelTitle').each(function(){
		var _tr = $('
<tr>');
		$(this).appendTo($(_tr));
		$(_tr).appendTo($(_ht ));
	});
	$(_ht).wrap("
<div class='_ht'></div>
 
");
	$(_ht).parent().insertBefore($(_ct));
	$("
<div style='clear:both'></div>
 
").insertAfter($(_ct));
});
 

The CSS

 
div.wrapScrollDiv {
    overflow:auto;
    width:576px;
    float:left;
}
div._ht {
    float:left;
    width:200px;
    margin-left:3px;
}
 

I do have another version that compares the heights of the rows in each of the two tables to make sure they're the same height. The shorter table row is then stretched to fit the larger. Alternatively you could simply make sure that none of your titles or data break onto two lines by experimenting with the table widths.

Posted in Development, jQuery | Leave a comment

Windows 7 Navigation with jQuery

Windows 7, with its new shiny hover-over effect on the nav bar. Is it possible to re-create that using jQuery?

Windows 7 Aero Interface

Windows 7 Aero Interface

I must admit that I'm more of a Mac user and there are hundreds of examples across the internet of how to create a Apple-style dock interface for a website. However I have Windows 7 on my work PC and the aero interface is shiny and new, and for the most part, not re-created in JavaScript. For those that don't have Windows 7, the task bar now has a glass effect that glows around the mouse when moved left or right. To re-create this we need to track mouse movement across the element and layer a few extra images to give the glow and glass effects.

My example is going to take a list full of anchor links and add a couple of styled <span> tags to provide the image effects. One will overlay everything to add a simple shine, the other will act as a mask and track the mouse movement along the x axis. Using this method, I can add different CSS background colours to each anchor link to create different coloured shine. This mask span will be hidden when it's added to the anchors and fades in and out when the user hovers over the link.

Images

Shine png overlay

Shine png overlay

Hover png overlay

Hover png overlay

jQuery

Adding the spans

  1.  
  2. $('#nav li a').each(function(){ var html = $(this).html();
  3. html = "<span class='content'>"+html+"</span>";
  4. $(this).html(html);
  5. });
  6. $('<span>').addClass('hover').appendTo('#nav li a').hide();
  7. $('<span>').addClass('shine').appendTo('#nav li a');
  8.  

Adding the hover over to fade in and fade out the mask span.

 
$('#nav li a').hover(
	  function(){ $(this).find('.hover').stop(true,true).fadeIn();},
  	  function(){ $(this).find('.hover').stop(true,true).fadeOut();}
    );
 

Finally add the mouse move event to move the mask span. We move the mask left by half the width to center the most transparent part of the mask under the mouse pointer.

 
$('#nav li a').mousemove(function(e){
   $(this).find('.hover').css({left: ((e.pageX - $(this).offset().left) -250)+"px"});
  }
);
 

HTML

 
<ul id="nav">
<li id="home"><a class="button" href="#">Home</a></li>
<li id="about"><a class="button" href="#">About</a></li>
<li id="jquery"><a class="button" href="#" >JQuery</a></li>
<li id="projects"><a class="button" href="#/" >Projects</a></li>
<li id="contact"><a class="button" href="#">Contact</a></li>
</ul>
 

CSS

 
 /* add different colours to each link to give a different coloured shine */
#home span.hover {
	background-color:red;
}
#about span.hover {
	background-color:yellow;
}
#jquery span.hover {
		background-color:pink;
}
#projects span.hover {
	background-color:blue;
}
#contact  span.hover {
	background-color:green;
}
span.hover {
	width:500px;
	height:200px;
	position:absolute;
	display:block;
	background-image:url(hover.png);
	background-position:0px -15px;
	top:-25px;
	z-index:0;
	left:3;
}
span.content {
	width:100%;
	height:40px;
	position:absolute;
	z-index:1;
	left:0;
	top:0;
	line-height:40px;
	display:block;
	z-index:2;
}
span.shine {
	width:200px;
	height:40px;
	position:absolute;
	z-index:4;
	background-image:url(shine.png);
	background-repeat:repeat-x;
	left:0;
	top:0;
	display:block;
}
 

Result

jQuery version of Windows 7 Navigation

jQuery version of Windows 7 Navigation

Ok, so its not a complete copy, there is plenty of room for improvement but for q quick rough prototype its not too bad. With a bit more work the images could be improved to give a cleaner, brighter shine and the code could be re-written to be a plugin rather than dump everything in a $(document).ready function. If anyone has ideas on how to improve, or can create better JavaScript or transparent PNG's then I'm open to suggestions...
Windows 7 Navigation with jQuery Demo

Download the source

Posted in Development, jQuery | Leave a comment

Can I use CSS to style the head?

Yes. Should I? Hmmm, only if you're prepared for it not to work in some browsers.

This was one of those questions you think of in the shower. You don't think of CSS in the shower? Fair enough. After reading through various CSS books and websites on the subject of background images an example given put a background image for a site on the <html> element. This then gave access to the <body> element to put another background image layered over the top. Brilliant idea. No longer will I have to add another <div> wrapper to style my content.

 
head  {
display: block;
position: absolute;
left: 0;
top: 0; height: 400px; width: 100%; background-repeat: repeat-x; z-index: 1;
background-image:url(images/header.jpg);
background-position:0 46px;
}
 

So if I can use the <body> and <html> elements what about the others? It seems that for the most part <head> can be styled, so long as you don't want any content in it. An example of this would be those elements you want to add to a page, such as background images, or styled elements for which you would usually 'chuck in' an extra <div>. In my example on MudWetandBeers.com I've used it as a banner running across the top of the site. Admittedly I could have used <body> but if there's another element I want to add, I have one spare.

MudWetandBeers header

MudWetandBeers header

Now I'm not entirely sure how cross-browser compatible any of this is, but it seems to work in the latest versions of all 4 browsers. But I would use it in the same way people use CSS3 elements. To add something extra to a page. If it doesn't work, then nothing is lost.

Posted in CSS, Development | Tagged , , | Leave a comment