Web development , php , ajax , symfony, framework, zend
In: web resources
24 Mar 2010
Today you will learn, how you can create a Flash-like effect with only using a few lines of jQuery and a transparent PNG as mask.
Not only will you be able to dynamically change the color of the logo, but also add patterns as you wish and even animate them later with a few lines of code. With this technique you will also be able to add transition effects and control any single part of the colors, patterns and animations.
You can take a look to the finished Demonstration by clicking here. As you see, you will be able to adjust every single bit of the color, transparency, pattern and even the animation itself.
If you want to follow along, you can download the finished project files here (zip archive).
This technique generally does not require any jQuery at all – but we are using it, to make nice transitions and to be able to adjust the color, pattern and animation by a few sliders.
The Key-PNG for this Effect:
First you have to create a PNG-24 (24bit, so the alpha-channel gets saved too) similar to this one:

As you see, the transparency is not the outside of the logo. It is inside of it, where you want to change the color, apply the gradients, add patterns and animate them. The background should be exactly the same as in the container, in which the logo is going to be. You can either use a single color or whatever else you want to. Just take care if your background has a pattern so the transition is seamless to your main background-pattern.
The Pattern-PNG for the Animation Effect:
The next image we will need is the one with the gradient and/or pattern. The one I will use looks like this:

The dimensions of my pattern are 450 x 3000 pixel. The width should be exactly the same as the PNG-mask. The height does not matter. The higher, the better. Also make sure to remember the size. We will need it later in our script to adjust the animation.
Before we start creating our needed files, we first create our folder structure again. It should look something like this again:

Our index.html, which will be created at the root of this structure will need following wrappers around the PNG-mask:
<div id="wrapper"> <div id="color"></div> <div id="pattern"></div> <div id="logobox"></div> </div>
As you see here, we have 3 different wrappers for each element. The first one will contain only the color. The second one only the pattern. And the last one will only contain the PNG-mask, which also will be the topmost element.
Why three wrappers???
Maybe you ask yourself now, why we need 3 separate wrappers for each element, if we can do the same with only one. This is why: With 3 separate wrappers, we will be able to adjust different transparencies for every used element, without worrying about loosing opacity on the pattern or the logo itself.
For the sliders we will use the latest jQuery UI again – so you don’t have to worry too much about the structure there. Just make sure they have all the same class and different ID’s.
My Slider structure looks like this:
<!-- color sliders --> <div id="red" class="slider"></div> <div id="green" class="slider"></div> <div id="blue" class="slider"></div> <div id="alpha1" class="slider"></div> <!-- pattern sliders --> <div id="alpha2" class="slider"></div> <div id="speed" class="slider"></div>
For the buttons I’m using ordinary a-tags – Just give them all the same class and different ID’s again, so you can style them and bind different functions to them. We will later escape the default link-behavior by returning “false” in the script.
Scripts and styles in the header:
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/black-tie/jquery-ui.css" type="text/css" media="all" /> <link rel="stylesheet" href="css/style.css" type="text/css" media="all" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script> <script type="text/javascript" src="js/jquery-ui-1.8rc3.custom.min.js"></script> <script type="text/javascript" src="js/script.js"></script>
For saving bandwidth, we will link to the Google files again. Unfortunately the latest jQuery UI (version 1.8, release candidate 3) is not hosted there yet, so you have to host in on your own server. You can customize the download yourself here. You will only need the UI Core and the Slider Widget.
I cannot use the latest stable release (version 1.7.2) because there is a small “bug”, regarding the animation of the sliders, when changing the values programmatically. You can take a look at the bug-tracker ticket here. However, it is resolved in the latest release candidate, so I will not go further into the changes now.
Of course you can use the jQuery UI ThemeRoller to create your own slider-styles.
This time I will skip the CSS part completely because there is nothing special to take care of. The only thing you maybe want to add is classes for pattern-only settings and animation-only settings, so we can hide them later in our script by only using the class names as selector.
The first thing we have to do is to create document.ready function, so the scripts start, as soon as the DOM is loaded and before the page contents are loaded.
$(function(){
// put all your jQuery goodness in here.
});
Now we will setup a few variables at first:
// color container
var color = $("#color");
// pattern container
var pattern = $("#pattern");
// animation start/stop button
var startstop = $("#startstop");
// show/hide button
var showhide = $("#showhide");
// random-color button
var randomcolors = $("#randomcolors");
// default animation speed (5ms to 100ms)
var speed = 50;
// starting position of the pattern
var curPos = 0;
// reset-position
var resetPos = -(3000-117);
The last variable defines when our pattern hits the end, so we can start from the beginning again – it will be for the animation later. 3000 is the height of our pattern image and 117 is the height of our logo.
Don’t forget to put a minus in front of this value. The pattern will move up in its container with the CSS background-position animated.
Converting the slider-div’s to the jQuery UI sliders:
// setting up the jQuery UI sliders
$("#red, #green, #blue").slider({ animate:true, range:"min", max:255, slide:colorChanger, change:colorChanger });
$("#red").slider("value", 52);
$("#green").slider("value", 174);
$("#blue").slider("value", 203);
$("#alpha1").slider({ animate:true, range:"min", max:100, value:100, slide:alphaChanger1, change:alphaChanger1 });
$("#alpha2").slider({ animate:true, range:"min", max:100, value:100, slide:alphaChanger2, change:alphaChanger2 });
$("#speed").slider({ animate:true, range:"min", min:5, max:100, value:50, slide:speedChange, change:speedChange });
This is everything you need, to “install” the sliders and setup the starting-values and behaviors.
I will go true all options, so you know what you are doing here:
If you need more information about the options and events we are using, you can take a look at the documentation here.
Now everything is ready to create our main functions.
Converting RGB to HEX
// RGB to HEX converter (with 3 arguments)
function rgbToHex(r,g,b){
var hex = [
// converting strings to hex (16)
r.toString(16),
g.toString(16),
b.toString(16)
];
// get all 3 values of the array
$.each(hex, function(nr, val){
// make sure they are not empty
if (val.length == 1){
// add leading zero
hex[nr] = "0" + val;
}
});
// returns a valid hexadecimal number
return hex.join("").toUpperCase();
}
With this function, we will convert the values of the red, green and blue sliders to a valid hexadecimal for using it in CSS.
For making this work, we need to pass 3 variables to the function (r,g,b) and convert those strings to hex-code. We do so by using .toString(16).
We also wrapped them into an array, so we can go through them now by jQuery’s each() loop, passing the index of the array (nr) and the value (val) to the loop.
Last thing we need to to is to join those 3 values and converting them to uppercase.
Background-color Changer:
// changing the colors
function colorChanger(){
// value of the "red"-slider
var red = $("#red").slider("value");
// value of the "green"-slider
var green = $("#green").slider("value");
// value of the "blue"-slider
var blue = $("#blue").slider("value");
// converting values to hex
var hex = rgbToHex(red,green,blue);
// changing the background-color of the wrapper
color.css("background-color", "#" + hex);
}
This function will get all 3 values of our red-, green- and blue-sliders, convert the values to a valid hex-code using the previous function and change the css of our color-container.
That’s all! You should now be able to change the color of your logo. (You have to comment out the alpha and the speed sliders, or you will get a JavaScript error.)
Opacity Changer:
// change the opacity of the color-wrapper
function alphaChanger1(){
var opacity = $("#alpha1").slider("value") / 100;
color.css("opacity", opacity );
}
// change the opacity of the pattern-wrapper
function alphaChanger2(){
var opacity = $("#alpha2").slider("value") / 100;
pattern.css("opacity", opacity );
}
Those two functions will handle the opacity of the color-wrapper and the pattern-wrapper. Nothing special there. Just make sure to divide your value by 100, so you get a value between 0.00 and 1.00. This step is important because the opacity attribute does not accept 3 digits as value. So a 50% opacity will be 0.50.
You can also combine those two functions by passing the correct container returning the right value. I skipped this step. It’s quick and dirty – but it works!
Function for the Animation:
// pattern animation
function patternScroller(){
// substracting 1 with every call
curPos--;
// if it hits our reset-position, back to 0
if (curPos == resetPos){ curPos = 0; }
pattern.css("background-position", "0 " + curPos + "px");
}
Every time this function gets called, we will subtract 1 from our current position variable (curPos). If it hits the value of our reset position (resetPos), we will set it back to 0. The last step there is to change the vertical position of the background from our pattern-container.
Speed Changer:
// animation speed changer
function speedChange(){
// get the current value of the speed-slider
speed = $("#speed").slider("value");
// clear interval, if there is any
clearInterval(initScroll);
// set a new interval with the current speed
initScroll = setInterval(patternScroller, speed);
}
This function will change the speed of our animation. First we need to get the current value of our speed-slider. After this we have to clear any previous interval (if there is any). Last but not least we are creating a new interval. This will call our previous function (patternScroller) every x milliseconds. The x stands for the value of our speed slider.
Random Color and Alpha function:
// random color function
function randomColors(){
$("#red").slider("value", Math.floor(Math.random()*256), true);
$("#green").slider("value", Math.floor(Math.random()*256), true);
$("#blue").slider("value", Math.floor(Math.random()*256), true);
$("#alpha1").slider("value", Math.floor(Math.random()*101), true);
}
This function will change the values of the red, green, blue and alpha1 sliders randomly when called. It does so by using JavaScripts Math.random() function. To make sure the returned value is not 0, just add 1 to the maximum value. To make it a Integer we wrapped returned value into Math.floor(), so it gets rounded downwards to the nearest integer.
This function is now ready to be bound to button:
// random colors button
randomcolors.click(function(){
// if button has no "random" class
if (!$(this).hasClass("random")){
// add it
$(this).addClass("random");
// change the button text
$(this).text("random-colors & alpha: ON");
// call the random function once
randomColors();
// set a intervall with the random function
randomizer = setInterval(randomColors, 2000);
} else {
// remove the class
$(this).removeClass("random");
// change the button text
$(this).text("random-colors & alpha: OFF");
// clear the interval
clearInterval(randomizer);
}
// change the default link-behavior
return false;
});
We will check if the random-function is already running by adding and removing a class (“random”) to the button.
The important parts of this whole function is setting/clearing the interval. The interval will get called every 2 seconds (2000 milliseconds) and the first call is after 2 seconds, so we are manually calling it the first time. By returning false, we make sure the override the default behavior of a link.
Show and Hide the Pattern container:
// show and hide the pattern
showhide.click(function(){
// if button has no "visible" class
if (!pattern.hasClass("visible")){
// add it
pattern.addClass("visible");
// change the text
$(this).text("hide pattern");
// fade in the pattern-container
pattern.stop().fadeTo(1000, 1);
// fade in all elements with the class "forpattern"
$(".forpattern").stop().fadeTo(800, 1);
} else {
// remove the class
pattern.removeClass("visible");
// change the button text
$(this).text("show pattern");
// fade out the pattern-container
pattern.stop().fadeTo(800, 0);
// fade out all elements with the class "forpattern"
$(".forpattern").stop().fadeTo(800, 0);
}
// change the default link-behavior
return false;
});
Again we are checking if the pattern is hidden or not by adding and removing a class to the button (“visible”). Nothing complicated in here – by now, everything should be clear. Just to make sure: The second fade-effect is used to show/hide all elements which have the class “forpattern”.
Start and Stop the Animation:
// start and stop the animation
startstop.click(function(){
// if button has no "scrolling" class
if (!pattern.hasClass("scrolling")){
// add it
pattern.addClass("scrolling");
// change the text
$(this).text("stop animation");
// start a new intervall with current speed-slider value
initScroll = setInterval(patternScroller, speed);
// fade in all elements with the "foranimation" class
$(".foranimation").stop().fadeTo(800, 1);
} else {
// remove the class
pattern.removeClass("scrolling");
// change the button text
$(this).text("start animation");
// clear the interval again
clearInterval(initScroll);
// fade out all elements with the "foranimation" class
$(".foranimation").stop().fadeTo(800, 0);
}
// change the default link-behavior
return false;
});
This is the last button-function we need for this project.
It will start and stop the animation of our pattern. To distinguish if the animation is already started or not, we are again adding and removing a class (“scrolling”). If the button does not have this class yet we are adding it, initiate an interval with the current value of our “speed” variable. If it has this class, we remove it and clear this interval again. For a little bit eye candy we are again fading all elements with the class “foranimation” in and out.
You should now have a Flash-like color and pattern morphing logo, using only a transparent PNG as mask and a few jQuery functions. You can take a look at the demo by clicking here or download all files by clicking here.
If you have any questions or need help with any of the steps, feel free to ask them in the comments!
Happy coding!
This blog delivers stylish and dynamic news for designers and web-developers on all subjects of design, ranging from: CSS, Ajax, Javascript, web design, graphics, typography, advertising & much more. Our goal is to help you communicate effectively on the web with an engaging website or functional interface.
2 Responses to How to Create a Flash-like Color and Pattern Morphing effect with jQuery
Khaled
March 25th, 2010 at 5:20 pm
First: Go to File -> Save Movie File.
Second: Choose a directory to save the file, there will pop up a list, choose: My Computer.
Third: Choose name for the movie and the directory to be saved to.
Fourth: Choose the quality.
Sixth: Relax and wait until it ends saving the movie.
Khaled
jason c
April 9th, 2010 at 9:45 pm
The higher the frame rate the smoother the animation but the longer it takes to make.
Ja.