Tuesday, May 21, 2013

Fun using css "background-position"


Last week I had checked a beautiful demo of a moving background here and I decided to shell out my own version. Check the image below to learn what I was upto.




The above graphic was done by modifying the background picture position of a DIV using Javascript.

It has four buttons at the bottom, if we click on the "<" button, the digits seem to flow from right to left; by clicking on the '^' button, the digits seem to flow from bottom to top etc. How the whole stuff actually works is described below.

a. First we create an image of digits. Example image is given here..



b. Second, we create a PNG image where the text "PHP" section is totally transparent. Example image is given here..In the picture below, some part is transparent, hence nothing is seen on browser. 


c. We take a DIV with same hight and width as of the PNG image mentioned in step (b) above.
d. We set the background image of the above DIV to the digits image we created in step (a)
e. Now if we change the background-position of the background image of the DIV in a constant manner, the above animation can be achieved.

We set the background image of the DIV through CSS, but we change the "background-position" through Javascript as shown below.

document.getElementById("scrollDiv").style.backgroundPosition = '10px 13px';

The value '10px 13px' defines x-position and y-position of the image. If we increase constantly the y-position from 13px, it would cross the height of the image and hence the image would be gone away and the animated effect would stop. That's why we use "repeat" while setting the background image for the DIV. This would repeat the background image even when we cross the image height/width limit. However, we have put a check in our JS logic that when during scrolling the background image, if any x-position or y-position values are crossing their limit, they are reset to 0.

The Javascript works the following way ::
a. When a button is clicked, we call use-defined scroll() function with a parameter denoting the direction.
b. scroll() function sets a timer so that scr_oll() function is called every 50 milliseconds.
c. The scr_oll() also takes the direction value as a parameter. This function reads the existing background-position style attribute (initially '0px 0px' or '0% 0%') from the DIV. It then clears the 'px' or '%' characters from that value, extracts correct x-pos and y-pos values, then does some maths to set a new value to that background-position style attribute of the DIV. We also check if the x-pos/y-pos values remain within range;

Check the implementation below.

<html>
<head>
<script>
var max_bottom = 300; // Image height of digits.jpg
var max_right  = 599; // Image width of digits.jpg
var timer = '';       // For timer

function scroll(dir)
{
  // Clear any Old Interval if exists
  clearInterval( timer );
  // Set new Interval
  timer = setInterval( function () { scr_oll(dir); }, 50 );
}

// Main function which scrolls the background image
function scr_oll(dir )
{

 // GEt existing background-position
 var backp_css = document.getElementById("scrollDiv").style.backgroundPosition;

 // Remove spl chars
 backp_css = backp_css.replace(/%/g,'');
 backp_css = backp_css.replace(/px/g,'');

 // Split to get xpos and ypos values
 var arr = backp_css.split(" ");

 // Scrolling from top to bottom
 if(dir == 1)
 {
   // For top-to-bottom scroll, we would
   // incerase the ypos value by 1
   var ypos = parseInt(arr[1]) + 1;
  
   // If crossing the maximum, reset
   if( ypos > max_bottom ) ypos = 0;
  
   // Build the final CSS string
   var css_str = arr[0] + 'px ' + ypos + 'px';
 }

 // Scrolling from bottom to top
 if(dir == 3)
 {
   // For bottom-to-top scroll, we would
   // decerase the ypos value by 1
   var ypos = parseInt(arr[1]) - 1;
  
   // If crossing the minimum low, reset
   if( ypos < 0 ) ypos = max_bottom;
  
   // Build the final CSS string
   var css_str = arr[0] + 'px ' + ypos + 'px';
 }

 // Scrolling from right to left
 if(dir == 2)
 {
   // For right-to-left scroll, we would
   // decerase the xpos value by 1
   var xpos = parseInt(arr[0]) - 1;
  
   // If crossing the minimum low, reset
   if( xpos < 0 ) xpos = max_right;
  
   // Build the final CSS string
   var css_str = xpos + 'px ' + arr[1] + 'px';
 }

 // Scrolling from left to right
 if(dir == 4)
 {
   // For left-to-right scroll, we would
   // incerase the xpos value by 1
   var xpos = parseInt(arr[0]) + 1;
  
   // If crossing the minimum low, reset
   if( xpos > max_right ) xpos = 0;
  
   // Build the final CSS string
   var css_str = xpos + 'px ' + arr[1] + 'px';
 }

 // Set new background-position
 document.getElementById("scrollDiv").style.backgroundPosition = css_str;
}
</script>
</head>

<body>



<!-- We set the background Image to the DIV -->
<div id='scrollDiv' style="background:url('digits.jpg');height:250px;width:300px;border:0px solid tomato">
 <img src='php.png' style='display:block'>
</div>

<!-- Direction Buttons -->
<input type='button' value='<' title='Left' onclick='scroll(2)'>
<input type='button' value='>' title='Right' onclick='scroll(4)'>
<input type='button' value='˄' title='Top' onclick='scroll(3)'>
<input type='button' value='˅' title='Bottom' onclick='scroll(1)'>

</body>
</html>


Copy-paste the above code and supply the images used, this would run on all browsers.

The scroll() function clears any previous timer set, by calling clearInterval() function. It is necessary otherwise n number of timer might get created and force the browser to execute all of them at the same interval.

No comments: