Get the actual width and height of a point feature in OpenLayers - javascript

I am trying to figure out a way to get actual width and height of point feature. I.e., the image + text and not just the latitude / longitude of the geometry.
So far, I learnt that I could get coordinates by using the following code:
feature.getGeometry().getCoordinates();
But this gives me the exact coordinate where the feature was added but what I want is the width and height of the feature after it has been rendered. I.e., height = height of image + height of the label.
I am doing this to start wrapping texts when two feature are very closes to each other.

to get the height and width of an icon of a point in openlayers you can use:
feature.getStyle().getImage().getScale()
feature.getStyle().getText().getScale()
I must mention the fact that if you have not specified scales for the text and for the icon in the style, you will receive undefined

Related

How to move an unknown object to center screen? HTML/CSS/JS

I am developing a VueJS project and have created a set of cards appearing on the page, when one of these cards is selected, I wish for it to move to centre screen but keep the position it has moved from in the list of options.
I know that by changing the position from 'unset' to 'relative' the card now has move functionality with 'left', 'top' etc. but I still need to find a way to automatically move the card to centre screen regardless of where on the screen the card is moving from.
Does anyone know how to achieve this with the use of JS?
I imagine there is a way of receiving the current location of the node and moving it to the center of the screen, but I am not sure on the specifics of how to achieve it...
Image for context:
CardsProject
EDIT: I have for now gone with rendering an absolute position for the card which means there's no CSS transition from the card's original place to the centre of the screen and the card also temporarily loses its place within the deck.
Before click: click here for image
After click: click here for image
I found the answer after many, many hours of scouring the internet and deepfrying my code.
The answer: Don't use 'relative' positioning!
There's a far nice option to hold the position the element is moving from, but allow for the item to move freely with the use of CSS' top or left etc. and this option is position:sticky;!
With this and the use of JavaScript's coordinates documentation
.getBoundingClientRect()
...I managed to solve the mystery. The function I made to pull a vector between the current object and it the centre of the screen can be found here, returning an array of size 2 of X and Y vectors respectively.
function calcCenterMove(element){
/*
X and Y are the current position of the element to be moved (top left corner).
Width and Height are the width and height of the element to be moved.
CX and CY are the X and Y coordinates of the centre of the screen.
*/
var x = element.getBoundingClientRect().x;
var y = element.getBoundingClientRect().y;
var width = element.getBoundingClientRect().width;
var height = element.getBoundingClientRect().height;
var cx = window.innerWidth / 2;
var cy = window.innerHeight / 2;
var xVector = cx-(width/2)-x;
var yVector = cy-(height/2)-y;
return [xVector, yVector];
}
var xAxisMove = calcCenterMove(element)[0];
var yAxisMove = calcCenterMove(element)[1];
element.style = "transform: translate("+xAxisMove+"px,"+yAxisMove+"px);";
I have paired the above code with a z-index to place the element above all others, and a screen dimming cover, to prevent the user from scrolling elsewhere or interacting with any other options.
Issues still arise here if the user resizes the screen, but I believe that is a different issue to address, possibly by using an event listener to assess a window resize and translate the element from the previous centre to the new centre using the same cx and cy properties above (or perhaps even the entire function!).
Nevertheless, I have come to the answer I was looking for, anyone feel free to use the code above, if needed!
Here are images for reference:
Before click
After click
Regards!

How to get screen coordinates with getBoundingClientRect() in the presence of CSS zoom?

I'm trying to find the bounding box of an HTML element using Javascript in screen coordinates so that I can use external tools (such as ffmpeg's x11grab screen recording functionality) to take screenshots/videos of that element by itself.
If there is no CSS zoom present, then I can find the bounding box for element elem like this:
let viewportTop = window.screenY + (window.outerHeight - window.innerHeight);
let viewportLeft = window.screenX;
let rect = elem.getBoundingClientRect();
let width = rect.width;
let height = rect.height;
let left = viewportLeft + rect.left;
let top = viewportTop + rect.top;
I can then use these width, height, left, top coordinates to record the desired box on the browser window.
However, sometimes I want to increase the zoom of the element to make things easier to see:
elem.style.zoom = "2";
Having done this, the bounding box returned by elem.getBoundingClientRect() is now scaled down by a factor of 2. If I use the approach above to calculate my recording bounding box, it no longer lines up with the element.
I've had some success with calling window.getComputedStyle(elem, null).getPropertyValue("zoom"), parsing the zoom number, and using it to correct the bounding box. However, this isn't a perfect solution--what if I want to zoom document.body by some amount and also zoom the target element by some amount?
So, I'm wondering if there's a universal way to convert the coordinates from elem.getBoundingClientRect to screen coords that works even when CSS zoom is applied to various elements.
I considered using the browser's own zoom rather than CSS zoom, but I would rather not since I'm using Selenium to set this stuff up and I've seen dire warnings about adjusting the browser zoom with Selenium here.

How to find bbox height and width for openlayer3 map

I'm working on openlayer3 map, i had draw one bbox on map, now i want to find height and width of this bbox. Please let me know how to get this.
I had already tried map.getPixelFromCordinate but not able to get the size of it.
Yellow color border is bbox, for which i want height and width.
Please help me out.
For getting heigh&width of bbox you can follow this way.
1) pass one by one coordinate to map.getPixelFromCordinate(), this will returns pixels.
2) subtract two pixels for x coordinate as well as y. this will be height and width for that zoom level.

How to get image coordinates after centering the object using image.centerObject() in fabric js

I am drawing a rectangle on top of a image and then saving the coordinates of both to a Mysql Database table.
Then I have to retrieve the same image and overlaying Rectangle from a Andriod APP
which will not know anything on FabricJS .
It will only know the coordinates of image and rectangle.
Luckily for image it is not a problem as it can be maintained using some Aspect ratio algorithm.
But how to get the coordinates of Rectangle , so that it can be rendered correctly.
Now what I see is Fabricjs saves the coordinates according to window left ,top, width, height. But andriod app expects the coordinates according to image , which fabricjs doesn't provide.
Any suggestions how to achieve this?
Please let me know if somebody didn't understand .
Its a basic and easy statement , hence not adding any fiddle or code.
before saving to database do this:
image.setCoords();
rect.setCoords();
in
image.oCoords.tl, image.oCoords.tr, image.oCoords.bl, image.oCoords.br
and
rect.oCoords.tl, rect.oCoords.tr, rect.oCoords.bl, rect.oCoords.br
you will find 4 objects with both x and y coordinates that represent your absolute position of the object.
tl stands for Top Left, br stands for Bottom Right and so on.
You should have no problem then to make some subtraction and find relative coordinates of the two objects.
Example:
if image has tl (45,80) and rect has tl (80,110) it means that rect coordinate relative to image is (80-45, 110-80) = (35, 30)

How to recalculate x,y coordinates based on screensize

I'm have a heat map application and store I store the x,y coordinates of a click and also the viewport width and height. Real data for 2 clicks:
x, y, width, height
433, 343, 1257, 959
331, 823, 1257, 959
The issue is when I resize the screen on the responsive site, the displayed clicks are now all off. I'm coming up empty on my searches but is there a formula or algorithm to recalculate the x and y coordinates for different resolutions. For example, the first click, if the width goes from 1257 to 990 and the height goes from 959 to 400, how to I recalculate the x and y so they line up in the same spot?
EDIT:
I added 2 fields to the database, width_percentage and height percentage
to store the x percentage of the width and the y percentage of the height. So if x was 433 and the width of the screen was 1257 then x was 35% from the left edge of the screen. I then used the same theory for the height and ran the calculations but it did not scale the click dot to the same spot as I though the percentages would do for scaling resolutions. I testing this by clicking on full resolution 1257 width then reopening at 900 width. See below for code to display click dots at lower resolution.
Ajax PHP
while ($row = mysql_fetch_array($results)) {
if( $_GET['w'] < $row['width'] ) {
$xcorr = $row['width_percentage'] * $_GET['w'];
$ycorr = $row['y'];
}
}
This uses the $_GET variable, passing the width and height of the screen resolution on page load. Then it gets the click dots from the database as $results. Since I only scale the resolution width from 1257 to 900 I did not put in calculation for height and its the same pixel as the initial click. The new width I multiplied by the percentage and set the dot that percentage margin from the left of the screen. Since the percentage is 35%
the new x coordinate becomes 900 *.35 = 315px from the left edge. It did not work and I'm still scratching my head on head to keep click in the same spot for responsive sites.
Have you tried this mathematical formula to change the range of a number?
And also instead of storing this:
x, y, width, height
433, 343, 1257, 959
331, 823, 1257, 959
You could store it normalized between 0 and 1 so it works for any width/height (calculated by dividing each x by its width and each y by its height):
x, y
0.344, 0.357
0.263, 0.858
Then you don't need to know the width/height you used when you stored them, and when you want to translate them to the size of the current screen you just multiply each one by the current width/height
You can acheive this by jquery:
$( window ).resize(function() {
//ur code
});
javascript
window.onresize = resize;
function resize()
{
alert("resize event detected!");
}
if you are working on mobile devices use this one also
$(window).on("orientationchange",function(event){
alert("Orientation is: " + event.orientation);
});
I think you are on the right track with the percentages. Are you including the offset of the map image. I wonder if your algo is working but the visual representation appears wrong because the offset is changing in the viewport.
$(window).resize(function() {
var offset = yourMap.offset();
myLeft = offset.left();
myTop = offset.top();
});
You need to add the offsets every time to get the proper placement.
This is what you should do. Sometimes the resize event fires when the document is being parsed. It is a good idea to put the code inside an onload event function. The orientation change function is taken from #Arun answer.
window.onload = function() {
$(window).on("orientationchange", function(event) {
alert("Orientation is: " + event.orientation);
});
window.onresize = function() {
alert('window resized; recalculate');
};
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
for this you need to do some calculation. Here is the function which will return new x and y potion based on the height and width
function getNewX(xVlaue, oldWidth, newWidth){
return xVlaue * newWidth / oldWidth;
}
newX = getNewX(10, 150, 100); // Use
You can use the common function for height and width calc.
DEMO
The whole question highly depends on the page you want to use this on.
Most pages have a centered block and/or some self-resizing (read "responsive") elements. If the page is not very responsive, e.g. having a fixed width, you have an easier job. If the page is centered, you might want to save the cursor's X-position relative to the center of the page. this way the window width doesn't matter. The same also applies to left- and right aligned pages of course - in this case you would save the X-pos relative to the left or right edge of the window respectively.
The following image shows a center-oriented click position. Note that the x- and y properties of the click don't change here if you resize the window.
Now to the more generic methods
If you save the window dimensions, the cursor position AND the scroll offsets on every click, you will most probably be able to reproduce it alongside the layout, but you'll need to reproduce it for every unique dimensions set. If you used the trick from above you might be able to overlay all layouts and find a common denominator. For example, if your page is centered in the window, has a max-width, and you saved the X-pos relative to the center of the window, you can overlay all clicks that happened in windows that were at least that width.
You could do some trickery however, and save the clicked elements alongside the informations you already do save. If you also save the click position relative to the element, you can evaluate this data to something like "the submit button is rather pressed on the bottom right side" or "people often click on the far end of that drop-down and sometimes mis-click by a few pixels".
Try both of the following:
1. Padding and margins might not scale. Use "* {padding:0;margin:0}" at the end of your stylesheet and check if that fixes it.
2. Ensure outer and inner (that means all) elements scale. Any single element failing to scale will make many other elements fall out of place. This generally happens with text inputs. Use "*{border:solid 2}" at the end of your stylesheet to visually observe the effect of scaling on each element.
I'm sure your problem will be resolved.

Categories