CSS: Position-x and Position-y (Updated)

Updated code

I’ve updated the article and code to use more modern methods. See the CodePen below for more details:

Position-x: Position-y:

View CodePen

Please visit the CodePen above if you would like to implement position-x and position-y.

[Caution] Below is the pre 2009 method if anyone is still interested…

While building out a content management system for DMP I needed to create a toolbar which would stay with position: fixed; on the y-axis, but act like position: absolute on the x-axis. To achieve this I used a clever JavaScript class from David Walsh called scrollspy.

View the old Demo

The JavaScript

Things you will need first: Mootools (This demo uses 1.2.4) and the ScrollSpy plugin from David Walsh. Next write this for you element:

var ss = new ScrollSpy({
     mode: 'horizontal',
     onTick: function(position,state,enters,leaves) {
          $("sidePanel").style.left = -position.x+"px";
     },
     container: window
});

The CSS

In the CSS use position: fixed; because we have handled the position-x: absolute; in JavaScript. so:

#sidePanel {
     position:fixed;
     left:0;
     top:0;
     width:250px;
     z-index:1000;
}

The above example will keep our sidePanel element from disappearing when you scroll down the page but it will scroll with the page when the user scrolls right.

To do the opposite ie. position-x: fixed; position-y: absolute; In the JavaScript change mode: ‘horizontal’ to mode: ‘vertical’ and -position.x+”px”; to -position.y+”px”; and that’s it any comments, ideas or improvements leave them below.

RickyH – Halloween Logo

[UPDATE 02/07/2013]

I found this kicking around since 2009. What was I thinking:
Caution flashing images:
Stars DEMO Click [FUTURE] to freak out.
Follow cursor DEMO

Original article

So its Halloween again and to celebrate I decided to create a new logo. I have to begin by apologizing to people using Internet Explorer because the Logo simply won’t work; this is partially to do with me being too lazy to port it over and partly because IE stinks and doesn’t support the CANVAS element.

The following steps show how i made my Halloween Logo:

Step 1: Turn your logo into a mask

New Design Of RickyH.co.uk

To change a logo into a mask simply select the outline of your logo shape. Photoshop: (cmd/ctrl click layer); and remove the selection from a solid square of slightly bigger size. Set the mask-image’s background-color to the background-color of your website (In my case my #141414). Now save the image with a transparent background as .png (or .gif if you care about IE6). View my image

Step 2: The HTML

<div id="headerimg">
     <canvas id="bloodyMess" />
     <a href="http://www.rickyh.co.uk/"/>
</div>

So we have three elements: The holder div, the canvas element and an anchor element.

Step 3: The CSS

#headerimg {
     position:absolute;
     background-color:#141414;
     width:157px;
     height:188px;
     left:45px;
     top:30px;
}

#bloodyMess {
     position:absolute;
     background-color:#141414;
     width:157px;
     height:188px;
     z-index:1;
     left: 0;
     top: 0;
}

#headerimg a {
     position:absolute;
     background-image:url(images/logoIn.png);
     display:block;
     width:157px;
     height:188px;
     left:0;
     top:0;
     z-index:1001;
}

As you can see from the css, all the elements are positioned absolute. This is to take advantage of using z-index to position the anchor element above the canvas element. The anchor element uses the image-mask we created earlier as the background-image.

Step 3: The JavaScript

This example uses a stripped down version of Christophe Résigné amazing Starfield experiment. I also use Mootools version 1.2.4.

var blood_x_save,blood_y_save;
var drip_speed= 0.01;
var blood_drops = 500;
var star=new Array(blood_drops);
var context;
var bloodtimeout = 0;
var bloodfps= 25;

var Page = {
     initialize: function(){
     initBlood();
     doLogo();
     }
}

window.addEvent("domready", Page.initialize);

function doLogo(){
     $("headerimg").getElement("a").addEvents({
          'mouseover': function(){
               $("bloodyMess").fade(1);
               animBlood();
          },
          'mouseout': function(){
               $("bloodyMess").fade(0);
               clearTimeout(bloodtimeout);
          }
     });
} 

function initBlood()
{
     $("bloodyMess").setStyle("opacity", "0");
     var a=0;
     for(var i=0;i<blood_drops;i++)
     {
          star[i]=new Array(5);
          star[i][0]=Math.random()*157*2-78*2;
          star[i][1]=Math.random()*188*2-89*2;
          star[i][2]=Math.round(Math.random()*172.5);
          star[i][3]=0;
          star[i][4]=0;
     }
     var bloodyMess=$('bloodyMess');
     context=bloodyMess.getContext('2d');
     bloodyMess.width = 157;
     bloodyMess.height = 188;
     context.fillStyle='rgb(149,4,4)';
     context.strokeStyle='rgb(0,0,0)';
}

function animBlood()
{
     context.fillRect(0,0,157,188);
     for(var i=0;i<blood_drops;i++)
     {
          test=true;
          blood_x_save=star[i][3];
          blood_y_save=star[i][4];
          star[i][0]+=11>>4;
          if(star[i][0]>78<<1){
               star[i][0]-=157<<1;
               test=false;
          }
          if(star[i][0]<-78<<1){
               star[i][0]+=157<<1;
               test=false;
          }
          star[i][1]+=31>>4;
          if(star[i][1]>89<<1) {
               star[i][1]-=188<<1;
               test=false;
          }
          if(star[i][1]<-89<<1) {
               star[i][1]+=188<<1;
               test=false;
          }
          star[i][2]-=drip_speed;
          if(star[i][2]>172.5) {
               star[i][2]-=172.5;
               test=false;
          }
          if(star[i][2]<0) {
               star[i][2]+=172.5;
               test=false;
          }
          star[i][3]=78+(star[i][0]/star[i][2])*300;
          star[i][4]=89+(star[i][1]/star[i][2])*300;
if(blood_x_save>0&&blood_x_save<157&&blood_y_save>0&&blood_y_save<188&&test)
          {
               context.fillStyle='rgba(149, 4, 4, 0.5)';
               context.lineWidth=(1-0.005*star[i][2])*5;
               context.beginPath();
               context.moveTo(blood_x_save,blood_y_save);
               context.lineTo(star[i][3],star[i][4]);
               context.stroke();
               context.closePath();
          }
     }
     bloodtimeout=setTimeout('animBlood()',bloodfps);
}

This is the most complicated part. First I fire two functions: initBlood() and doLogo() using Mootools domready event.

initBlood() initializes the CANVAS element and the array to handle the blood. It also sets the CANVAS elements opacity to 0 because I didn’t want to view the blood until you hover over it.

doLogo() handles the hover of the anchor element. On mouseover I fade-in the CANVAS element and begin the blood effects. On mouseout I fade out the CANVAS element and stop the effects using clearTimout(); This saves on the clients CPU when the effects not in use.

initBlood() This is used to handle the blood effects. It should run at 25fps given you’re using a browser with a good JavaScript engine and that your CPU isn’t from before the millennium. The function will loop until the clients mouse leaves the anchor element.

Step 4: View the beast

To view my example simply roll your mouse over my logo. Its positioned in the top-left-hand corner.