Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move rectangle on canvas

I use canvas in my application using JavaScript. On that canvas I draw one rectangle. I want to move rectangle with the help of mouse (e.g moving slider) how to move that rectangle using JavaScript or jQuery.

like image 305
pravin Avatar asked Apr 02 '12 11:04

pravin


2 Answers

A Canvas is literally just a surface that you paint on and none of the things you paint are objects.

If you want to pretend they are objects (like moving around a rectangle or a line) then you need to keep track of everything and do all the hit-testing and re-painting yourself .

I wrote a gentle introduction article on getting started by making rectangles that you can select and drag around. Give that a read.

like image 97
Simon Sarris Avatar answered Sep 22 '22 21:09

Simon Sarris


On a second reading, I think I misunderstood your question, so here's an updated version:

http://jsfiddle.net/HSMfR/4/

$(function () {
  var
    $canvas = $('#canvas'),
    ctx = $canvas[0].getContext('2d'),
    offset = $canvas.offset(),
    draw,
    handle;

  handle = {
    color: '#666',
    dim: { w: 20, h: canvas.height },
    pos: { x: 0, y: 0 }
  };

  $canvas.on({
    'mousedown.slider': function (evt) {
      var grabOffset = {
        x: evt.pageX - offset.left - handle.pos.x,
        y: evt.pageY - offset.top - handle.pos.y
      };

      // simple hit test
      if (   grabOffset.x >= 0
          && grabOffset.x <= handle.dim.w
          && grabOffset.y >= 0
          && grabOffset.x <= handle.dim.h
      ) {
        $(document).on({
          'mousemove.slider': function (evt) {
            handle.pos.x = evt.pageX - offset.left - grabOffset.x;

            // prevent dragging out of canvas
            if (handle.pos.x < 0) {
              handle.pos.x = 0;
            }

            if (handle.pos.x + handle.dim.w > canvas.width) {
              handle.pos.x = canvas.width - handle.dim.w;
            }

            //handle.pos.y = evt.pageY - offset.top - grabOffset.y;
          },
          'mouseup.slider': function () {
            $(document).off('.slider');
          }
        });
      }
    }
  });

  draw = function() {
    var val = (100 * (handle.pos.x / (canvas.width - handle.dim.w))).toFixed(2) + '%';

    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.fillStyle = handle.color;
    ctx.fillRect(handle.pos.x, handle.pos.y, handle.dim.w, handle.dim.h);

    ctx.textBaseline = 'hanging';
    ctx.font = '12px Verdana';
    ctx.fillStyle = '#333';
    ctx.fillText(val, 4, 4);
    ctx.fillStyle = '#fff';
    ctx.fillText(val, 3, 3);
  };

  setInterval(draw, 16);
});

prev version:

Very simple solution to extend upon:

http://jsfiddle.net/HSMfR/

$(function () {
  var
    ctx = $('#canvas')[0].getContext('2d'),
    $pos = $('#pos'),
    draw;

  draw = function() {
    var x = ($pos.val() / 100) * (ctx.canvas.width - 20);

    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    ctx.fillStyle = 'black';
    ctx.fillRect(x, 0, 20, 20);
  };

  setInterval(draw, 40);
});
like image 24
Yoshi Avatar answered Sep 20 '22 21:09

Yoshi