1
votes

I have the following canvas code:

    var canvas, ctx, flag = false,
      prevX = 0,
      currX = 0,
      prevY = 0,
      currY = 0,
      dot_flag = false;

    var x = "black",
      y = 2;

    function init() {
      canvas = document.getElementById('can');
      ctx = canvas.getContext("2d");
      w = canvas.width;
      h = canvas.height;

      canvas.addEventListener("mousemove", function(e) {
        findxy('move', e)
      }, false);
      canvas.addEventListener("mousedown", function(e) {
        findxy('down', e)
      }, false);
      canvas.addEventListener("mouseup", function(e) {
        findxy('up', e)
      }, false);
      canvas.addEventListener("mouseout", function(e) {
        findxy('out', e)
      }, false);
    }

    function color(obj) {
      switch (obj.id) {

        case "blue":
          x = "blue";
          break;
        case "red":
          x = "red";
          break;

        case "black":
          x = "black";
          break;
        case "white":
          x = "white";
          break;
      }
      if (x == "white") y = 14;
      else y = 2;

    }

    function draw() {
      ctx.beginPath();
      ctx.moveTo(prevX, prevY);
      ctx.lineTo(currX, currY);
      ctx.strokeStyle = x;
      ctx.lineWidth = y;
      ctx.stroke();
      ctx.closePath();
    }

    function erase() {
      var m = confirm("Want to clear");
      if (m) {
        ctx.clearRect(0, 0, w, h);
        document.getElementById("canvasimg").style.display = "none";
      }
    }

    function save() {
      document.getElementById("canvasimg").style.border = "2px solid";
      var dataURL = canvas.toDataURL();
      document.getElementById("canvasimg").src = dataURL;
      document.getElementById("canvasimg").style.display = "inline";
    }

    function findxy(res, e) {
      if (res == 'down') {
        prevX = currX;
        prevY = currY;
        currX = e.clientX - canvas.offsetLeft;
        currY = e.clientY - canvas.offsetTop;

        flag = true;
        dot_flag = true;
        if (dot_flag) {
          ctx.beginPath();
          ctx.fillStyle = x;
          ctx.fillRect(currX, currY, 2, 2);
          ctx.closePath();
          dot_flag = false;
        }
      }
      if (res == 'up' || res == "out") {
        flag = false;
      }
      if (res == 'move') {
        if (flag) {
          prevX = currX;
          prevY = currY;
          currX = e.clientX - canvas.offsetLeft;
          currY = e.clientY - canvas.offsetTop;
          draw();
        }
      }
    }
<div class="row 50% third">
  <div class="12u">
    <canvas class="image fit" id="can" style=" background-color:rgb(250,250,250); "></canvas>
    <div style="width:5%;height:30px;background:blue;" id="blue" class="colors" onclick="color(this)"></div>
    <div style="width:5%;height:30px;background:red;" id="red" class="colors" onclick="color(this)"></div>
    <div style="width:5%;height:30px;background:black;" id="black" class="colors" onclick="color(this)"></div>
    <div style="width:5%;height:30px;background:white;border:2px solid;" id="white" class="colors" onclick="color(this)"></div>
    <img id="canvasimg" style="position:absolute;top:10%;left:52%;" style="display:none;">
    <input type="button" value="save" id="btn" size="30" onclick="save()" style="position:absolute;top:55%;left:10%;">
    <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
  </div>
</div>

I have set my body onload to init();

However, the canvas does not work.

EDIT: The canvas works when i provide it a specific width and height in the html, but i find that my drawing and mouse is always off by a little. Is there also a way to use percentage widths and heights? The w = canvas.width; h = canvas.height; Seems to be the one causing the problem.

1
When I create a fiddle for it everything seems to work, please be more specific on what is not working...LJᛃ
hi there, in my html i didnt specify the width and height, and i think that is whats causing the issue.userxxxso
when i give it a percentage width/height, the canvas stops working, when i use pixels, it works but the drawing is off by a little, currently you can see that the width/height of the canvas is determined by the class image fit, which uses percentagesuserxxxso
When using a 2D or 3D canvas context your canvas needs to have pixel based width and height attributes. Also I cant see any offset here in chrome, you may want to provide a full testcase.LJᛃ
hmm, if i use a pixel based width and height, it does not scroll/resize welluserxxxso

1 Answers

0
votes

The code seems ok to me. I added a call to the init function.

As LJ_1102 stated: The offset issue is a CSS issue. The width and height attributes set the width and height of the bitmap itself. The CSS width and height attributes set the element width and height. So, think about the canvas tag as if it were an img tag. If you set the CSS width of an img, it would stretch. Canvas will do the same thing.

var canvas, ctx, flag = false,
  prevX = 0,
  currX = 0,
  prevY = 0,
  currY = 0,
  dot_flag = false;

var x = "black",
  y = 2;

function init() {
  canvas = document.getElementById('can');
  ctx = canvas.getContext("2d");
  w = canvas.width;
  h = canvas.height;

  canvas.addEventListener("mousemove", function(e) {
    findxy('move', e)
  }, false);
  canvas.addEventListener("mousedown", function(e) {
    findxy('down', e)
  }, false);
  canvas.addEventListener("mouseup", function(e) {
    findxy('up', e)
  }, false);
  canvas.addEventListener("mouseout", function(e) {
    findxy('out', e)
  }, false);
}

function color(obj) {
  switch (obj.id) {

    case "blue":
      x = "blue";
      break;
    case "red":
      x = "red";
      break;

    case "black":
      x = "black";
      break;
    case "white":
      x = "white";
      break;
  }
  if (x == "white") y = 14;
  else y = 2;

}

function draw() {
  ctx.beginPath();
  ctx.moveTo(prevX, prevY);
  ctx.lineTo(currX, currY);
  ctx.strokeStyle = x;
  ctx.lineWidth = y;
  ctx.stroke();
  ctx.closePath();
}

function erase() {
  var m = confirm("Want to clear");
  if (m) {
    ctx.clearRect(0, 0, w, h);
    document.getElementById("canvasimg").style.display = "none";
  }
}

function save() {
  document.getElementById("canvasimg").style.border = "2px solid";
  var dataURL = canvas.toDataURL();
  document.getElementById("canvasimg").src = dataURL;
  document.getElementById("canvasimg").style.display = "inline";
}

function findxy(res, e) {
  if (res == 'down') {
    prevX = currX;
    prevY = currY;
    currX = e.clientX - canvas.offsetLeft;
    currY = e.clientY - canvas.offsetTop;

    flag = true;
    dot_flag = true;
    if (dot_flag) {
      ctx.beginPath();
      ctx.fillStyle = x;
      ctx.fillRect(currX, currY, 2, 2);
      ctx.closePath();
      dot_flag = false;
    }
  }
  if (res == 'up' || res == "out") {
    flag = false;
  }
  if (res == 'move') {
    if (flag) {
      prevX = currX;
      prevY = currY;
      currX = e.clientX - canvas.offsetLeft;
      currY = e.clientY - canvas.offsetTop;
      draw();
    }
  }
}
init();
<div class="row 50% third">
  <div class="12u">
    <canvas class="image fit" id="can" width="50%" height="50%" style=" background-color:rgb(250,250,250); "></canvas>
    <div style="width:5%;height:30px;background:blue;" id="blue" class="colors" onclick="color(this)"></div>
    <div style="width:5%;height:30px;background:red;" id="red" class="colors" onclick="color(this)"></div>
    <div style="width:5%;height:30px;background:black;" id="black" class="colors" onclick="color(this)"></div>
    <div style="width:5%;height:30px;background:white;border:2px solid;" id="white" class="colors" onclick="color(this)"></div>
    <img id="canvasimg" style="position:absolute;top:10%;left:52%;" style="display:none;">
    <input type="button" value="save" id="btn" size="30" onclick="save()" style="position:absolute;top:55%;left:10%;">
    <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
  </div>
</div>