Step 1 – Setup Your HTML, CSS, and MooTools
Before starting, take a look at the demo. It will be easier to understand the purpose of each step if you know the goal.First, create a simple HTML file, and add a link to the stylesheet (main.css) and to two JavaScript files (mootools.js and main.js). Create those files in the same directory. Then go to the MooTools Core Builder. Select all of the components and then click Download. This will download mootools-1.2-core.js. Copy the contents of that file to the mootools.js file. Then got to the MooTools More Builder and select all of the components and click Download. Copy the contents again and paste them at the bottom of mootools.js.
(Note: Most sites, including this photo gallery, do not need all of the components. However, using all of them at the beginning, and then cutting out the ones you don’t need make development a lot easier. If you were in the middle of a project and realized you wanted a different featured included in one of the components you didn’t download, you would have to download it again before continuing. This way, you only have to download it again after you are finished.)
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Photo Gallery</title>
- <link rel="stylesheet" type="text/css" href="main.css" />
- <script type="text/javascript" src="mootools.js"></script>
- <script type="text/javascript" src="main.js"></script>
- </head>
- <body>
- </body>
- </html>
Step 2 – Create the Layout
Now we have to create the layout for our photo gallery using HTML and CSS. Add the following code inside the body tags of your HTML file.- <div id="container">
- <h1>Photo Gallery</h1>
- <div id="picture_section">
- <div id="inside">
- <img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" />
- <img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" />
- <img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" />
- <img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" />
- <img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" /><img src="#" />
- </div>
- </div>
- <div id="controls_vert">
- <div id="up" class="deactivated">Scroll Up</div>
- <div id="down">Scroll Down</div>
- </div>
- <div id="controls_horz">
- <div id="left">Left</div>
- <div id="right">Right</div>
- </div>
- </div>
- * { margin:0; padding:0; outline:none; }
- .hide { display:none; }
- body {
- background:#000;
- color:#fff;
- padding:30px;
- font-family:Arial, Helvetica, sans-serif;
- }
- #container {
- width:596px;
- height:400px;
- background:#111;
- overflow:hidden;
- border:1px solid #333;
- }
- h1 {
- background:#222;
- width:592px;
- height:29px;
- padding-left:7px;
- border-bottom:1px solid #333;
- font-size:18px;
- line-height:29px;
- font-weight:normal;
- }
- #picture_section {
- padding:7px 0 7px 7px;
- width:590px;
- height:332px;
- overflow:hidden;
- }
- #inside {
- width:590px;
- height:332px;
- }
- #picture_section img {
- border:0;
- height:57px;
- width:111px;
- float:left;
- background:#333;
- margin-bottom:7px;
- margin-right:7px;
- cursor:pointer;
- }
- #controls_vert {
- background:#222;
- width:600px;
- height:23px;
- border-top:1px solid #333;
- }
- #controls_horz {
- background:#222;
- width:600px;
- height:23px;
- border-top:1px solid #333;
- }
- #up {
- height:10px;
- width:10px;
- margin-right:7px;
- background:url(up.jpg) no-repeat;
- text-indent:-9999px;
- float:left;
- margin:7px;
- margin-bottom:6px;
- cursor:pointer;
- }
- #down {
- height:10px;
- width:10px;
- background:url(down.jpg) no-repeat;
- text-indent:-9999px;
- float:left;
- margin:7px;
- margin-left:0;
- margin-bottom:6px;
- cursor:pointer;
- }
- #left {
- height:10px;
- width:10px;
- background:url(left.jpg) no-repeat;
- text-indent:-9999px;
- float:left;
- margin:7px;
- margin-bottom:6px;
- cursor:pointer;
- }
- #right {
- height:10px;
- width:10px;
- background:url(rightright.jpg) no-repeat;
- text-indent:-9999px;
- float:left;
- margin:7px;
- margin-left:0;
- margin-bottom:6px;
- cursor:pointer;
- }
- div#up.deactivated { opacity:0.2; filter:alpha(opacity=20); cursor:default; }
- div#down.deactivated { opacity:0.2; filter:alpha(opacity=20); cursor:default; }
- div#right.deactivated { opacity:0.2; filter:alpha(opacity=20); cursor:default; }
- div#left.deactivated { opacity:0.2; filter:alpha(opacity=20); cursor:default; }
Now, let’s add the overlay that will show the large images. First, add the following code right before the closing body tag in your HTML file.
- <div id="display_picture_container">
- <div id="display_picture">Click on the image to go back to the gallery.</div>
- <div id="display_picture_img"></div></div>a
- #display_picture_container {
- position:absolute;
- top:0;
- left:0;
- width:700px;
- height:400px;
- padding-top:16px;
- }
- #display_picture {
- position:absolute;
- top:61px;
- left:31px;
- width:596px;
- height:330px;
- background:#000;
- opacity:0.8; filter:alpha(opacity=80);
- text-align:center;
- font-size:11px;
- padding-top:16px;
- }
- #display_picture_img {
- position:absolute;
- top:108px;
- left:65px;
- height:272px;
- width:530px;
- cursor:pointer;
- }
Step 3 – Collect and Resize Your Pictures
This is a good time to collect all of your pictures and resize them. First of all, create a “pictures” folder and a “thumbs” folder. Add all of your pictures to the pictures folder and name them 1.jpg, 2.jpg, 3.jpg, etc. Resize them all to the size of the display_picture_img div: 530 pixels wide and 272 pixels tall. Then copy those files to the thumbs directory and resize those copies to 111 pixels wide by 57 pixels tall. It doesn’t matter how many pictures you have. However, I would recommend using over 26 for this tutorial so you can use the vertical scrolling.Step 4 – Add Functionality With MooTools
The first thing to do is remove all of the <img src=”#” /> tags in the HTML file. Those were only placeholders; we will add the actual files with JavaScript later. Now we will make the overlay vanish when the page loads. Add the following code to the main.js file- var number_of_pictures = 32;
- function show_pictures () {
- var while_pictures = 1;
- while(while_pictures <= number_of_pictures) {
- var new_image = new Element('img', {
- 'src': 'thumbs/' + while_pictures + '.jpg',
- 'id': 'image_' + while_pictures,
- 'events': {
- 'click': function(){
- $('display_picture_img').innerHTML = "<img src=\"" + this.src.replace('thumbs/', 'pictures/') + "\" id=\"big_picture\" class=\"" + this.id + "\" />";
- $('display_picture_container').fade(1);
- $('big_picture').fade(.999999);
- $('controls_vert').setStyle('display', 'none');
- if(this.id.replace('image_', '')==1) {
- $('left').set('class', 'deactivated');
- $('right').erase('class');
- } else if(this.id.replace('image_', '')==number_of_pictures) {
- $('left').erase('class');
- $('right').set('class', 'deactivated');
- } else {
- $('left').set('class', 'activated');
- $('right').erase('class');
- }
- $('controls_horz').setStyle('display', 'block');
- $('left').tween('margin-left', '286px');
- }
- }
- });
- new_image.inject($('inside'));
- // preload all of the images
- var preload_image = new Element('img', {
- 'src': 'pictures/' + while_pictures + '.jpg',
- 'class': 'hide'
- });
- preload_image.inject($('container'));
- // NOTE: I didn't create an alt attribute because it won't be seen by anyone here anyway.
- while_pictures++;
- }
- }
- window.addEvent('domready', function() {
- show_pictures();
- $('display_picture_container').fade('hide');
- });
Now for the large part: the show_pictures function. First of all, we set the number_of_pictures variable. This tells the function to add thumbnails from the thumbs folder using every integer from 1 to the given number. To add more pictures to this slideshow, all you have to do is add them to the folders, resize them, and increase the number_of_pictures value. I used 32.
The next part is the internal workings of show_pictures. This does, as the name suggests, show all of the pictures. It also preloads the larger pictures in the background. Inside of the function, while_pictures is defined as 1. This is the variable we will use as the starting point for displaying all of the pictures. The following while statement shows that the code inside will be executed one time for each picture, starting at one and going up to the total number of pictures (number_of_pictures). Notice that while_pictures++; is at the end of the while loop, to have it increase by one each time the loop repeats.
Next, we create an Element instance for an img element. We can add src, id, class, event, and other attributes. However, we only need src, id, and events. By using ‘src’: ‘thumbs/’ + while_pictures + ‘.jpg’, we state that we want the src of the image to be whatever oru current number is, and inside the thumbs folder. The ids for all of our thumbnails will be image_1, image_2, etc.
Now use the .fade(1) method to fade in the display_picture_container div and all of its contents. The 1 represents the level of opacity (1 is 100%, .5 is 50%, etc.). However, this causes a bug in all but the newest browsers such as Firefox 3 and Safari. They fade in correctly, but the others just pop in the image and fade the darker area around it. After much experimentation, I found out that if you have the large picture (which has big_picture as its id) fade in with its own fade method, it works—but only if the fade is not set to 1. However, we want the picture to be at 100% opacity. Therefore, I set it to .999999, which has no noticeable transparency.
So now the large picture is on the screen. However, we also want the controls to move to the center and become left and right arrows, instead of up and down arrows. First of all, we hide the vertical controls (controls_vert). We can use display:none; for this, because we are not going to be fading it in or out. Then we use an if, if else, and else statement to determine if the image that was clicked on was the first or last one in our gallery. If it was the first one, we don’t want it to be able to go to the left, because no previous one exists. The same thing is necessary at the right. Later on, when we have the left and right arrows working, we will have it detect whether or not it has a deactivated class. This will determine if the click event will work for it. (Also, check out the CSS. It sets the arrow image to 20%. This saves the need of having 8 directional arrow images instead of 4.)
Next, we display the horizontal controls by setting its display style to block. So, by hiding the vertical controls and showing the horizontal controls, we have just switched them out. However, we want the horizontal controls to be centered. I accomplished this by creating a tween that animates an increase in the left margin to 286px, which is the center of the gallery.
Now that we have our new_image created, we have to put it inside of the document. The inject method allows us to insert the newly made img element into the inside div.
We also want to preload each of the images, too, so there won’t be any delay when people actually click on the images to fade them in. We create a new img element for each picture that is full-sized. However, it uses the hide class, which, in our CSS, uses display:none; to hide the contents. Then we inject the hidden preloader image into the container div.
Here is what it looks like after you click on a thumbnail:
- $('display_picture_img').addEvent('click', function(){
- $('display_picture_container').fade(0);
- $('big_picture').fade(0);
- $('up').setStyle('margin-left', '286px');
- $('controls_horz').setStyle('display', 'none');
- $('controls_vert').setStyle('display', 'block');
- $('left').setStyle('margin-left', '7px');
- $('up').tween('margin-left', '7px');
- });
Now take the following code and paste it above the cod you just entered.
- var vertical_moves = 0;
- var rows = Math.ceil(number_of_pictures/5);
- if(rows>5) {
- $('up').addEvent('click', function(event){
- if(!$('up').hasClass('deactivated')) {
- vertical_moves--;
- $('down').erase('class');
- $('inside').tween('margin-top', '-'+ (64 * vertical_moves) +'px');
- if (vertical_moves==0) {
- $('up').set('class', 'deactivated');
- }
- }
- });
- $('down').addEvent('click', function(event){
- if(!$('down').hasClass('deactivated')) {
- vertical_moves++;
- $('up').erase('class');
- $('inside').tween('margin-top', '-'+ (64 * vertical_moves) +'px');
- if(vertical_moves == (rows-5)) {
- $('down').set('class', 'deactivated');
- }
- }
- });
- } else {
- $('up').set('class', 'deactivated');
- $('down').set('class', 'deactivated');
- }
- var current_id = 1;
- $('left').addEvent('click', function(){
- if(!$('left').hasClass('deactivated')) {
- current_id = $('big_picture').get('class').replace('image_', '');
- current_id--;
- $('big_picture').fade('hide');
- $('big_picture').set('src', 'pictures/' + current_id + '.jpg');
- $('big_picture').fade(1);
- $('big_picture').set('class', 'image_' + current_id);
- if(current_id==1) { $('left').set('class', 'deactivated'); }
- if(current_id==(number_of_pictures-1)) { $('right').erase('class'); }
- }
- });
- $('right').addEvent('click', function(){
- if(!$('right').hasClass('deactivated')) {
- current_id = $('big_picture').get('class').replace('image_', '');
- current_id++;
- $('big_picture').fade('hide');
- $('big_picture').set('src', 'pictures/' + current_id + '.jpg');
- $('big_picture').fade(1);
- $('big_picture').set('class', 'image_' + current_id);
- if(current_id==2) { $('left').erase('class'); }
- if(current_id==number_of_pictures) { $('right').set('class', 'deactivated'); }
- }
- });
Next, we detect if there are more than five rows. If there aren’t, we deactivate the up and down arrows. With five rows or less, all of the pictures are shown without the need for the scroll buttons. However, if there are six or more, we want to add events to them. For the up arrow div, we add an event and then detect whether it has been labeled as deactivated or not. If it is deactivated, it will show up with only 20% opacity, and when you click on it, it won’t do anything. Additionally, it won’t have a pointer as a cursor anymore. However, if it doesn’t have that class, it continues. If you are going up, it decreases the amount of rows down you have gone, so vertical_moves decreases by one row. It then erases any class that the down div has. If it is on the bottom row and the down arrow is deactivated, once it moves up a row, it will be able to move down again. Therefore, it stops it from being deactivated.
Next, it makes all of the thumbnails move up by detecting what the new vertical_moves is, multiplying it by 64, and making it negative. The number 64 is used because that is the height of a row of thumbnails plus the margin below it. It then applies this value to the margin-top. For example, if the margin-top was originally -128px, it would move upwards because the new margin-top would only be -64px. The tween method makes it fade to its new position. Inside the main.css file, it has the picture_section div hide its overflow. This is so that when you apply a negative margin-top, it hides it instead of sticking through.Then it determines if it is at the top of the gallery. If it is, it deactivates the up arrow so it can’t go up any farther. The down arrow has the same actions applied, except in reverse.
Now we will make the left and right buttons function correctly. First of all, we set current_id equal to one to create the variable. This will help us determine which large image is being displayed (remember, the left and right buttons only appear when a large image is being displayed). Then we add a click event to the left div and check if it is deactivated or not. If it isn’t, we detect the class of the img with the id of big_picture. This was set earlier as image_(enter number of current image here). We use the get method to find this and the replace method to remove the image_ prefix. Then we subtract it by one, because, by moving to the left, we are going back to a picture with an id of one less.
Next, we hide the image itself instantly, and then change it’s src to the previous image. We then fade the image in to 100% opacity. After that, we change the image’s class to its new value, which enables a user to go left repeatedly. We then detect if it is at the very first picture. If so, we can’t go left anymore, so we deactivate the left button. If it is the next to last picture after clicking left, then it means that it was just on the last picture, where the right button would be disabled. If that is the case, we enable the right button so they can continue forward. Almost the identical actions are applied to the right button, except, again, in reverse.
Step 4 – Testing and Optimization
Now that’s about it. The large picture fades in when you click on a thumbnail, you can move left and right, go back to the main gallery by clicking on the large image, and scroll up and down. But wait! After developing in a good browser such as Firefox, you need to test it in other popular browsers such as Safari, IE6, and IE7. I tested them all, and they all worked, except for—surprise!—Internet Explorer 6. When you click on an image and the horizontal controls slide out, they slide out much too far in IE6. For some reason, IE6 thinks that what every other browser thinks is 286px is only 143px. So, change the following code:- $('left').tween('margin-left', '286px');
- if(Browser.Engine.trident4) { $('left').tween('margin-left', '143px'); } else { $('left').tween('margin-left', '286px'); }
- $('up').setStyle('margin-left', '286px');
- if(Browser.Engine.trident4) { $('up').setStyle('margin-left', '143px'); } else { $('up').setStyle('margin-left', '286px'); }
And there you have it: a working MooTools photo gallery. Remember, that the MooTools documentation is always useful when developing a site with MooTools. I hope this helps out people trying to combine many JavaScript actions into a complete site.
0 comments:
Post a Comment