D5145c421cd25af6fa577c15219add90

I've written a countdown to my wedding, and the numbers have to be in a custom font, and positioned on top of an image in the top-right corner of the page. The numbers have to be at an angle. That's taken care of in the images 0.png to 9.png, but there are up to three digits in the number, so the images have to be placed accordingly. I've done it by creating a line called cornerLine, defined by co-ordinate arrays, and the top-right corners of the images are all positioned along this line, but if it works out better map the numbers out, you can do that.

rightOffset = 20;
topOffset = 20;
               
// refer to co-ordinates by name
// eg magicLine[point1][right]
point1 = 0;
point2 = 1;
dRight = 0;
dTop = 1; //funny name because top is a reserved word
        
cornerLine = new Array();
cornerLine[0] = new Array( 0 , 32 );
cornerLine[1] = new Array( 52 , 23 );

var now = new Date();
var wedding = new Date(2010,05,12,13,0);
var oneDay=1000*60*60*24;
days = '' + Math.round((wedding-now)/oneDay);
//days = '777';   // test figure
days = days.split('');
days.reverse();

digitPositions = new Array(days.length);

for (i=0;i<days.length;i++)
  digitPositions[i] = new Array();
        
if (days.length == 3)
{
  // to the furthest right position
  digitPositions[0][dRight] = Math.round(cornerLine[0][dRight]) + rightOffset;
  digitPositions[0][dTop]   = Math.round(cornerLine[0][dTop]) + topOffset;
  // to the centre position
  digitPositions[1][dRight] = Math.round((cornerLine[0][dRight] + cornerLine[1][dRight])/2 + rightOffset);
  digitPositions[1][dTop]   = Math.round((cornerLine[0][dTop] + cornerLine[1][dTop])/2 + topOffset);
  // to the furthest left postion
  digitPositions[2][dRight] = Math.round(cornerLine[1][dRight]) + rightOffset;
  digitPositions[2][dTop]   = Math.round(cornerLine[1][dTop]) + topOffset;
}
else if (days.length == 2)
{
  // a quarter of the way from the right
  digitPositions[0][dRight] = Math.round((cornerLine[0][dRight]*3 + cornerLine[1][dRight]) / 4) + rightOffset;
  digitPositions[0][dTop]   = Math.round((cornerLine[0][dTop]*3 + cornerLine[1][dTop]) / 4) + topOffset;
  // a quarter of the way from the left
  digitPositions[1][dRight] = Math.round((cornerLine[0][dRight] + cornerLine[1][dRight]*3) / 4) + rightOffset;
  digitPositions[1][dTop]   = Math.round((cornerLine[0][dTop] + cornerLine[1][dTop]*3) / 4) + topOffset;
}
else // days.length == 1
{
  // the center position
  digitPositions[0][dRight] = Math.round((cornerLine[0][dRight] + cornerLine[1][dRight])/2) + rightOffset;
  digitPositions[0][dTop]   = Math.round((cornerLine[0][1] + cornerLine[1][1])/2) + topOffset;
}
        
for (i=0; i<days.length; i++)
  document.write('<img src="images/countdown/' + days[i] + '.png" id="digit_' + i
    + '" style="position:absolute;right:' + digitPositions[i][dRight] + 'px;top:'
    + digitPositions[i][dTop] +  'px;z-index:' + (i + 6) + '" />');

Refactorings

No refactoring yet !

9b4d76224c1fefc34b682e799df98624

Jason Bury

March 2, 2010, March 02, 2010 23:49, permalink

No rating. Login to rate!

You have a line that passes through two points on the canvas. What I wanted to do was parameterize that line in such a way that the first specified point is at t=0 and the second specified point is at t=1. The parameterizeLine function returns a new function that you can use to get points on the line for different values of t.

With all that math packaged away in the function, the code is cleaner and I bet you can take it even further. Obviously you only need at most 3 digits here, but it shouldn't be hard to generalize this now for any number of digits.

Also, I respected your use of topOffset and leftOffset. However, you might consider wrapping your image in a div tag, and then use relative positioning to position your digits inside that div. Then, if you decide to move the image later on, or if the page renders differently for different browsers, the code will still work without the need of topOffset and leftOffset.

And Congrats on setting a date for your wedding ;)

function parameterizeLine(p1, p2, offset)
{
    v  = [p2[0] - p1[0],
        p2[1] - p1[1]];

    return function (t)
    {
        return [Math.round(v[0]*t + p1[0] + offset[0]),
                Math.round(v[1]*t + p1[1] + offset[1])];
    }
}


var now = new Date();
var wedding = new Date(2010,05,12,13,0);
var oneDay=1000*60*60*24;
//days = '' + Math.round((wedding-now)/oneDay);
days = '123';   // test figure
days = days.split('');
days.reverse();

line = parameterizeLine([0, 32], [52, 23], [20, 20]);

digitPositions = []; 
        
if (days.length == 3)
{
  // to the furthest right position
  digitPositions[0] = line(0);
  // to the centre position
  digitPositions[1] = line(0.5);
  // to the furthest left postion
  digitPositions[2] = line(1);
}
else if (days.length == 2)
{
  // a quarter of the way from the right
  digitPositions[0] = line(0.25);
  // a quarter of the way from the left
  digitPositions[1] = line(0.75);
}
else // days.length == 1
{
  // the center position
  digitPositions[0] = line(0.5);
}

for (i=0; i<days.length; i++)
{
    document.write('<img src="images/countdown/' + days[i] + '.png" id="digit_' +
    i + '" style="position:absolute;right:' + digitPositions[i][0] +
    'px;top:' + digitPositions[i][1] +  'px;z-index:' + (i + 6) + '" />');
}

Your refactoring





Format Copy from initial code

or Cancel