Q:

Question about JavaScript graphic animation: saving and restoring a "sprite" background

I am writing a train based game in Facebook Javascript. I have an inverted triangle that represents the train and dashed lines that represent track which connects cities in Europe. The train moves along the track to travel from one city to the next. At this time, I redraw the gameboard with every page refresh. This has the effect of always showing the train in its latest position on the track. However, using page refresh to redraw the gameboard is turning out to be too CPU intensive and my apps performance is suffering as a result. Hence I need to implement Ajax and some kind of sprite animation for the train. 
When the train changes position on the track, I need to erase the train marker at its old position, and redraw it at it's new position. I know how to redraw it, but erasing it at it's old position and restoring the background graphics is where I need help. I have no idea how to do this. As a matter of fact, I have no knowledge of manipulating graphics in javascript at all (except a basic PlotPixel() routine that creates 1px divs) Please bear in mind that Facebook JS is incompatible with exisiting JS libraries and frameworks. 
Can anyone offer me some help with this? I would very much appreciate it. Thanks!
Here's the relevant code:
function drawTrack(x1, y1, x2, y2, c, trains) {
if(c == '#444') new Dialog().showMessage('dialog', 'in drawTrack: x1='+x1+', y1='+y1+', x2='+x2+', y2='+y2);
/**
if(trains[0]) {
var train_dump = dump(trains[0], 2);
new Dialog().showMessage('dialog', 'td='+train_dump);
}
**/
    var xs1 = x1;
    var ys1 = y1;
    var xs2 = x2;
    var ys2 = y2;
    var step = 1;
    var dashlen = 4;
    var middash = parseInt(dashlen/2);
    var count = 1;
    var steep = Math.abs(y2 - y1) > Math.abs(x2 - x1);
    if (steep) {
        var t = y1;
        y1 = x1;
        x1 = t;
        t = y2;
        y2 = x2;
        x2 = t;
    }
    var deltaX = Math.abs(x2 - x1);
    var deltaY = Math.abs(y2 - y1);
    var error = 0;
    var deltaErr = deltaY;
    var xStep;
    var yStep;
    var x = x1;
    var y = y1;
    var drewDash;
    if (x1 < x2) {
        xStep = step;
    }
    else {
        xStep = -step;
    }

    if(y1 < y2) {
        yStep = step;
    }

    else {
        yStep = -step;
    }
    var points = 0;
    var drawFlag = false;
    while(x != x2) {
        x = x + xStep;
        if(xStep > 0) {
          if(x > x2) {
            break;
          }
          // do not draw dashes near the city markers
          if(x >= x2-dashlen) {
            drawFlag = false;
          }
        }
        if(xStep < 0) {
          if(x < x2) {
            break;
          }
          // do not draw dashes near the city markers
          if(x <= x2+dashlen) {
            drawFlag = false;
          }
        }
        error = error + deltaErr;
        if(2 * error >= deltaX) {
            y = y + yStep;
            error = error - deltaX;
        }
        if(points < dashlen) {
          if(drawFlag) {
            if(steep) {
                PlotPixel(y, x, c);
                drewDash = true;
            }
            else {
                PlotPixel(x, y, c);
                drewDash = true;
            }
            if(points == middash) {
              if(trains[0]) {
                for(var key = 0; key < trains.length; key++) {
                  if(trains[key]['track_unit'] == count) {
                    if(steep) {
                      trainMarker(y, x, trains[key]);
                    } else {
                      trainMarker(x, y, trains[key]);
                    }
                  }
                }
              }
            }
          }
          points++;
       } else {
          drawFlag = !drawFlag;
          if(drewDash) count++;
          points = 0;
          drewDash = false;
       }
    }

    if(trains[0]) {
      for(var key = 0; key < trains.length; key++) {
        if(trains[key]['status'] == 'ARRIVED') {
          if(trains[key]['direction'] == '+') {
            trainMarker(xs2, ys2, trains[key]);
          } else {
            trainMarker(xs1, ys1, trains[key]);
          }
        }
      }
    }
    return count;
}

function trainMarker(x, y, trainData) {
  var train = document.createElement('div');
  train.setClassName('train');
  y -= trainMarkerHeight;
  x -= parseInt(trainMarkerWidth/2);
  var trainId = 'train-'+trainData['line'].toLowerCase()+'-'+trainData['player_number'];
  train.setId(trainId);
  train.setStyle('left', x + 'px');
  train.setStyle('top', y + 'px');

  var trainImg = document.createElement('img');
  trainImg.setSrc(publicURL + '/images/train_marker_red.gif');
  train.appendChild(trainImg);

  var trainPlayerNum = document.createElement('div');
  trainPlayerNum.setClassName('train-player-num');
  trainPlayerNum.setId('train-player-'+trainData['player_number']);
  trainPlayerNum.setTextValue(trainData['player_number']);
  trainPlayerNum.setStyle('left', '8px');
  trainPlayerNum.setStyle('top', '1px');
  trainPlayerNum.addEventListener('mouseover', myEventHandler);
  trainPlayerNum.addEventListener('mouseout', myEventHandler);
  trainPlayerNum.appendChild(setTrainTooltip(trainData));
  train.appendChild(trainPlayerNum);

  var parentObj = document.getElementById('map');
  parentObj.appendChild(train);
}

This code draws track (dashed lines) from one city's x,y coords to another city's x,y coords. If a train is present on that line of track, it draws the train as well. If the train is present at one of the cites, it draws the train at the city.
The game itself is at http://apps.facebook.com/rails_dev.

A:

Perhaps instead of manipulating the image itself, you can move the train image over top of the position (map image?) using z-index and an absolutely positioned div? This might be easier to implement and more performant than trying to create or modify the actual image data in javascript.
[Edit: to show or hide an image, the javascript looks like:
(given some HTML like:)
<img src="train.jpg" id="trainImg" />
<img src="background.jpg" id="backgroundImg" />

The javascript looks like:
function getTrain() {
  document.getElementById("trainImg");
}

function showTrain() {
  getTrain().style.display = "";
}

function hideTrain() {
  getTrain().style.display = "none";
}

]

