1

I am trying to draw and move an image using JS.

This code works up until the moveImage function which simply does nothing. Can anyone help me figure this out?

I believe that I can get the image to move if I place it in the html, but I would prefer to have the script code place it instead if possible.

function init() {
  var x = 1, y = 1;

  var context = document.getElementById("Vehicle").getContext("2d");
  var img = new Image();
  img.onload = function () { context.drawImage(img, x, y, 24, 20); }
  img.src = "images/Image.png";

  //move
  function moveImage(imgX, imgY) { 
    img.style.left = imgX + "px";
    img.style.top = imgY + 'px';
  }

  setInterval(function () {
    var FPS = 60;
    x++;
    y++;
    if (x > 1000) { x = 1; }
    if (y > 1000) { y = 1; }
    moveImage(x, y);
  }, 1000/FPS);
};

My guess is that img.style.left/right is either not correct or that I am not pointing to img properly.

If there is no way to do this, is there a way for me to remove (not just hide) the image so I can redraw it in the new location?

Curtis
  • 101,612
  • 66
  • 270
  • 352
  • Can you provide a fiddle? – artm Jun 19 '15 at 11:24
  • Did you call `init()`? – slebetman Jun 19 '15 at 11:25
  • Try setting `img.style.position = 'absolute'` in the init code, AFAIK `left` and `right` only apply when `position` is either `absolute` or `fixed`. – reg4in Jun 19 '15 at 11:25
  • Why would the image move? It doesn't exist on screen, you have drawn a *copy* of it, but that won't update just cause you move an unrelated element. You will need to redraw with each change to image – musefan Jun 19 '15 at 12:19

1 Answers1

2

You have a scope issue. You are defining FPS inside the interval. This needs to be done before so that it can be used on the interval step parameter.

var FPS = 60;
var timer = (1000/FPS);

setInterval(function () {
    x++;
    y++;
    if (x > 1000) { x = 1; }
    if (y > 1000) { y = 1; }
    moveImage(x, y);
  }, timer);

Furthermore you cannot simply reposition an image on a canvas. It needs to be redrawn onto the canvas.

Once you call context.drawImage() the image can no longer be manipulated. You have, as it suggests, drew this onto the canvas. It's not the same as a HTML element within the DOM. It is now simply coloured pixels on a canvas.

See Demo: http://jsfiddle.net/8Ljvnt8j/1/

However you'll notice that the image is being repeated. This is because you are drawing on top of canvas. The canvas is 2d so you are simply painting on top of what is already there.

Therefore you need to clear down the canvas.

img.onload = function () { 
   context.clearRect(0, 0, canvas.width, canvas.height);
   context.drawImage(img, imgX, imgY, 24, 20);
}

See Demo: http://jsfiddle.net/8Ljvnt8j/2/


All in all:

function init() {

    var x = 1;
    var y = 1;

    var canvas = document.getElementById("Vehicle");

    drawImage();

  //move
  function drawImage() {       
      var context = document.getElementById("Vehicle").getContext("2d");
      var img = new Image();
      img.onload = function () { 
      context.clearRect(0, 0, canvas.width, canvas.height);
      context.drawImage(img, x, y, 24, 20);
  }
  img.src = "https://placeholdit.imgix.net/~text?txtsize=5&txt=20%C3%9720&w=20&h=20";

  }

  var FPS = 60;
   var timer = (1000/FPS);

setInterval(function () {
    x++;
    y++;
    if (x > 1000) { x = 1; }
    if (y > 1000) { y = 1; }
    drawImage();
  }, timer);
};

init();
Curtis
  • 101,612
  • 66
  • 270
  • 352
  • Would this not create resource issues after a while? – user3630993 Jun 19 '15 at 11:34
  • @user3630993 How do you mean? What resources issues would arise? – Curtis Jun 19 '15 at 11:39
  • @user3630993 Canvas isn't the same as HTML DOM elements. You can't reposition it, for it doesn't exist. It's been drawn onto the canvas. Much like you can't draw a picture on a piece of paper and then move it. – Curtis Jun 19 '15 at 11:44
  • @user3630993: Shut your face, this is a great answer. What your open face was even on about makes no sense anyway, what resources? – musefan Jun 19 '15 at 12:23
  • This works! Thanks so much Curt! @musefan: I'm not sure what you're so angry about, but I was referring to continuously redrawing anything on the screen infinitely. I'm new to JS and am not sure how any of this works. – user3630993 Jun 19 '15 at 13:30
  • @Curt: Also, thanks for referencing this JSFiddle website. It will be very helpful to me in the future. – user3630993 Jun 19 '15 at 13:32
  • 1
    @user3630993: I am not angry about anything (well maybe about the decaying state of our existence), I was JK JK. Enjoy your new job ;) – musefan Jun 19 '15 at 13:37
  • @user3630993 Redrawing to the screen happens all the time. Thats what Frames Per Second is, as you've mentioned in your question. Now recreating HTML elements all the time is costly as this involves DOM manipulation, but thats different. – Curtis Jun 19 '15 at 13:46