salad_bar_breath
salad_bar_breath

Reputation: 281

Having issues using MouseEvent in HTML canvas animation

So I hit a snag while building an HTML5 canvas UI element. I want to make the circle in this toggle switch drag to the X-coordinate that the user drags it to (there's ultimately a lot more that this thing is going to have but I want to do it a step at a time!). I can output the x coordinates so I know that's working but for some reason I cannot get it to work in my animation loop to change the variable primX. Here's my code:

HTML:

<canvas id="toggle1" class="toggle" onmousemove="getCoords(event)"></canvas>
  <p id="test"></p>

The CSS is irrelevant, as long as you set any width to .toggle or #toggle1

JavaScript:

var canvas=document.getElementById("toggle1");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height=cw/3;
var PI=Math.PI;
var PI2=(PI * 2);
var cx=ch/2;
var cy=ch/2;
var backStyle="#FFFFFF"
var globalID;
var lw=ctx.lineWidth=8;
var radius=ch/2-lw/2;
var half=cw/2;
var currX;
var globalID;
var mouseIsDown=false;

function getCoords(event) {
    var currX = event.clientX;
    document.getElementById("test").innerHTML = currX;
}

function backGround(){  
    if (primX > half){
      Style="#00FF00";
      } else {
      Style="#FF0000";
        };  
  ctx.fillStyle=backStyle;
  ctx.strokeStyle=Style;
  ctx.beginPath();
  ctx.arc(cx+lw/2,cy,radius,(0.5 * PI),(1.5 * PI));
  ctx.lineTo((cw-(ch/2)),0+lw/2);
  ctx.arc((cw-(ch/2+lw/2)),cy,radius,(1.5 * PI),(.5 * PI));
  ctx.lineTo(cx,ch-lw/2);
  ctx.fill();
  ctx.stroke();
};

function mainCir() {
    if (primX > half){
      Style="#00FF00";
      on=true;
      } else {
      Style="#FF0000";
      on=false;
        };
    ctx.beginPath();
    ctx.arc(primX,cy,radius,0,PI2);
    ctx.fillStyle=Style;
    ctx.fill();
}

primX = cx;

function draw(){
backGround();
mainCir();
}

draw();

function animate() {
    primX=currX;
    globalID=requestAnimationFrame(animate);
    draw();
}


$("#toggle1").mousedown(function() {
    mouseIsDown=true;
});
$(document).mouseup(function() {
  if(mouseIsDown){
  animate();
  mouseIsDown=false;
}
});

I've tried a ton of different things but nothing work. If I put a simple animation in the animate() function then that seems to work when the mouse is clicked and held on the element, such as primX++;

But I have no idea how to "animate" the circle to where it goes to the X coordinate that the user drags it to. I've tried a couple of different things and rearranged stuff but it just ends up either disabling animations completely or, as you can see by THIS FIDDLE the circle just disappears.

If anyone knows how to fix this issue, I'd be grateful. Thank you!

Upvotes: 0

Views: 119

Answers (1)

David
David

Reputation: 7305

It was a little thing. In the function that get the coordinates:

function getCoords(event) {
    var currX = event.clientX;
    document.getElementById("test").innerHTML = currX;
}

you are declaring the currX variable. But it was alredy declared, so what you are doing is to create a new one whose scope get lost in the moment the function finish.

You want this:

function getCoords(event) {
    currX = event.clientX;
    document.getElementById("test").innerHTML = currX;
}

Hope it helps!


UPDATE:

There are two more details that maybe are useful for you:

First: you are getting the coordinates in the application's client area, not in the canvas. So maybe you want to add the canvas' left offset.

Second: canvas.width is the logical canvas width, different from the element.width CSS attribute. So most sure you want to make a units conversion.

Altogether:

function getCoords(event) {
    currX = event.clientX - $(event.target).offset().left ;
    currX = currX * (canvas.width / $(canvas).width());
    if (currX < radius) currX = radius;
    if (currX > canvas.width - radius) currX = canvas.width - radius;
    document.getElementById("test").innerHTML = currX;
}

Here you can read more about getting mouse coordinates and here about the dimensions of a canvas.

Upvotes: 1

Related Questions