I am trying to write a scroll-on-hover function in an HTML canvas by defining a hover
variable, detecting mouse events over the designated hover area and (on doing so) adding or subtracting to this hover variable depending on which area is hovered over. This hover
variable is connected to the position of a series of selection buttons which, for the purposes of this example, contain the numbers 0 to 30. When either end of this series of selection buttons is hovered over they all move up or down as if scrolled, but to make it act like a scroll you must keep the mouse moving as the canvas is only rendered
on each new mousemove
event.
My question is how can I trigger the event on mouseover
such that if (lowerHoverBoxHitTest(x, y))
or (upperHoverBoxHitTest(x, y))
(i.e if the mouse is hovered over either of the hit boxes defined in the script below) the hover variable keeps being added to by the set increment (0.1
) until the mouse leaves that area. I have tried replacing the if/else
statement in the function mouseMove
with a while
loop (as it would seem this is logically akin to what I am asking) as so
while (lowerHoverBoxHitTest(x, y)) {
if (hover < 750) {
hover-=0.1;
}
}
while (upperHoverBoxHitTest(x, y)) {
if (hover > 0) {
hover+=0.1;
}
}
but this just causes the page to crash (presumably it triggers an infinite loop?). There isn't much on Stack Overflow about this besides this but this solution is not useful if you have a lot of other things in your canvas that you don't want to scroll (unless you were to define their position absolutely which I don't want to) which I do in my full project. Any help will be appreciated.
var c=document.getElementById('game'),
canvasX=c.offsetLeft,
canvasY=c.offsetTop,
ctx=c.getContext('2d');
var hover=0;
function upperHoverBoxHitTest(x, y) {
return (x >= 0) && (x <= 350) && (y >= 0) && (y <= 50);
}
function lowerHoverBoxHitTest(x, y) {
return (x >= 0) && (x <= 350) && (y >= 450) && (y <= 500);
}
var selectionForMenu = function(id, text, y) {
this.id = id;
this.text = text;
this.y = y;
}
selectionForMenu.prototype.makeSelection = function() {
ctx.beginPath();
ctx.fillStyle='#A84FA5';
ctx.fillRect(0, this.y+hover, 350, 30)
ctx.stroke();
ctx.font='10px Noto Sans';
ctx.fillStyle='white';
ctx.textAlign='left';
ctx.fillText(this.text, 10, this.y+hover+19);
}
var Paint = function(element) {
this.element = element;
this.shapes = [];
}
Paint.prototype.addShape = function(shape) {
this.shapes.push(shape);
}
Paint.prototype.render = function() {
ctx.clearRect(0, 0, this.element.width, this.element.height);
for (var i=0; i<this.shapes.length; i++) {
this.shapes[i].makeSelection();
}
}
var paint = new Paint(c);
for (i=0; i<30; i++) {
paint.addShape(new selectionForMenu(i+1, i, i*30));
}
paint.render();
function mouseMove(event) {
var x = event.x - canvasX;
var y = event.y - canvasY;
paint.render();
if (lowerHoverBoxHitTest(x, y)) {
hover+=1;
} else if (upperHoverBoxHitTest(x, y)) {
hover-=1;
}
}
c.addEventListener('mousemove', mouseMove);
canvas {
z-index: -1;
margin: 1em auto;
border: 1px solid black;
display: block;
background: #9F3A9B;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>uTalk Demo</title>
<link rel='stylesheet' type='text/css' href='wordpractice.css' media='screen'>
</head>
<body>
<canvas id="game" width = "350" height = "500"></canvas>
</body>
</html>