Positioning elements of different heights - javascript

Sorry for the vague title, but I'm not exactly sure what to call this. I'm making an assignment planner using HTML and JavaScript, and I've ran into a bit of a problem while trying to make a feature to snap your text to the nearest line.
The planner itself looks like this
The "Snap to Line" feature works by checking the Y coordinate of the note (which is an input element) and checking the nearest line. I know it's not good practice, but to make it easier everything is a fixed size, so I have an array of every line's Y coordinate it could snap to:
[58,80,102,124,146,168,190,212,234,257,279,301,323,345,367,389,411,434,458,480,502,524,546,568,590,612]
When the user creates a note or change's its position, this bit of code runs:
let height = parseInt(window.getComputedStyle(e.target).getPropertyValue('height'));
e.target.style.top = getClosest(yCoord+(height/2))-(height/2)
So it gets the element's height, then finds the Y coordinate of the closest line and subtracts half the height of the element to find the proper coordinates.
I arbitrarily used height/2 as opposed to height. I thought that since the coordinate is of the line, it would need to be exactly height higher up, which makes perfect sense, but in practice for whatever reason that didn't work, and height/2 was able to give me better, somewhat better results.
However, if I use the function, it doesn't exactly work. I've tried many different methods but I can't seem to figure it out. This is the result. As you can see, it works pretty well for smaller heights, but it's as if there's an offset relative to the height of the element that affects the position. Is the problem because my method is terribly wrong? (probably) Or is there just some factor that I've been forgetting?
There aren't any borders, no margins, the padding is only 1px, but that shouldn't matter anyway since I use getComputedStyle (which I believe takes everything into account) to find the height and not the font size.
The code surrounding this feature is only a small part in a decently sized project, but I'm posting the entire document so that it may be easier to fix this.
Thanks!
note: the window with the planner on it is a popup, so your browser might block it
The code (too many characters for this post so it's on pastebin)
EDIT: I think I found the problem, no surprise that I found it just as I posted this. First of all, I needed to use height and not height/2 (no surprise there, makes sense). I though I needed to use height/2 because I was testing with small heights and the snap points were a few pixels off (7, to be exact) which made it seem like height/2 was better. Two, the main problem, is that since I used height instead of font-size, the height was the height of the entire element which meant that the bottom of the P hit the line instead of going past it.

Related

get element dimensions regardless of rotation

Suppose we have a 50x100 div, if we rotate it 45 degrees, jquery returns different values for width and height. If we rotate it again for 45 degrees, jquery returns 100 for width and 50 for height.
I'm looking for a way to get actual width and height regardless of rotation.
Note: actually the parent of my element has rotation, and I don't want to get involved with it's rotation. I'm not willing to use sin/cos with jquery width height to get original dimensions.
Since jQuery is an old library, it used some different combinations (of getBoundingClientRect, getComputedStyle, clientWidth/clientHeight and offsetWidth/offsetHeight (and also node.style)) over the times.
So, without knowing your used version of jQuery, it's hard to say what it does internally.
At least getBoundingClientRect gives you the actual dimensions of transformed elements.
Here's a small test case: https://jsfiddle.net/bxe1ve9q
I would bet that using clientWidth/clientHeight or offsetWidth/offsetHeight give you the correct values.
Addendum: As you, probably, no longer use jQuery (which is very good at working around browser bugs), you should keep an eye on those hiccupillities™. Here are some resources to look at:
http://caniuse.com
http://www.quirksmode.org/dom
http://www.webbrowsercompatibility.com
A solution to your problem is to use the native offsetHeight and offsetWidth. This since jQuerys width() and height() functions is finicky at best.
JSFiddle
https://jsfiddle.net/4vxnmr4y/2/
The fiddle checks the box both on transitionEnd and each second.
Tested in Chrome, FF, IE11, IE Edge. Try it out!
The gist of it is basically this:
var box = $('#box');
var w = box[0].offsetWidth;
var h = box[0].offsetHeight;
But in the fiddle i added a lot of code to make it a slighly more realistic real-world sample.

Getting the shape/outline of an HTML node in JavaScript

Is it possible to get the shape/outline of a DOM node in JavaScript? I would like to get some kind of representation of the shape or outline so that I can tell exactly which pixels the DOM node occupies. I can calculate the rectangle using width, height, and position, but this doesn't take into account the border-radius property, among others.
I know that I have access to all of the individual properties that will determine the rendered outline of a node (height, width, border-radius, etc), so I could, in JavaScript, reproduce the calculations the browser does. However, this would be pretty tedious and there would be a lot of edge cases.
and don't forget that different browsers may render slightly different.
That is if you are interested in the padding and margin as well.

The width seems to be zero (or NaN) always for an svg:text element in Firefox 15

I am using d3 to make a chart with multiple paths. I am displaying the path(s) description on the left hand side. The data & descriptions are dynamic so the size of the legend is naturally also dynamic, since it is not a big deal as long as I know the size of the text (just a minor adjustment to the domain/range). The problem is that I do not see an easy way to find the size of the text element in Firefox browsers.
Previously I was doing it with jquery's .width() but the clientWidth on the element is zero which seems to cause a NaNpx to be returned.
...
.on("click", function(){
alert( $(this).width() ); // NaNpx
})
...
DEMO: Click on the words.
While writing up this question I found the solution (but still going to post it because I spent a very long time searching before finding it deep in a code example). Might be just because I am brand new to d3 and svg this month but there is a getBBox() method on the text element (most elements) that will generate an object with the width/height/x/y (and it really should be used instead of jquery for all svg dimensions).
Hope posting this will help anyone else who runs into this problem because it did not seem very visible to me.
DEMO
And in the example the ~~ is a flip-bit-operator, twice will actually work like a Math.floor() but will likely be faster in all browsers then .floor().
Got the same problem. Seems like there is a bug in firefox (45.0) that <text> elements width inside SVG is always 0.
I overcame the bug by using a <tspan> element (inside the <text> element), and seems like the <tspan> has the correct width of text.
Hope it helps.

How to get screen position of CSS3-3d transformed elements?

I have a very complicated site built on CSS3 that has html elements 3d-transformed, rotated, flipped, flopped and just generally distorted.
I'm trying to figure out the on-screen location of one of these elements and don't see any way to do so. I was wondering if anyone has any ingenious ideas.
Alternatively, if anyone can explain the math behind -webkit-perspective, I can figure out the position as that's the only thing I'm not sure how to model.
Have you tried using getBoundingClientRect()?
I've used it successfully in the past to calculate the dimensions of elements that have been transformed with the transform property.
The problem is, that the CSS3 transformations doesn't actually change the position of the elements in anyway. Of course the browsers "know" that they are repositioned, because it renders them, but this information is not provided back to the DOM/API.
The only thing I can think of, is to calculate the positions based on the transformations yourself, since these are "simple" matrix transformations.
Unfortunately Algebra class has been too long ago, that I can't tell you anymore how to do it - only that it is possible.
Using getBoundingClientRect is a good idea but will only give you the coordinates of the rectangle that contains your shape, not the exact coordinates of the 4 topleft, bottomright, bottomleft, topright corners.
You'd only be able to do this by taking each of those non-transformed coordinates and applying the transform via javascript.

HTML5 Canvas drawing and updating

Sorry for how vague the title is, but I'm not completely sure how to sum up what I'm trying ask.
First off, here is a jsFiddle of what I have so far.
I'm just starting off learning to use the HTML5 canvas element, as well as using js OOP.
As you can see from the fiddle, I create a rectangle class (so that I may create as many squares as possible, although I think that may be redundant), and reference it to draw. However, when I set the height = width, I always end up with a non-square. I'm relatively new to using the canvas, but I assume thats because the square's height and width are relative to the size of the canvas element, and so the canvas element's height and width must not be proportional (since their assigned percent values as opposed to definite pixels).
I can fix this by setting the size of the square to pixels, but then when my keypress event is called, the square doesn't move at all.
Also, I have the keypress event so that a user can move the square with the arrow keys. However, the up/down keys values seem to be inverted, even when I flip-flop them in the code? And the left/right keys don't do anything?
And, I also can only make the square move up/down once? Shouldn't my code allow me to increase my x/y values as long as the user keeps pushing the corresponding buttons?
If someone could check this out and give me some pointers as to what I'm doing wrong, that would be great! I'm trying a lot of new things with this, as its just a learning experience, so if you feel so inclined, help me learn!
You experienced a thing that often goes wrong with resizing a canvas - trying to use CSS for it. Using CSS for canvas drawing will scale it - not changing the resolution. For setting the resolution, use the width= and height= attributes in HTML.
As for the movements, it appears that keyup works better. However, for the up key, the y would decrement (top is 0, bottom is something positive).
A few other things I'd like to highlight.
Using canvas as a variable name for the context is a little ambiguous. There is a difference between the canvas and its context used for drawing.
Also, you state //browser doesn't support html5 if ctx does not exist. However, in case the browser does not support canvas/HTML5, the .getContext('2d') function call will fail already because it's not a function in that case. Your else statement will only get executed if the function does exist but does not return something. That will probably never be the case.
Empty else loops aren't very useful either, but that doesn't hurt :)
http://jsfiddle.net/DqrEm/4/
Your problem isn't with the size of your square, but with how you size your canvas. In your jsfiddle, when I changed the canvas starting line to <canvas id="practice" width="500" height="500"> the square was drawn properly. I tried changing the width and height in the CSS from 100% to 500px but the square was still drawn incorrectly.
Update: Setting the width and height to 100% in the actual canvas tag(i.e <canvas id="practice" width="100%" height="100%">) works too.

Categories