Is there a way to find out if an element is obscured by another element that is not a child of the first one? Because I have a menu that I like to hide when you click anywhere on the page, but not when there is currently a lightbox open that obscures the menu.
function isObscured(element) {
// get element at element's position
var elem = document.elementFromPoint(element.offsetLeft, element.offsetTop);
// return whether obscured element has same parent node (will also return false if
// element === elem)
return elem.parentNode !== element.parentNode;
}
http://jsfiddle.net/pimvdb/tKtEV/
You have to evaluate it yourself.
Take into consideration coordinates and size of the frontmost element, then check for "collision" with the elements behind it you need to control.
It's basically a check for overlapping squares.
If you know which element could be obscuring the "target", you can use the method getBoundingClientRect to find the edges of the obscurer and the "target". Then it's a problem of finding if two rectangles overlap.
It could seem daunting to calculate that, but to separate the X and Y axes is the Egg of Columbus here.
Two rectangles do NOT overlap if:
1) their X axis range doesn't overlap
a. rect1's bottom is above rect2's top
b. rect1's top is below rect2's bottom
2) their Y axis range doesn't overlap
a. rect1's right edge is to the left of rect2's left edge
b. rect1's left edge is to the right of rect2's right edge
Otherwise--that is, if their X axis overlaps and their Y axis also overlaps--they definitely DO overlap.
function overlaps(el1, el2){
var rect1 = el1.getBoundingClientRect();
var rect2 = el2.getBoundingClientRect();
if (rect1.bottom < rect2.top // 1a
|| rect2.bottom < rect1.top // 1b
|| rect1.right < rect2.left // 2a
|| rect2.right < rect1.left) { // 2b
return false;
}
return true;
}
Related
I'm working on a script that will move a layer, right, left, up, or down. This depends upon which edge of the layer is inside the canvas.
I've managed to get the layer moving left and right (x-axis) using bounds[0] and bounds[2].
But when I try to get it to move up or down, it still moves left/right. Is it the bounds number I've got wrong?
var Y1 = bounds[3].as('px');
var Height = app.activeDocument.height.as('px');
//move down
if (Y1 < Height) {
activeDocument.activeLayer.translate(Height-Y1);
}
The first thing you probably want to do in a situation like this is to check the documentation. For .translate() we can find the following:
so to move horizontally we would use deltaX and to move vertically deltaY, in your code you're giving to .translate() only deltaX, so as expected your layer is being moved horizontally. To fix this pass 0 as a first argument and your Height-Y1 as a second one:
activeDocument.activeLayer.translate(0, Height - Y1);
Well I am trying to make an animation where there are a lot of dots on the canvas and on mouseover they are hidden and after a timeout shown again.
The mouseover effect shouldn't just happen on the exact spot the mouse is but in e.g. a box of 20x20 pixels.
In my prototype I have these loops...
for (var i = -10; i <= 10; i++) {
for (var j = -10; j <= 10; j++) {
var imagedata = c.getImageData(x+i, y+j, 1, 1).data;
if (imagedata[0] == 99) {
fadeInRectangle(c, x+i,y+j);
}
}
}
Is there a quicker way to find dots where the mouse is? It doesn't have to be a square it can be a circle also where the position is checked... I don't care. Thanks in advance
The fiddle: https://jsfiddle.net/vrjw996h/
What I would do is create an array of dot objects, each one storing the dot's x and y position, as well as a visible property (Like {x:10, y: 40, visible: true}). Whenever the mouse moves, loop through each object and check the distance between the mouse and the dot. If a dot is found to be in range, set its property visible to false. After that part, still inside onmousemove, clear the canvas and redraw each dot, skipping those with visible: false. After a few seconds, set visible back to true.
https://jsfiddle.net/Howzieky/vrjw996h/1/
I'm making a drawing application which involves clicking in a div box and reading co-ordinate values. The problem with it so far is that the coordinate values aren't correct relative to the box.
Here's my setup.. the drawing application starts off by loading simple HTML and then a DIV exclusively for drawing. Then I use a click handler to detect a click and return co-ordinates.
The width and height return fine because I defined them for the DIV, but the top and left positions return NaN in javascript.
I know I can easily do this with using css property position="absolute" for the DIV and specifying left and top that way, but that would wreck the rest of the HTML document because then the whole thing would look out of place.
Is there a way I can get a top and left value of DIV without explicitly specifying the two values for the DIV?
I want to achieve this with simple javascript. No jquery.
jsBin demo
function getXY( ev ){
var gbc = this.getBoundingClientRect(),
X = ev.clientX - gbc.left,
Y = ev.clientY - gbc.top;
alert( X +' '+ Y);
}
document.getElementById('board').onclick = getXY;
https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
https://developer.mozilla.org/en-US/docs/Web/API/event.clientX
https://developer.mozilla.org/en-US/docs/Web/API/event.clientY
So I'm trying to solve a graphics problem. Basically there's a container, let's say its 600px wide. If there is only one rectangle in that container(with no overlapping rectangles) it takes up the width of it. However, the issue is when these rectangles overlap, the width has to shrink accordingly. We are given the top left and bottom left y-coordinates of this rectangle. (such as it starts 60px down and ends 120 px down the big container)
So I wrote an overlap algorithm that checks if an overlap exists and counts the number of rectangles that the rectangle overlaps with (including itself). Then I divide the container width by the maximum number of elements overlapped to get the width of the smaller rectangles.
for (i = 0; i < events.length; i++) {
var event = events[i];
var numCollisions = 0;
for (j = 0; j < events.length; j++) {
var eventCmp = events[j];
if (event.start <= eventCmp.start && event.end > eventCmp.start ||
event.start < eventCmp.end && event.end >= eventCmp.end) {
numCollisions++;
}
}
However, I've noticed a huge problem with this. If you look at this picture below the rightmost rectangle has two overlapping rectangles. By my algorithm you would get the container width/3 (including the rectangle itself) which is incorrect. The actual answer is the container width/2.
So the issue is (after this long winded explanation) that I need to find if two rectangles are horizontally aligned. I've been busting my head on this for hours. Any hints on how I can do this?
Well, the easiest answer is divide by 2 IF you have a collision (not caring how many collisions you actually have). If you need something more sophisticated, can you show a more sophisticated case?
a less than optimal, but easy to implement algo would be:
foreach y coord in the main container
rects = find all rects which contain this y coord
foreach rects as rect
rect.maxHorizNeighbors = max(rects.length, rect.maxHorizNeighbors)
theres still some other issues you'll need to address, but this should get you started on your homework assignment. in particular, theres a case where you could possibly end up with horizontal gaps. ill let you find that on your own.
Recently, I have started dabbling with HTML5 and the mighty canvas. However, I am trying to accomplish something and I am not sure what the best way would be to handle it.
I am trying to make a randomly generated set of buildings with windows, as you can see in the following example that uses divs:
Example Using Divs
The issue that I am coming up with is that I want to be able to randomly generate images/content in the windows of these buildings, and be able to easily capture when a window is clicked, but I am not sure how to go about handling it using the canvas.
Example Building:
function Building()
{
this.floors = Math.floor((Math.random()+1)*7); //Number of Floors
this.windows = Math.floor((Math.random()+1)*3); //Windows per Floor
this.height = (this.floors*12); //1px window padding
this.width = (this.windows*12); //1px window padding
//Do I need to build an array with all of my windows and their locations
//to determine if a click occurs?
}
Example Window:
function Window(x,y)
{
this.x = x; //X Coordinate
this.y = y; //Y Coordinate
this.color = //Random color from a range
this.hasPerson //Determines if a person in is the window
this.hasObject //Determines if an object is in the window
}
Summary: I am trying to generate random buildings with windows, however I am unsure how to go about building them, displaying them and tracking window locations using the canvas.
UPDATE:
I was finally able to get the buildings to generate as I was looking for, however now all I need to do is generate the windows within the buildings and keep track of their locations.
Building Generation Demo
I guess if you are drawing the window, you already have the function to create their canvas path. So you can apply the isPointInPath function on all window you have to determine if the user clicked on a window.
canvasContext.beginPath()
{
(functions corresponding to your window path)
}
canvasContext.closePath()
var isInWindow = canvasContext.isInPath(clicPosX,clicPosY);
Actualy you have to check where mouse is clicked, and if it's in window, then call some function. And yes, you will need to have array, of locations.
Take a look here
Draw your squares using fillRect, store their north-western point coordinates into an array. You'll also need these rectangles' dimensions, but since they are all equal squares — no need to store them in the array.
Then add a click listener to the canvas element, in which detect the pointer's position via pageX/pageY minus the position of the canvas element.
Then on each click traverse the array of rectangles and see if they contain the pointer's coordinates:
if (((pageX > rectX && pageX < rectX + rectWidth) || (pageX < rectX && pageX > rectX + rectWidth))) &&
((pageY > rectY && pageY < rectY + rectHeight) || (pageY < rectY && pageY > rectY + rectHeight))) {
/* clicked on a window */
}
Demo.