Reputation: 327
I have a function which looks at a cursor (x, y) to see if it falls within one of several rectangles (a<x<b, c<y<d
). However, I need to set a boolean based on whether the cursor ever fell into a particular rectangle and only reset it when the cursor falls into some other rectangles. In other words
A is true if cursor fall within rectangle X
A is false if cursor falls within rectangle 1, 2, 3 or 4
A retains its former value if it's anywhere but Y or Z
The trouble is no matter what I do the boolean returns false if I leave the first rectangle, whether I visit the other 2 rectangles or not. I tried making the boolean global but that was no help.
Code;
var r
var s
var l
var inCenter = false
function makeRects(a,b)
{
r = a-b
s = (a/2) - (b/2)
l = (a/2) + (b/2)
lSide = new Array(4)
lSide[0] = 0
lSide[1] = 0
lSide[2] = a
lSide[3] = b
tSide = new Array(4)
tSide[0] = 0
tSide[1] = 0
tSide[2] = b
tSide[3] = a
rSide = new Array(4)
rSide[0] = r
rSide[1] = 0
rSide[2] = b
rSide[3] = b
bSide = new Array(4)
bSide[0] = 0
bSide[1] = r
bSide[2] = b
bSide[3] = b
aSquare = new Array(4)
aSquare[0] = 0
aSquare[1] = 0
aSquare[2] = s
aSquare[3] = s
bSquare = new Array(4)
bSquare[0] = l
bSquare[1] = 0
bSquare[2] = b
bSquare[3] = s
cSquare = new Array(4)
cSquare[0] = 0
cSquare[1] = l
cSquare[2] = s
cSquare[3] = r
dSquare = new Array(4)
dSquare[0] = l
dSquare[1] = l
dSquare[2] = r
dSquare[3] = r
lCenter = new Array(4)
lCenter[0] = 0
lCenter[1] = s
lCenter[2] = b
lCenter[3] = l
tCenter = new Array(4)
tCenter[0] = s
tCenter[1] = 0
tCenter[2] = l
tCenter[3] = b
rCenter = new Array(4)
rCenter[0] = r
rCenter[1] = s
rCenter[2] = a
rCenter[3] = l
bCenter = new Array(4)
bCenter[0] = s
bCenter[1] = r
bCenter[2] = l
bCenter[3] = a
mCenter = new Array(4)
mCenter[0] = s
mCenter[1] = s
mCenter[2] = l
mCenter[3] = l
}
function cursor(a,b)
{
var inaSquare = false
var inbSquare = false
var incSquare = false
var indSquare = false
var inCenter = false
if ((a>aSquare[0] && a<aSquare[2])&&(b>aSquare[1] && b<aSquare[3]))
{
inaSquare = true
post("aSquare");
post();
}
if ((a>bSquare[0] && a<bSquare[2])&&(b>bSquare[1] && b<bSquare[3]))
{
inbSquare = true
post("bSquare");
post();
}
if ((a>cSquare[0] && a<cSquare[2])&&(b>cSquare[1] && b<cSquare[3]))
{
inbSquare = true
post("cSquare");
post();
}
if ((a>dSquare[0] && a<dSquare[2])&&(b>dSquare[1] && b<dSquare[3]))
{
indSquare = true
post("dSquare");
post();
}
if (inaSquare||inbSquare||incSquare||indSquare)
{
inCenter = false
}
if ((a>mCenter[0] && a<mCenter[2])&&(b>mCenter[1] && b<mCenter[3]))
{
inCenter = true
inaSquare = false
inbSquare = false
incSquare = false
indSquare = false
}
if (((inCenter && a>s) && a<l) && b<lCenter[3])
{
outlet (1, 1)
}
else if (((inCenter && a>s) && a<l) && b>rCenter[0])
{
outlet (1, 2)
}
else if (((inCenter && b>s) && b<l) && a<tCenter[3])
{
outlet (1, 3)
}
else if (((inCenter && b>s) && b<l) && b>bCenter[1])
{
outlet (1, 4)
}
else
{
outlet (1, 0)
}
post("inCenter");
post(inCenter);
post();
post("inaSquare");
post(inaSquare);
post();
post("inbSquare");
post(inbSquare);
post();
post("incSquare");
post(incSquare);
post();
post("indSquare");
post(indSquare);
post();
}
Upvotes: 0
Views: 284
Reputation: 1
probably your hit test function needs to have a flag called doTest
set to true initially and then set to false once the center rectangle is hit
then you can set doTest
to true again once a different rectangle is hit
Upvotes: 0
Reputation: 2546
okay i modified the original demo based on what i think you are trying to accomplish but it still isn't very clear so you need to better describe what you are trying to accomplish rather than how to toggle boolean based on rectangle coordinate hit testing. it's possible that what you are trying to accomplish could be done in a simpler way without resorting to coordinate based hit tests.
demo:
http://jsfiddle.net/DaveAlger/cVPpU/5/
html:
<p id="toggle-state">false: center not hit</p>
<p id="mouse-xy"></p>
<canvas id="top" class="box" x="200" y="50" width="100" height="100" c="#933" b="#faa"></canvas>
<canvas id="left" class="box" x="50" y="200" width="100" height="100" c="#993" b="#ffa"></canvas>
<canvas id="right" class="box" x="350" y="200" width="100" height="100" c="#696" b="#dfd"></canvas>
<canvas id="bottom" class="box" x="200" y="350" width="100" height="100" c="#369" b="#adf"></canvas>
<canvas id="center" class="box" x="200" y="200" width="100" height="100" c="#999" b="#ddd"></canvas>
css:
.box{position: absolute;}
#mouse-xy{float:right;padding:30px;color:#999;font-family:sans-serif;}
js:
var isCenterHit = false;
var checkCenterHit = true;
// draw canvas rectangles
$('.box').each(function(i) {
//alert(i);
var id = $(this).attr('id')
var w = $(this).width();
var h = $(this).height();
var c = $(this).attr('c');
var x = $(this).attr('x');
var y = $(this).attr('y');
drawRect( document.getElementById( id ).getContext('2d'), w, h, c, id );
$(this).offset({top: y, left: x});
});
function drawRect( ctx, width, height, color, text ) {
ctx.fillStyle = color;
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = '#fff';
ctx.font = '30px sans-serif';
ctx.textBaseline = 'top';
ctx.fillText(text, 0, 0);
}
// listen for mouse over
$(document).mousemove(function(e){
var x = e.pageX;
var y = e.pageY;
var tX = $(e.target).attr('x');
var tY = $(e.target).attr('y');
var tW = $(e.target).width();
var tH = $(e.target).height();
// update mouse location
$('#mouse-xy').html("center hit: " + isCenterHit + " | X: " + x + " Y: " + y);
// rectangle coordinate hit test (this can be done other ways too)
if ( x > tX && x < tX + tW && y > tY && y < tY + tH ) {
// toggle the boolean
if ( checkCenterHit && $(e.target).attr('id') === 'center' ) {
isCenterHit = !isCenterHit;
checkCenterHit = false;
}
if ( isCenterHit ) {
// do this when center hit state is 'on'
$('body').css('background-color',$(e.target).attr('b'));
$('canvas').css('cursor','pointer');
} else {
// do this when center hit state is 'off'
$('body').css('background-color','');
$('canvas').css('cursor','');
}
}
else {
$('body').css('background-color','#ffffff');
checkCenterHit = true;
}
});
Upvotes: 0
Reputation: 514
Well sorry this isn't a real answer, but I've edited your code to use loops and arrays/maps. That way you may be able to get some more help. Hope you'll be able to learn something from it as well :)
So your code could also look like this:
var r
var s
var l
function makeRects(a,b)
{
r = a-b
s = (a/2) - (b/2)
l = (a/2) + (b/2)
// Place all arrays inside maps, so that we can loop through them later.
side = {
l: [0, 0, a, b],
t: [0, 0, b, a],
r: [r, 0, b, b],
b: [0, r, b, b],
}
square = {
a: [0, 0, s, s],
b: [l, 0, b, s],
c: [0, l, s, r],
d: [l, l, r, r]
}
center = {
l: [0, s, b, l],
t: [s, 0, l, b],
r: [r, s, a, l],
b: [s, r, l, a],
m: [s, s, l, l]
}
}
function cursor(a,b)
{
var inside = {
a: false,
b: false,
c: false,
d: false,
center: true
}
// This loop will run through every key of the map, and x will hold the key
for (var x in square) {
if ((a>square[a][x] && a<square[x][2])&&(b>square[x][1] && b<square[x][3]))
{
inside[x] = true;
// Instead of checking if the cursor is inside the center, we assume it
// is by default, and if it is found inside a square, inside['center'] is set to false
inside['center'] = false;
post(x + "Square");
post();
}
}
// Not sure what you want to do here...
if (((inside['center'] && a>s) && a<l) && b<center['l'][3])
{
outlet (1, 1)
}
else if (((inside['center'] && a>s) && a<l) && b>center['r'][0])
{
outlet (1, 2)
}
else if (((inside['center'] && b>s) && b<l) && a<center['t'][3])
{
outlet (1, 3)
}
else if (((inside['center'] && b>s) && b<l) && b>center['b'][1])
{
outlet (1, 4)
}
else
{
outlet (1, 0)
}
}
Upvotes: 1