spacer

Webref WebRef   Sitemap · Experts · Tools · Services · Newsletters · About i.com

home / programming / javascript / gr / column7 / 1 To page 1current pageTo page 3
[previous][next]

Senior Consultant/Information Security - permanent position (TX)
Next Step Systems
US-TX-Irving

Justtechjobs.com Post A Job | Post A Resume
Developer News
Mandrake Linux Founder Back, Virtually
Amazon: We're a Technology Company
Sun Expands MySQL With Closed Source

How to Create a JavaScript Web Page Screen Saver

The next task is to solve the problem of rendering stars on the browser page. Some readers will recall an article I wrote earlier this year titled “JavaScript OO Vector Graphics Package.” In that article, I presented a simple graphics drawing framework that allows shapes to be drawn on the web page using small pixel sized <div> elements. Here, I make use of that graphics package. To keep the code modular, I am assuming the graphics framework code will be held in a separate file called JSGraphics.js. This file can be referenced using the src attribute of the <script> tag

<script src="JSGraphics.js"></script>

For the purposes of this article, I have made some changes to the original JSGraphics code:

Graphics.prototype.createPlotElement = function(x,y,w,h)
{
  // detect canvas
if ( !this.oCanvas )
{
    switch ( typeof(this.canvas) )
{
      case "string":
      this.oCanvas = document.getElementById(this.canvas);
      break;
case "object":
      this.oCanvas = this.canvas;
      break;
default:
      this.oCanvas = document.body;
      break;
    }
  }
// rest of createPlotElement function
...

}

Point.prototype.move = function(x,y)
{

  this.oDiv.style.left = x + "px";
this.oDiv.style.top = y + "px";
}
Point.prototype.setSize = function(nSize)
{
  this.oDiv.style.width = nSize + "px";
this.oDiv.style.height = nSize + "px";
}

The change to the createPlotElement allows the user to pass a DIV object directly to the Graphics constructor, rather than give it the ID and have it search the document. To make the starfield simulation as efficient as possible, I needed to provide a means to moving a point element without having to unplot and redraw it, so a move() method has been added to the Point prototype. To make the stars appear bigger as they come closer, I also added a setSize() method that controls the width and height of the underlying <div> element.

The start() method of the StarFieldSaver object first checks whether the screen saver is active; it would be quite confusing if it were to be started more than once. After this test is passed, it checks whether it has been initialized by checking an object called this.oCanvas. The canvas is a <div> element and is used by the JSGraphics code to render the graphics objects. If the canvas has not been allocated, the init() method is called. After this, the visibility style of the canvas is set to visible because as we will see later, it is set to hidden when the screen saver is stopped. Last of all, the tick() method is called to start the animation.

StarFieldSaver.prototype.start = function()
{
  if ( this.bActive ) return;
this.bActive = true;

if ( !this.oCanvas ) this.init();
this.oCanvas.style.visibility = "visible";
this.tick();
}

The init() method does nothing special: The canvas <div> element is created and configured, a Graphics object is created and its pen color set to white and an array is created to store the points used to render the stars.

StarFieldSaver.prototype.init = function()
{
 

this.oCanvas = document.createElement("div");
document.body.appendChild(this.oCanvas);
this.oCanvas.style.zIndex = this.zIndex;
this.oCanvas.style.position = "absolute";
this.oCanvas.style.backgroundColor = "black";

this.g = new Graphics(this.oCanvas);
this.g.penColor = "white";

this.aPoints = new Array();

}

Now for the animation; it all happens in one method called tick(). As the name suggests, this method is called repeatedly at small intervals to drive the starfield animation.

StarFieldSaver.prototype.tick = function()
{
  // resize canvas to fit the browser window.
this.oCanvas.style.left = document.body.scrollLeft + "px";
this.oCanvas.style.top = document.body.scrollTop + "px";
this.oCanvas.style.width = document.body.clientWidth + "px";
this.oCanvas.style.height = document.body.clientHeight + "px";

this.width = document.body.clientWidth;
this.height = document.body.clientHeight;

The first task is resize, so the canvas is positioned to the current scroll position and width. This must be done each time tick() is called, so the user can resize the browser while the screen saver is still running.

  var cx = this.width / 2;
var cy = this.height / 2;
for ( var i in this.aPoints )
{
    var p = this.aPoints[i];
var dx = p.x - cx;
var dy = p.y - cy;

// move point outwards
p.x += dx / 50;
p.y += dy / 50;

The next step is to move each star point away from the center by a small distance to give the impression of motion. In the code above, each star is moved by a distance proportional to its distance from the center, so the stars will speed up as they appear closer to the viewer. The X and Y properties of the Point objects are added after the Point object has been created and are used to track the point location on the canvas.

    // if it has gone off the screen...
if ( (p.x < 0) || (p.x > this.width - Math.ceil(p.n/50)) ||
      (p.y < 0) || (p.y > this.height - Math.ceil(p.n/50)) )
    {
     

// replace star somwhere
p.x = Math.random() * this.width;
p.y = Math.random() * this.height;

// p.n is the point’s iteration number – used to determine
// how big the point should be
p.n = 0;

    }

If a star falls off the canvas, it needs to be repositioned on the canvas again. Any random point on the canvas will do.

   

p.move(Math.floor(p.x),Math.floor(p.y));

// resize as they get closer
p.setSize(Math.ceil(p.n++ / 50))

  }

After its position has been altered, the Point object is moved. To make the stars grow as they come towards the viewer, a property (n) is added to each point to keep track of how many ticks have passed since it was first seen. Every fifty ticks, the star will increase in size by one pixel.

  // if we have less stars than we need, make some more.
while ( this.aPoints.length < this.nStars )
{
    var x = Math.random() * this.width;
var y = Math.random() * this.height;
var p = this.g.drawPoint(Math.floor(x), Math.floor(y));
p.setSize(1);
p.x = x;
p.y = y;
p.n = 0;
this.aPoints.push(p);
  }

The first time tick() is called, the array of points will be empty. If this is the case, the points are generated and placed randomly on the canvas.

  var pThis = this;
var f = function(){pThis.tick();}
this.timerID = window.setTimeout(f,this.speed);
}  

Finally, the tick() method is scheduled again using the speed setting to control the rate of ticks.

StarFieldSaver.prototype.stop = function()
{
 

if ( !this.bActive ) return;

window.clearTimeout(this.timerID);
this.oCanvas.style.visibility = "hidden";

for ( var i in this.aPoints )
{

    this.aPoints[i].undraw();
 

}
this.aPoints = new Array();

this.bActive = false;

}

To stop the simulation, the stop() method sets the visibility of the canvas to hidden and removes each star by calling the undraw() method. Even though the parent note is hidden, the stars can still be visible.

home / programming / javascript / gr / column7 / 1 To page 1current pageTo page 3
[previous][next]

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info

Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

Whitepapers and eBooks

Symantec Whitepaper: Converging System and Data Protection for Complete Disaster Recovery
Intel Whitepaper: Comparing Two- and Four-Socket Platforms for Server Virtualization
IBM Solutions Brief: Go Green With IBM System xTM And Intel
HP eBook: Simplifying SQL Server Management
IBM Contest: Are You the Next Superstar? Join the "Search for the XML Superstar" Contest to Find Out
Microsoft PDF: Top 10 Reasons to Move to Server Virtualization with Hyper-V
Microsoft PDF: Six Reasons Why Microsoft's Hyper-V Will Overtake Vmware
Microsoft Step-by-Step Guide: Hyper-V and Failover Clustering
Intel PDF: Quad-Core Impacts More Than the Data Center
Intel PDF: Virtualization Delivers Data Center Efficiency
Go Parallel Article: PDC 2008 in Review
Microsoft PDF: Top 11 Reasons to Upgrade to Windows Server 2008
Avaya Article: Communication-Enabled Mashups: Empowering Both Business Owners and IT
Intel Whitepaper: Building a Real-World Model to Assess Virtualization Platforms
  PDF: Intel Centrino Duo Processor Technology with Intel Core2 Duo Processor
Microsoft Article: Build and Run Virtual Machines with Hyper-V Server 2008
Go Parallel Article: Q&A with a TBB Junkie
IBM Whitepaper: Innovative Collaboration to Advance Your Business
Internet.com eBook: Real Life Rails
IBM eBook: The Pros and Cons of Outsourcing
Internet.com eBook: Best Practices for Developing a Web Site
IBM CXO Whitepaper: The 2008 Global CEO Study "The Enterprise of the Future"
Avaya Article: Call Control XML in Action - A CCXML Auto Attendant
IBM CXO Whitepaper: Unlocking the DNA of the Adaptable Workforce--The Global Human Capital Study 2008
Adobe Acrobat Connect Pro: Web Conferencing and eLearning Whitepapers
Symantec Whitepaper: Comprehensive Backup and Recovery of VMware Virtual Infrastructure
MORE WHITEPAPERS, EBOOKS, AND ARTICLES
webref The latest from WebReference.com Browse >
Popular JavaScript Framework Libraries: An Overview - Part 3 · Accessing Your MySQL Database from the Web with PHP · Working with the DOM Stylesheets Collection
Sitemap · Experts · Tools · Services · Email a Colleague · Contact FREE Newsletters 
 The latest from internet.com
Fixing MySQL Replication · Firewall Guide: First Steps to Securing the Enterprise · VoxOx Tames the Tumultuous Communications Tangle

Created: March 27, 2003
Revised: June 8, 2004

URL: http://webreference.com/programming/javascript/gr/column7/1