Feed aggregator

Sliding Letters with jQuery

Codrops News - Mon, 05/09/2011 - 16:10

Today we have a neat little effect for you. We want to bring some life to the standard hover effect by playing around with the letters in an anchor word. The aim is to slide in letter by letter when hovering over a link element. We can either have the same word or a different one and we can slide in the new letters all the same time or one after the other.

We will be using the Lettering.js jQuery Plugin which you can find on Github.

Example

In the following we will go through an example and we’ll start by the html for a little menu:

<div class="sl_examples"> <a href="#" id="example1" data-hover="Creativity">Illustrations</a> </div>

We will use data-hover to indicate the word that should appear on hover. If you don’t use the data-hover then the same word will be used on hover.
Then we will style it in the following way, making sure that we have the right properties for the structure that will be generated:

.sl_examples{ float:left; font-family: 'Bevan', arial, serif; font-size:50px; line-height:50px; color:#f0f0f0; margin-right:5px; text-transform:uppercase; } .sl_examples a{ display:block; position:relative; float:left; clear:both; color:#fff; } .sl_examples a > span{ height:50px; float:left; position:relative; overflow:hidden; } .sl_examples a span span{ position:absolute; display:block; left:0px; top:0px; text-align:center; } .sl_examples a span span.sl-w1{ color:#fff; text-shadow:0px 0px 1px #fff; z-index:2; } .sl_examples a span span.sl-w2{ color:#e82760; text-shadow:-1px 1px 2px #9f0633; z-index:3; }

So, “sl-w1″ is the class for the first word letters and “sl-w2″ is the class for the second word letters.

Finally, we call the plugin:

$(window).load(function(){ $('#example1').hoverwords({ delay:50 }); });

The following settings can be used:

delay : false, // each letter will have different animation times speed : 300, // animation speed easing : 'jswing', // easing animation dir : 'leftright', // leftright - current goes left, new one goes right || rightleft - current goes right, new one goes left, overlay : false, // hover word is slided on top of the current word (just for the case when the hover word equals word) opacity : true // animate the letters opacity

We hope you liked this little experiment and find it useful!

View demoDownload source

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Rotating Image Slider with jQuery

Codrops News - Thu, 04/28/2011 - 21:02


View demo Download source

In the following tutorial we will create an asymmetrical image slider with a little twist: when sliding the pictures we will slightly rotate them and delay the sliding of each element. The unusual shape of the slider is created by some elements placement and the use of thick borders. We will also add an autoplay option and the mousewheel functionality.

We’ll use the jQuery 2D Transformation Plugin for rotating the images and the jQuery Mousewheel Plugin by Brandon Aaron for the mousewheel control.

The beautiful photos are by Andrew and Lili and you can see their Behance profile here:
http://www.behance.net/AndrewLili
The images are licensed under the Creative Commons Attribution-NonCommercial 3.0 Unported License.

Allrighty! Let’s start with the HTML!

The Markup

First, we will wrap all our slider elements in a wrapper with the class “rm_wrapper”:

<div class="rm_wrapper"> ... </div>

Inside of that wrapper we will have a container for the actual slider list, some mask and corner elements, the heading and a hidden div that will contain all the image sets:

<div id="rm_container" class="rm_container"> <ul> <li data-images="rm_container_1" data-rotation="-15"> <img src="images/1.jpg"/> </li> <li data-images="rm_container_2" data-rotation="-5"> <img src="images/2.jpg"/> </li> <li data-images="rm_container_3" data-rotation="5"> <img src="images/3.jpg"/> </li> <li data-images="rm_container_4" data-rotation="15"> <img src="images/4.jpg"/> </li> </ul> <div id="rm_mask_left" class="rm_mask_left"></div> <div id="rm_mask_right" class="rm_mask_right"></div> <div id="rm_corner_left" class="rm_corner_left"></div> <div id="rm_corner_right" class="rm_corner_right"></div> <h2>Fashion Explosion 2012</h2> <div style="display:none;"> <div id="rm_container_1"> <img src="images/1.jpg"/> <img src="images/5.jpg"/> <img src="images/6.jpg"/> <img src="images/7.jpg"/> </div> <div id="rm_container_2"> <img src="images/2.jpg"/> <img src="images/8.jpg"/> <img src="images/9.jpg"/> <img src="images/10.jpg"/> </div> <div id="rm_container_3"> <img src="images/3.jpg"/> <img src="images/11.jpg"/> <img src="images/12.jpg"/> <img src="images/13.jpg"/> </div> <div id="rm_container_4"> <img src="images/4.jpg"/> <img src="images/14.jpg"/> <img src="images/15.jpg"/> <img src="images/16.jpg"/> </div> </div> </div>

So the unordered lists will have the first set of four images where each list element has some data attributes for the image sets and the rotation degree. We will use that data to know which images come next and how much each image should be rotated.

The mask and corner divs will be absolute elements that we will place on top of the slider, slightly rotated in order to cover some areas. Since we will use the same background color for these elements like the body’s background color, we will create the illusion of the images being shaped in a certain way.

Then we’ll add the elements for the navigation and the autoplay controls:

<div class="rm_nav"> <a id="rm_next" href="#" class="rm_next"></a> <a id="rm_prev" href="#" class="rm_prev"></a> </div> <div class="rm_controls"> <a id="rm_play" href="#" class="rm_play">Play</a> <a id="rm_pause" href="#" class="rm_pause">Pause</a> </div>

Let’s take a look at the CSS.

The CSS

First, we’ll reset some styles and define the properties for the body. (Remember, if we would have another background color, we would want to change the background and border colors of some of the elements in our slider, too.)

@import url('reset.css'); body{ background:#f0f0f0; color:#000; font-family: 'PT Sans Narrow', Arial, sans-serif; font-size:16px; } a{ color:#000; text-decoration:none; } h1{ padding:10px; margin:20px; font-size:40px; text-transform:uppercase; text-shadow:0px 0px 1px #fff; color:#333; background:transparent url(../images/line.png) repeat-x bottom left; }

The main wrapper will have the following style:

.rm_wrapper{ width:1160px; margin:0 auto; position:relative; }

The container for the slider will have any overflow hidden, which will help shaping our slider since we will cut off the outer sides of it:

.rm_container{ width:1050px; overflow:hidden; position:relative; height:530px; margin:0 auto; }

The heading will have the following style:

.rm_container h2{ background:transparent url(../images/lines.png) repeat top left; padding:10px 30px; position:absolute; bottom:170px; right:0px; color:#000; font-size:36px; text-transform:uppercase; text-shadow:1px 0px 1px #fff; }

Let’s define the width for the ul to be bigger than the container since we want to make the list element float next to each other:

.rm_container ul{ width:1170px; }

By giving a negative left margin and a thick border to the list element, we will overlap the images and cut off the right sides so that we create our asymmetrical shapes by rotating the elements then. The border color will be the same like the background color of the body (or the container).

.rm_container ul li{ float:left; margin-left:-80px; position:relative; overflow:hidden; width:310px; height:465px; border:30px solid #f0f0f0; border-width:50px 30px 0px 30px; background-color:#f0f0f0; }

We’ll position the images absolutely:

.rm_container ul li img{ position:absolute; top:0px; left:0px; }

In the following we will style the mask and the corner elements. They will be all positioned absolutely and we’ll give them the grey background color. By rotating them, we’ll make the images to appear as being “shaped”:

.rm_mask_right, .rm_mask_left{ position: absolute; height: 110px; background: #f0f0f0; width: 530px; bottom: -30px; left: 0px; -moz-transform:rotate(-3deg); -webkit-transform:rotate(-3deg); transform:rotate(-3deg); } .rm_mask_right{ left:auto; right:0px; -moz-transform:rotate(3deg); -webkit-transform:rotate(3deg); transform:rotate(3deg); } .rm_corner_right, .rm_corner_left{ background: #f0f0f0; position:absolute; width:200px; height:100px; bottom:0px; left:-65px; -moz-transform:rotate(45deg); -webkit-transform:rotate(45deg); transform:rotate(45deg); } .rm_corner_right{ left:auto; right:-65px; -moz-transform:rotate(-45deg); -webkit-transform:rotate(-45deg); transform:rotate(-45deg); }

The navigation elements will be placed to the left and right of the main container:

.rm_nav a{ position:absolute; top:200px; width:38px; height:87px; cursor:pointer; opacity:0.7; } .rm_nav a:hover{ opacity:1.0; } .rm_nav a.rm_next{ background:transparent url(../images/next.png) no-repeat top left; right:0px; } .rm_nav a.rm_prev{ background:transparent url(../images/prev.png) no-repeat top left; left:0px; }

The pause/play control will be placed to the top left of the main container:

.rm_controls{ position:absolute; top:0px; left:-40px; height:20px; } .rm_controls a{ cursor:pointer; opacity:0.7; padding-left:24px; font-size:16px; text-transform:uppercase; height:20px; float:left; line-height:20px; } .rm_controls a:hover{ opacity:1.0; } .rm_controls a.rm_play{ display:none; background:transparent url(../images/play.png) no-repeat center left; } .rm_controls a.rm_pause{ background:transparent url(../images/pause.png) no-repeat center left; }

And that’s all the style! Let add the spice!

The JavaScript

The main idea for the slider functionality is to add another image before the current one with a slightly increased rotation degree than the current item. Then we will animate the rotation and make the new images appear.
So let’s start by caching some elements and checking if we are dealing with a special needs browser in order to deal with some issues:

//our 4 items var $listItems = $('#rm_container > ul > li'), totalItems = $listItems.length, //the controls $rm_next = $('#rm_next'), $rm_prev = $('#rm_prev'), $rm_play = $('#rm_play'), $rm_pause = $('#rm_pause'), //the masks and corners of the slider $rm_mask_left = $('#rm_mask_left'), $rm_mask_right = $('#rm_mask_right'), $rm_corner_left = $('#rm_corner_left'), $rm_corner_right= $('#rm_corner_right'), //check if the browser is <= IE8 ieLte8 = ($.browser.msie && parseInt($.browser.version) <= 8),

Then we will define our main function:

RotateImageMenu = (function() { ... })(); RotateImageMenu.init();

And then we define the following in our function:

//difference of animation time between the items var timeDiff = 300, //time between each image animation (slideshow) slideshowTime = 3000, slideshowInterval, //checks if the images are rotating isRotating = false, //how many images completed each slideshow iteration completed = 0, /* all our images have 310 of width and 465 of height. this could / should be dynamically calculated if we would have different image sizes. we will set the rotation origin at x = width/2 and y = height*2 */ origin = ['155px', '930px'], init = function() { configure(); initEventsHandler(); }, //initialize some events initEventsHandler = function() { /* next and previous arrows: we will stop the slideshow if active, and rotate each items images. 1 rotate right -1 rotate left */ $rm_next.bind('click', function(e) { stopSlideshow(); rotateImages(1); return false; }); $rm_prev.bind('click', function(e) { stopSlideshow(); rotateImages(-1); return false; }); /* start and stop the slideshow */ $rm_play.bind('click', function(e) { startSlideshow(); return false; }); $rm_pause.bind('click', function(e) { stopSlideshow(); return false; }); /* adds events to the mouse and left / right keys */ $(document).bind('mousewheel', function(e, delta) { if(delta > 0) { stopSlideshow(); rotateImages(0); } else { stopSlideshow(); rotateImages(1); } return false; }).keydown(function(e){ switch(e.which){ case 37: stopSlideshow(); rotateImages(0); break; case 39: stopSlideshow(); rotateImages(1); break; } }); }, /* rotates each items images. we set a delay between each item animation */ rotateImages = function(dir) { //if the animation is in progress return if(isRotating) return false; isRotating = true; $listItems.each(function(i) { var $item = $(this), /* the delay calculation. if rotation is to the right, then the first item to rotate is the first one, otherwise the last one */ interval = (dir === 1) ? i * timeDiff : (totalItems - 1 - i) * timeDiff; setTimeout(function() { //the images associated to this item var $otherImages = $('#' + $item.data('images')).children('img'), totalOtherImages = $otherImages.length; //the current one $img = $item.children('img:last'), //keep track of each items current image current = $item.data('current'); //out of bounds if(current > totalOtherImages - 1) current = 0; else if(current < 0) current = totalOtherImages - 1; //the next image to show and its //initial rotation (depends on dir) var otherRotation = (dir === 1) ? '-30deg' : '30deg', $other = $otherImages.eq(current).clone(); //for IE <= 8 we will not rotate, //but fade out / fade in ... //better than nothing :) if(!ieLte8) $other.css({ rotate : otherRotation, origin : origin }); (dir === 1) ? ++current : --current; //prepend the next image to the <li> $item.data('current', current).prepend($other); //the final rotation for the current image var rotateTo = (dir === 1) ? '80deg' : '-80deg'; if(!ieLte8) { $img.animate({ rotate : rotateTo }, 1200, function(){ $(this).remove(); ++completed; if(completed === 4) { completed = 0; isRotating = false; } }); $other.animate({ rotate : '0deg' }, 600); } else { $img.fadeOut(1200, function(){ $(this).remove(); ++completed; if(completed === 4) { completed = 0; isRotating = false; } }); } }, interval ); }); }, //set initial rotations configure = function() { if($.browser.msie && !ieLte8) rotateMaskCorners(); else if(ieLte8) hideMaskCorners(); $listItems.each(function(i) { //the initial current is 1 //since we already showing the first image var $item = $(this).data('current', 1); if(!ieLte8) $item.transform({rotate: $item.data('rotation') + 'deg'}) .find('img') .transform({origin: origin}); }); }, //rotates the masks and corners rotateMaskCorners = function() { $rm_mask_left.transform({rotate: '-3deg'}); $rm_mask_right.transform({rotate: '3deg'}); $rm_corner_left.transform({rotate: '45deg'}); $rm_corner_right.transform({rotate: '-45deg'}); }, //hides the masks and corners hideMaskCorners = function() { $rm_mask_left.hide(); $rm_mask_right.hide(); $rm_corner_left.hide(); $rm_corner_right.hide(); }, startSlideshow = function() { clearInterval(slideshowInterval); rotateImages(1); slideshowInterval = setInterval(function() { rotateImages(1); }, slideshowTime); //show the pause button and hide the play button $rm_play.hide(); $rm_pause.show(); }, stopSlideshow = function() { clearInterval(slideshowInterval); //show the play button and hide the pause button $rm_pause.hide(); $rm_play.show(); }; return {init : init};

As you noticed, we will treat older browsers a bit differently so that the slider works properly.

And that’s it! We really hope you enjoyed the tutorial and like the result!

View demo Download source

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Animated Skills Diagram with Raphaël

Codrops News - Fri, 04/22/2011 - 22:50


View demo Download source
In this tutorial we will show you how to create a diagram using Raphaël – a small JavaScript library that is great for working with vector graphics. The idea is very simple: we will draw some arcs using mathematical functions and we’ll be displaying a skill percentage in a main circle when we hover over those arcs.
Let’s start with the markup.

The Markup

The HTML structure is going to consist of a main container with the class ‘get’. This container stores all data that we need to draw the arcs. Then we create a new div element with the id ‘diagram’ which will be the container for the arcs:

<div id="diagram"></div> <div class="get"> <div class="arc"> <span class="text">jQuery</span> <input type="hidden" class="percent" value="95" /> <input type="hidden" class="color" value="#97BE0D" /> </div> <div class="arc"> <span class="text">CSS3</span> <input type="hidden" class="percent" value="90" /> <input type="hidden" class="color" value="#D84F5F" /> </div> <div class="arc"> <span class="text">HTML5</span> <input type="hidden" class="percent" value="80" /> <input type="hidden" class="color" value="#88B8E6" /> </div> <div class="arc"> <span class="text">PHP</span> <input type="hidden" class="percent" value="53" /> <input type="hidden" class="color" value="#BEDBE9" /> </div> <div class="arc"> <span class="text">MySQL</span> <input type="hidden" class="percent" value="45" /> <input type="hidden" class="color" value="#EDEBEE" /> </div> </div>The CSS

In the CSS we will only do two things: hide the elements with the class ‘get’ and set the width and height of the div with the id ‘diagram’:

.get { display:none; } #diagram { float:left; width:600px; height:600px; }The JavaScript

The main idea is to first create a new Raphael object (variable ‘r’) and draw our first circle with a radius that we specify in ‘rad’.
Then we create a new circle in the Raphael object. We center the circle (x: 300px and y: 300px) and we add some text to it.

var o = { init: function(){ this.diagram(); }, random: function(l, u){ return Math.floor((Math.random()*(u-l+1))+l); }, diagram: function(){ var r = Raphael('diagram', 600, 600), rad = 73; r.circle(300, 300, 85).attr({ stroke: 'none', fill: '#193340' }); var title = r.text(300, 300, 'Skills').attr({ font: '20px Arial', fill: '#fff' }).toFront(); } }

Now, let’s go one step further.
We’ll extend the Raphael object with some custom attributes:

  • alpha – angle of the arc
  • random – random number from the specified range
  • sx, sy – start drawing from this point
  • x, y – end drawing at this point
  • path
var o = { init: function(){ this.diagram(); }, random: function(l, u){ return Math.floor((Math.random()*(u-l+1))+l); }, diagram: function(){ var r = Raphael('diagram', 600, 600), rad = 73; r.circle(300, 300, 85).attr({ stroke: 'none', fill: '#193340' }); var title = r.text(300, 300, 'Skills').attr({ font: '20px Arial', fill: '#fff' }).toFront(); r.customAttributes.arc = function(value, color, rad){ var v = 3.6*value, alpha = v == 360 ? 359.99 : v, random = o.random(91, 240), a = (random-alpha) * Math.PI/180, b = random * Math.PI/180, sx = 300 + rad * Math.cos(b), sy = 300 - rad * Math.sin(b), x = 300 + rad * Math.cos(a), y = 300 - rad * Math.sin(a), path = [['M', sx, sy], ['A', rad, rad, 0, +(alpha > 180), 1, x, y]]; return { path: path, stroke: color } } $('.get').find('.arc').each(function(i){ var t = $(this), color = t.find('.color').val(), value = t.find('.percent').val(), text = t.find('.text').text(); rad += 30; var z = r.path().attr({ arc: [value, color, rad], 'stroke-width': 26 }); z.mouseover(function(){ this.animate({ 'stroke-width': 50, opacity: .75 }, 1000, 'elastic'); if(Raphael.type != 'VML') //solves IE problem this.toFront(); title.animate({ opacity: 0 }, 500, '>', function(){ this.attr({ text: text + '\n' + value + '%' }).animate({ opacity: 1 }, 500, '<'); }); }).mouseout(function(){ this.animate({ 'stroke-width': 26, opacity: 1 }, 1000, 'elastic'); }); }); } }

Then we’ll retrieve all the data needed, such as the percentage value, the color of the arc and the text. We increase the radius value for each arc and finally create a new arc path.
In the last step we are adding some animations on hover. When the mouse will be over the arc the title (which is placed in the main circle) is changing. Also, we’ll make the arc a little bit bigger.

Conclusion

In today’s tutorial you’ve learned some first steps on how to use Raphaël. It is a powerful library and you can do a lot of great stuff with it. Visit the Raphaël website for more examples.

View demoDownload source

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Restaurant Website and Gallery Template

Codrops News - Thu, 04/21/2011 - 14:56


View demoDownload source

Today we want to share a little website experiment with you. The theme for today’s template is a restaurant website which will include an image gallery for the menu and an integrated Google map that shows the location.

The great food photography is by avlxyz and you can find his Flickr photostream here.
The license for these pictures is the Attribution-NonCommercial-ShareAlike 2.0 Generic License.

The main homepage photo of Venice at night is by krossbow, be sure to check out his Flickr photostream.

When coming to the homepage, the background image will fade in and we will see the first welcome content block:

When the user clicks on “Our Menu”, a little thumbnails gallery will appear in the content area:

Choosing a dish from the thumbnails gallery, will open the fullscreen gallery, that shows the dish image with a title and a description and the same image as background. Using the navigation arrows on screen, the left/right keyboard arrows, or the scrolling wheel of the mouse, the user can slide the images. The title and description will animate back behind the foreground image during the sliding.

When clicking on the foreground image, it will disappear and the background will become more bright. Now, the user can view the fullscreen image and navigate through them the same way. Clicking on the background will bring us back the foreground gallery element.

When we click on the cross on the top right corner, we will leave the image gallery.

The menu point “Visit us” will hide the content box and show a google map as the background of the whole page:

And that’s it! We really hope you liked this template idea and find it useful!

View demoDownload source

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Mega Web Buttons Pack #1

Codrops News - Mon, 04/18/2011 - 02:31


View demoDownload source

Today we want to share our first set of easy-to-implement buttons called ‘Mega Web Buttons Pack’. In this set you will find 42 buttons which you can use easily on your website. We are using the WooFunction icon set released under the GNU General Public License.

Our first step is to add the following line of jQuery:

$('.btn').append($('<span />').addClass('helper'));

This means that we will create a new ‘span’ element which is the holder for the button icon.

If, for example, you want to add the ‘Chart’ button you need to add markup to your website:

<a href="#" class="btn chart">Chart</a>

or the ‘Search’ button:

<a href="#" class="btn search">Search</a>

In the CSS you can change the looks by, for example, changing the background color:

.btn.green { background:#2DA10C; }

and markup will be:

Search

etc. :)

We hope you like our experiment. Let us know which icon set you would like to see wrapped up like this in the future.

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Interactive Google Map using the Twitter API

Codrops News - Wed, 04/13/2011 - 16:42


View demo Download source

Hey! In today’s tutorial we will create an interactive Google map using the geocoding service. Using the Twitter API we will retrieve the user’s location, and then display the profile picture on the map. We will also add the click action, after which we will retrieve the user’s 5 latest tweets.

So, let’s start!

The Markup

At the beginning let’s write some simple HTML code.

<div id="map"></div> <div class="twitter"> <div class="inside"></div> </div> <div class="posts"></div> <div class="get"> <input type="hidden" value="marcinmobily" /> <input type="hidden" value="codrops" /> <input type="hidden" value="onextrapixel" /> <input type="hidden" value="smashingmag" /> <input type="hidden" value="umutm" /> <input type="hidden" value="1stwebdesigner" /> <input type="hidden" value="chriscoyier" /> <input type="hidden" value="marcofolio" /> </div>

Let’s examine the code line-by-line. The first “div” will display a Google map. Another “div” is the place where we store the description, name and profile picture of the Twitter users. Next, we create a “div” which will display the last 5 tweets.

At the end of the block, we store the Twitter user name, which will be used to download the location. If this is already done, we can proceed to write the JavaScript code.

The JavaScript

At the beginning we should define the global variables.

var map, geocoder, marker, ey, my, mouseDown = false;

Then we create the main object that will incorporate all functions used by us. The most important function in this object is the ‘init’ function.

var map, geocoder, marker, ey, my, mouseDown = false; var o = { init: function(){ // in this place we will call all needed functions } } $(function(){ o.init(); }

Let’s create a new object called “map” in the main “o” object. It is an object, where the function initiating a Google Map will be placed. The first function in this object is the “size” function, where we draw the current window size. This is what we need in order to display the map in full screen. Then we create the object entitled “data” with the parameters: “zoom”, “center” and “mapTypeId”. When the DOM is ready we call the init function.

var map, geocoder, marker, ey, my, mouseDown = false; var o = { init: function(){ this.map.init(); }, map: { size: function(){ var w = $(window).width(), h = $(window).height(); return { width: w, height: h } }, data: { zoom: 3, center: new google.maps.LatLng(52, 23), mapTypeId: google.maps.MapTypeId.ROADMAP }, init: function(){ var size = o.map.size(); $('#map').css({ width: size.width, height: size.height }); map = new google.maps.Map(document.getElementById('map'), o.map.data), geocoder = new google.maps.Geocoder(); google.maps.event.addListener(map, 'dragstart', function(){ $('.posts').hide(); }); } } } $(function(){ o.init(); }

The next step is to create an object, where we will retrieve the Twitter user data such as name, description, location and the path to the profile picture. First, we create a function where we will retrieve the value of the ‘input’ fields and we will store it in the array. The next stage is another function where every element of previously created tables is looped. Thus, by using the Twitter API, we can extract the user’s location and using a geocoding service we can convert it to geographic coordinates. At the end, we show the user in the right place on the map and put the name, description and user picture to a blank ‘div’ just called ‘twitter’ ;)

var map, geocoder, marker, ey, my, mouseDown = false; var o = { init: function(){ this.map.init(); this.twitter.show(); this.twitter.click(); }, twitter: { get: function(){ var arr = new Array; $('.get').find('input').each(function(i){ var t = $(this), val = t.val(); arr[i] = val; }); return arr; }, show: function(){ var users = o.twitter.get(), arr = new Array; for (i in users){ var user = users[i]; $.getJSON('http://twitter.com/users/show/'+user+'.json?callback=?', function(data) { var img = data.profile_image_url, screen_name = data.screen_name; geocoder.geocode({ address: data.location }, function(response, status){ if (status == google.maps.GeocoderStatus.OK) { var x = response[0].geometry.location.lat(), y = response[0].geometry.location.lng(); marker = new google.maps.Marker({ icon: img, map: map, title: screen_name, position: new google.maps.LatLng(x, y) }); arr.push('<div class="item">'); arr.push('<p class="img"><a href="#" class="open" rel="'+screen_name+'"><img src="'+img+'" alt="" /></a></p>'); arr.push('<div class="entry">'); arr.push('<a href="#" class="open title" rel="'+screen_name+'">'+data.name+'</a>'); arr.push('<p class="description">'+data.description+'</p>'); arr.push('<p class="url"><a href="'+data.url+'" target="_blank">'+data.url+'</a></p>'); arr.push('<p class="count">Followers: '+data.followers_count+', Following: '+data.friends_count+'</p>'); arr.push('</div>'); arr.push('</div>'); var html = arr.join(''); arr = []; $('.twitter').find('.inside').append(html); google.maps.event.addListener(marker, 'click', function(){ o.twitter.open(this.title); }); } }); }); } }, click: function(){ $('.twitter').find('.open').live('click', function(){ var t = $(this), rel = t.attr('rel'); o.twitter.open(rel); }); }, open: function(user){ var posts = $('.posts'), arr = new Array; $.getJSON('http://twitter.com/status/user_timeline/'+user+'.json?count=5&callback=?', function(data) { $.each(data, function(i, post){ arr.push('<div class="post">'); arr.push(post.text); arr.push('</div>'); }); var html = arr.join(''); posts.html(html).fadeIn(); }); } }, map: { size: function(){ var w = $(window).width(), h = $(window).height(); return { width: w, height: h } }, data: { zoom: 3, center: new google.maps.LatLng(52, 23), mapTypeId: google.maps.MapTypeId.ROADMAP }, init: function(){ var size = o.map.size(); $('#map').css({ width: size.width, height: size.height }); map = new google.maps.Map(document.getElementById('map'), o.map.data), geocoder = new google.maps.Geocoder(); google.maps.event.addListener(map, 'dragstart', function(){ $('.posts').hide(); }); } } } $(function(){ o.init(); }

Lastly, we will add a ‘scroll’ object that has a function called ‘init’ which is responsible for scrolling the ‘.twitter’ div vertically.

var map, geocoder, marker, ey, my, mouseDown = false; var o = { init: function(){ this.map.init(); this.twitter.show(); this.twitter.click(); }, twitter: { get: function(){ var arr = new Array; $('.get').find('input').each(function(i){ var t = $(this), val = t.val(); arr[i] = val; }); return arr; }, show: function(){ var users = o.twitter.get(), // retrieve all users which are stored in html arr = new Array; for (i in users){ var user = users[i]; $.getJSON('http://twitter.com/users/show/'+user+'.json?callback=?', function(data) { var img = data.profile_image_url, screen_name = data.screen_name; geocoder.geocode({ address: data.location }, function(response, status){ if (status == google.maps.GeocoderStatus.OK) { var x = response[0].geometry.location.lat(), y = response[0].geometry.location.lng(); marker = new google.maps.Marker({ icon: img, map: map, title: screen_name, position: new google.maps.LatLng(x, y) }); arr.push('<div class="item">'); arr.push('<p class="img"><a href="#" class="open" rel="'+screen_name+'"><img src="'+img+'" alt="" /></a></p>'); arr.push('<div class="entry">'); arr.push('<a href="#" class="open title" rel="'+screen_name+'">'+data.name+'</a>'); arr.push('<p class="description">'+data.description+'</p>'); arr.push('<p class="url"><a href="'+data.url+'" target="_blank">'+data.url+'</a></p>'); arr.push('<p class="count">Followers: '+data.followers_count+', Following: '+data.friends_count+'</p>'); arr.push('</div>'); arr.push('</div>'); var html = arr.join(''); arr = []; $('.twitter').find('.inside').append(html); google.maps.event.addListener(marker, 'click', function(){ o.twitter.open(this.title); }); } }); }); } }, click: function(){ $('.twitter').find('.open').live('click', function(){ var t = $(this), rel = t.attr('rel'); o.twitter.open(rel); }); }, open: function(user){ var posts = $('.posts'), arr = new Array; $.getJSON('http://twitter.com/status/user_timeline/'+user+'.json?count=5&callback=?', function(data) { $.each(data, function(i, post){ arr.push('<div class="post">'); arr.push(post.text); arr.push('</div>'); }); var html = arr.join(''); posts.html(html).fadeIn(); }); } }, map: { size: function(){ var w = $(window).width(), h = $(window).height(); return { width: w, height: h } }, data: { zoom: 3, center: new google.maps.LatLng(52, 23), mapTypeId: google.maps.MapTypeId.ROADMAP }, init: function(){ var size = o.map.size(); $('#map').css({ width: size.width, height: size.height }); map = new google.maps.Map(document.getElementById('map'), o.map.data), geocoder = new google.maps.Geocoder(); google.maps.event.addListener(map, 'dragstart', function(){ $('.posts').hide(); }); } }, scroll: { mouse: function(e){ var y = e.pageY; return y; }, check: function(y){ var all = $('.twitter').height(), inside = $('.twitter').find('.inside').height(); if (y < (all - inside)) { y = all - inside; } else if (y > 0) { y = 0; } return y; }, update: function(e){ var y = o.scroll.mouse(e), movey = y-my, top = ey+movey; check = o.scroll.check(top); $('.twitter').find('.inside').css({ top: check+'px' }); }, init: function(){ $('.twitter').find('.inside').bind({ mousedown: function(e){ e.preventDefault(); mouseDown = true; var mouse = o.scroll.mouse(e); my = mouse; var element = $(this).position(); ey = element.top; o.scroll.update(e); }, mousemove: function(e){ if (mouseDown) o.scroll.update(e); return false; }, mouseup: function(){ if (mouseDown) mouseDown = false; return false; }, mouseleave: function(){ if (mouseDown) mouseDown = false; return false; } }); } } } $(function(){ o.init(); } The CSS

First, we will embed our reset.css that will reset all the basic styles, and we’ll define some main properties:

@import url("reset.css"); html, body { margin:0; padding:0; } body { font-family:Arial, Helvetica, sans-serif; font-size:12px; color:#333; line-height:18px; } a { text-decoration:none; color:#fff; }

Next, we will define the styles for the map, Twitter posts and descriptions.

.twitter { position:fixed; left:0; bottom:0; background:#000; background:rgba(0, 0, 0, .7); width:100%; height:180px; color:#fff; overflow:hidden; } .twitter .inside { position:absolute; top:0; left:0; cursor:n-resize; } .twitter .item { float:left; width:280px; padding:20px; } .twitter .item .img { float:left; width:48px; } .twitter .img img { -moz-box-shadow:0 0 5px #000; -webkit-box-shadow:0 0 5px #000; box-shadow:0 0 5px #000; } .twitter .item .entry { float:right; width:215px; height:140px; color:#eee; font-size:11px; position:relative; } .twitter .item .count { position:absolute; left:0; bottom:-10px; font-size:10px; text-transform:uppercase; } .twitter .item .title { font-size:13px; font-weight:bold; color:#fff; } .twitter .item .url a { text-decoration:underline; } .twitter .item p { margin-bottom:5px; } .posts { display:none; position:absolute; left:50%; margin-left:-310px; width:580px; bottom:180px; background:#fff; color:#fff; background:#000; background:rgba(0, 0, 0, .7); padding:20px; } .posts .post { float:left; clear:both; width:100%; margin-bottom:20px; font-size:12px; font-weight:bold; } Conclusion

In today’s tutorial you learned how to use a geocoding service and how to use the Twitter API. An important fact to remember is that Google has imposed some limits to its geocoding service. Maximum number of requests in one day from a single IP address is 2500. Also, Twitter will rate limit the IP address from which the request was made.

Stay tuned for the next tutorial!

View demo Download source

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Circular Discography Template with jQuery

Codrops News - Mon, 04/11/2011 - 16:15

View demoDownload source

Today we want to share a simple website template with you. The template will show some discography or music albums in a rounded fashion, rotating the albums when clicking on next or previous. When clicking on an album, we will open the album details view which contains a music player (jPlayer) and a playlist of some songs. There is also a description area that can be scrolled.

We will be using the following jQuery plugins and scripts that will help us with the effects and the functionality:

We’ve added some nice music samples from the following artists:

Audiotechnica – Testing
by audiotechnica

Coffeeeurope -Arena Blanca
by Hektor Thillet

Ramblinglibrarian – Our Resolve
by Ivan Chew

Syenta – Emerging Cry
by Syenta

Thanks to the artists for releasing their music under the Creative Commons Attribution Noncommercial (3.0) Licence!

The initial screen of the template will show some loading element, and we will preload all the images. It will show the album view with the navigation arrows lined up in a diagonal:

When clicking on one of the navigations arrows, we will rotate the album and fade in the next/previous one:

When clicking on one of the albums, we will open the album detail view with a music player, a playlist and some detailed info on the album. The background image will now change to the one we had in the circle of the album before. The music will start automatically with the first song and continue through the playlist:

We hope you like this little template and find it useful!

View demoDownload source

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Collective: Timeglider, a jQuery Plugin

Codrops News - Thu, 04/07/2011 - 19:29

Timeglider is a zooming, panning data-driven timeline — great for history projects, project planning, and much more. This Javascript/jQuery plugin is completely free & open-source [MIT]..

Source

http://timeglider.com/jquery/

Demo

http://timeglider.com/jquery/large.html

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Collective: diagonalFade, a jQuery Plugin

Codrops News - Thu, 04/07/2011 - 19:23

diagonalFade is a jQuery plugin allowing you to easily specify direction, fade-in, fade-out, and a host of other options to a grouping of elements. All you have to do is import it, specify the container to which the group of items resides, and poof, you’re off and away..

Source

http://jonobr1.github.com/diagonalFade/

Demo

http://jonobr1.github.com/diagonalFade/

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy:

Moving Boxes Content with jQuery

Codrops News - Mon, 03/28/2011 - 18:04


View demoDownload source
Today we will create a website template with some really sweet animations using jQuery. The idea is to have little boxes scattered around at the top of the site and when a menu item is clicked, the boxes animate to form the main content area. We will use some different animation effects that we will add as options to the menu item.

The content area will custom scroll for which we will be using the really awesome jScrollPane Plugin by Kevin Luck. We will also use the jQuery 2d transformation plugin by Grady in order to rotate the little boxes while we animate them, and the the jQuery Easing Plugin for some spice.

The beautiful photos are by Jin. Visit his Flickr photostream at http://www.flickr.com/photos/jinthai/

So, let’s start!

The Markup

First, we want to place the background image with the grid overlay:

<div id="mb_background" class="mb_background"> <img class="mb_bgimage" src="images/default.jpg" alt="Background"/> <div class="mb_overlay"></div> </div>

The next div element will be used to add the little boxes with their random position and rotation degree

<div id="mb_pattern" class="mb_pattern"></div>

We will place a total of 16 boxes (div elements) into this container.
The menu and the heading will have the following HTML stucture:

<div class="mb_heading"> <h1>Lack of Color</h1> </div> <div id="mb_menu" class="mb_menu"> <a href="#" data-speed="600" data-easing="easeOutBack">About</a> <a href="#" data-speed="1000" data-easing="easeInExpo">Work</a> <a href="#" data-speed="600" data-easing="easeOutBack">Media</a> <a href="#" data-speed="1000" data-easing="easeInExpo">Contact</a> </div>

As you can see, we will add two “data-” attributes that we’ll use to define the speed and the easing effect that will be associated to the animation of the boxes. Read more about these new custom data attributes of HTML5 on John Resig’s blog: HTML 5 data- Attributes
Next, we will define the structure for the content area. There will be a main wrapper with the class “mb_content_wrapper” which contains all the content containers that have the class “mb_content” and a span for the closing cross:

<div id="mb_content_wrapper" class="mb_content_wrapper"> <span class="mb_close"></span> <div class="mb_content"> <h2>About</h2> <div class="mb_content_inner"> <p>Some text...</p> </div> </div> <div class="mb_content"> ... </div> <div class="mb_content"> ... </div> <div class="mb_content"> ... </div> </div>

One of the content elements is going to contain a list of images:

<div class="mb_content_inner"> <p>...</p> <ul id="mb_imagelist" class="mb_imagelist"> <li><img src="images/small/1.jpg" alt="image1" data-bgimg="images/image1.jpg"/></li> <li><img src="images/small/2.jpg" alt="image2" data-bgimg="images/image2.jpg"/></li> <li>...</li> </ul> <p>...</p> </div>

And that’s all the HTML. Now, let’s make it pretty!

The CSS

First, we will embed our reset.css that will reset all the basic styles, and we’ll define some main properties:

@import url('reset.css'); body{ background:#000; color:#fff; font-family: 'PT Sans Narrow', Arial, sans-serif; } a{ color:#fff; text-decoration:none; }

Next, we will define the styles for the image that we will use as a background and the overlay pattern:

img.mb_bgimage{ position:fixed; left:0px; top:0px; width:100%; opacity:0.8; z-index:1; } .mb_overlay{ width:100%; height:100%; position:fixed; top:0px; left:0px; background:transparent url(../images/pattern.png) repeat top left; z-index:2; }

They will both be of fixed positioning and we will give them a low z-index so that they really stay under everything else.

The little boxes will all have a height and width of 50 pixel and they will have absolute positioning:

.mb_pattern div{ position:absolute; width:50px; height:50px; background:#000; z-index:10; }

The main heading will also be positioned absolutely and we will use a font-face from the collection of Google Web Fonts:

.mb_heading h1{ position:absolute; top:10px; left:10px; font-size:86px; color:#000; text-shadow:0px 0px 1px #fff; font-family:"Astloch", Arial, sans-serif; z-index:4; }

The menu container will be placed absolutely to the left side of the screen:

.mb_menu{ position:absolute; top:154px; left:0px; z-index:11; }

The link elements inside of the menu container will be black boxes with a neat transition on hover:

.mb_menu a{ background-color:#000; margin-bottom:2px; opacity:0.9; display:block; width:98px; height:98px; color:#fff; line-height:98px; text-align:center; text-transform:uppercase; outline:none; -webkit-transition: all 0.2s ease-in; -moz-transition:all 0.2s ease-in; -o-transition: all 0.2s ease-in; -transition: all 0.2s ease-in; } .mb_menu a:hover{ color:#000; background-color:#fff; }

Read more about transitions in the W3 working draft at http://www.w3.org/TR/css3-transitions/ or in this great article on A List Apart by Dan Cederholm: Understanding CSS3 Transitions.

Next step is to style the content wrapper. We will give it a fixed width and height and a semi-transparent dark background. We’ll hide it initially:

.mb_content_wrapper{ background:transparent url(../images/bg_menu.png) repeat top left; width:400px; height:400px; position:absolute; top:154px; left:200px; z-index:4; display:none; }

Why don’t we just use opacity instead of a repeated background image? In some browsers all child elements will inherit that opacity level and we cannot set it higher for them. So, if we really want the inner elements to be completely opaque, it’s safer to use a background image for the surrounding container.

The little closing span will have the following style:

span.mb_close{ position:absolute; top:10px; right:10px; width:11px; height:12px; cursor:pointer; background:transparent url(../images/close.png) no-repeat top left; opacity:0.8; } span.mb_close:hover{ opacity:1.0; }

The content area is going to have some padding and we’ll hide it:

.mb_content{ padding:30px; display:none; }

The heading will have some background image for the stripe underline:

.mb_content h2{ font-family:"Astloch"; text-shadow:0px 0px 1px #fff; font-size:42px; background:transparent url(../images/line.png) repeat-x bottom left; padding:0px 0px 5px 0px; margin-bottom:10px; }

The following container is for the resting content and it will be this element that we will apply the custom scrollbar to:

.mb_content_inner{ line-height:24px; height:268px; outline: none; } .mb_content_inner p{ padding:5px 0px; }

For the thumbnail list in the “Work” section, we will have the following style:

ul.mb_imagelist li{ float:left; margin:2px; cursor:pointer; } ul.mb_imagelist li img{ display:block; opacity:0.3; -webkit-transition: all 0.5s ease-in-out; -moz-transition: all 0.5s ease-in-out; -o-transition: all 0.5s ease-in-out; -transition: all 0.5s ease-in-out; } ul.mb_imagelist li img:hover{ opacity:1.0; }

As you can see, we will add some transition to it, making the thumbnail become opaque smoothly.

And that’s all the main style. (You can check out the styling for the form and the footer in the style.css file.)

Let’s add some brio to the whole thing!

The JavaScript

So the main idea is to create those little boxes and scatter them around a restricted area and rotate them. When we click on a menu item, we’ll make those boxes animate to a certain position and form the main content container. Then we’ll show the container and the respective content. When clicking on the closing span, we want to make the boxes disperse again.
In the “Works” content, we will have some thumbnails that will show a background image when clicking on them.

So, let’s start by caching some elements:

var $menu = $('#mb_menu'), $menuItems = $menu.children('a'), $mbWrapper = $('#mb_content_wrapper'), $mbClose = $mbWrapper.children('.mb_close'), $mbContentItems = $mbWrapper.children('.mb_content'), $mbContentInnerItems= $mbContentItems.children('.mb_content_inner'); $mbPattern = $('#mb_pattern'), $works = $('#mb_imagelist > li'), $mb_bgimage = $('#mb_background > img'),

Next, we will define the “Menu” function:

Menu = (function(){ ... })(); /* call the init method of Menu */ Menu.init();

So, inside of our “Menu” function, we’ll define our main functionality, starting with a method to initialize the whole thing:

var init = function() { preloadImages(); initPlugins(); initPattern(); initEventsHandler(); },

We want to preload the images that we have in the “Work” content. The data attribute in the thumbnails tells us, which images we need:

preloadImages = function() { $works.each(function(i) { $('').attr('src' , $(this).children('img').data('bgimg')); }); },

The jScollPane plugin needs to be initialized, and we’ll apply the custom scroll to the inner content area of the content div when we call this:

initPlugins = function() { $mbContentInnerItems.jScrollPane({ verticalDragMinHeight: 40, verticalDragMaxHeight: 40 }); },

“initPattern” will randomly place 16 boxes (div elements) into a restricted area. We restrict that area by restricting the top and left values to a certain range:

initPattern = function() { for(var i = 0; i < 16 ; ++i) { //opacity, random top, left and angle var o = 0.1, t = Math.floor(Math.random()*196) + 5, // between 5 and 200 l = Math.floor(Math.random()*696) + 5, // between 5 and 700 a = Math.floor(Math.random()*101) - 50; // between -50 and 50 $el = $(' ').css({ opacity : o, top : t + 'px', left : l + 'px' }); if (!$.browser.msie) $el.transform({'rotate' : a + 'deg'}); $el.appendTo($mbPattern); } $mbPattern.children().draggable(); //just for fun },

When we close the content area we want to move the little boxes back, scattered around randomly again:

disperse = function() { $mbPattern.children().each(function(i) { var o = 0.1, t = Math.floor(Math.random()*196) + 5, l = Math.floor(Math.random()*696) + 5, a = Math.floor(Math.random()*101) - 50; $el = $(this), param = { width : '50px', height : '50px', opacity : o, top : t + 'px', left : l + 'px' }; if (!$.browser.msie) param.rotate = a + 'deg'; $el.animate(param, 1000, 'easeOutExpo'); }); },

Let’s handle the events:

initEventsHandler = function() { /* click a link in the menu */ $menuItems.bind('click', function(e) { var $this = $(this), pos = $this.index(), speed = $this.data('speed'), easing = $this.data('easing'); //if an item is not yet shown if(!$menu.data('open')){ //if current animating return if($menu.data('moving')) return false; $menu.data('moving', true); $.when(openItem(pos, speed, easing)).done(function(){ $menu.data({ open : true, moving : false }); showContentItem(pos); $mbPattern.children().fadeOut(500); }); } else showContentItem(pos); return false; }); /* click close makes the boxes animate to the top of the page */ $mbClose.bind('click', function(e) { $menu.data('open', false); /* if we would want to show the default image when we close: changeBGImage('images/default.jpg'); */ $mbPattern.children().fadeIn(500, function() { $mbContentItems.hide(); $mbWrapper.hide(); }); disperse(); return false; }); /* click an image from "Works" content item, displays the image on the background */ $works.bind('click', function(e) { var source = $(this).children('img').data('bgimg'); changeBGImage(source); return false; }); },

When we click on one of the thumbnails in the “Work” section, we want the background image to change. So we define:

changeBGImage = function(img) { //if its the current one return if($mb_bgimage.attr('src') === img || $mb_bgimage.siblings('img').length > 0) return false; var $itemImage = $('<img src="'+img+'" alt="Background" class="mb_bgimage" style="display:none;"/>'); $itemImage.insertBefore($mb_bgimage); $mb_bgimage.fadeOut(1000, function() { $(this).remove(); $mb_bgimage = $itemImage; }); $itemImage.fadeIn(1000); },

This shows a content item when there is already one shown:

showContentItem = function(pos) { $mbContentItems.hide(); $mbWrapper.show(); $mbContentItems.eq(pos).show().children('.mb_content_inner').jScrollPane(); },

“openItem” moves the boxes from the top to the center of the page, and shows the respective content item:

openItem = function(pos, speed, easing) { return $.Deferred( function(dfd) { $mbPattern.children().each(function(i) { var $el = $(this), param = { width : '100px', height : '100px', top : 154 + 100 * Math.floor(i/4), left : 200 + 100 * (i%4), opacity : 1 }; if (!$.browser.msie) param.rotate = '0deg'; $el.animate(param, speed, easing, dfd.resolve); }); } ).promise(); };

And that’s it! We really hope you enjoyed the tutorial and find it useful!

View demoDownload source

google_ad_client="pub-8092681487200304";google_ad_slot="5129482204";google_ad_width=468;google_ad_height=60; Share and Enjoy: