How to know what lines / chars are currently visible in a textarea? - javascript

Online editor with "live preview": there is a textarea on the left and a preview div on the right. Whenever the textarea changes, the preview is updated.
This works well for small documents; for very long documents however, it becomes sluggish, because the preview has lots of DOM elements that are constantly repainted.
It would be better to only send to the preview, the part of the textarea that is currently visible (since it's the one that needs to be previewed).
There is a heuristic way to get the first visible line of the textarea:
determine current scroll offset of the textarea:
offset = scrollTop / scrollHeight
(0 < offset < 1)
the first line that is visible in the textarea is:
(total number of lines) x offset
However this only works for "short" lines, ie lines that don't wrap. In general, the number of "lines" in a textarea is not the number of linebreaks; a long line, without linebreaks, wraps and might occupy many "line spaces".
One could try to calculate the average number of "line spaces" a line occupies (average number of characters between line breaks, width of textarea, size of font...) but this is wildly imprecise.
Is there a way to know the position of the first and last visible characters in a textarea?

Well, as a crazy way for doing it you can look how ACE converts the text into canvas-drawn lines. I assume with this approach you can determine the exact position (or better to say, the exact line objects that are currently visible.
But this could also be a kind of vicious circle if the canvas-generated text is compatible in complexity to what you are having in the preview.
Alternatively you can use a fixed-width font which will give you a knowledge of the exact number of chars in the single line, and thus a way of calculating the exact first / last lines.

Related

Rechart.js decrease space between bottom text (Months)

I almost make chart, that i need. Now i make this in Rechart.js
I must do this
An i have a few questions
How i can decrease space between bottom text (jun,dec etc...) in Rechart.js
How i can shift the starting point, for example, by 20 pixels, without shrinking the line
How i can customize vertical line when hover ( change color, style, height etc )
If you know at least 1 answer l'll be very thankful
Thank you for any information about this

How to find one image inside of another? Node.js

I have 2 bmp images. ImageA is a screenshot (example) ImageB is a subset of that. Say for example, an icon.
I want to find the X,Y coordinates of ImageB within ImageA (if it exists).
Any idea how I would do that?
This is called optical-recognition. It may seem complicated (it is) but can be very simple in implementation, so don't shy away from it!
Let Image A be the image we're looking for, and Image B be the larger image with Image A in it.
Method 1
If Image A's scale in Image B hasn't been altered, and the colors are all preserved, you can place Image B on an HTML 5 canvas and iterate over the pixel data. You would load the first line of pixels from Image A and then iterate over every pixel in Image B. If a pixel was the same, you would store that pixels column in a variable and check if the next matched too. If the first row was a full match, then hop to the next row and compare those. You'd repeat that until you either got a match or hit an (or enough) pixels that didn't match. In that case, you would reset all variables and start all over again looking for a match to row 1.
Method 2
If Image A isn't perfectly identical in Image B, new complications arise and things become a lot more complicated. If only the scale changes, we can make a few tweaks to Method 1 to get something that works. Instead of grabbing any pixel and seeing if 80% or so matches, we additionally need to track the images sheer/compression.
In each row, go over pixel incrementally. For example, we'll check every tenth pixel. If we find a match for pixel 1, we then check 10 pixels away and see if that pixel exists anywhere in our row. If we find it, the distance from 0 to that pixel divided by 10 (our increment) is how many times larger the original image is.
If we found a pixel 20 slots from 0 in Image A, and it was only 10 pixels apart in Image B (remember, 10 is our increment), then our original image was 2 times larger. In other words, the new image is half the size of the original.
1) compression = target_width / original_width
2) compression = 20 / 10
3) compression = 2
This is a much more complex but robust way to detect a match. Enough matching rows mean you've got a matching image, but what about vertical stretching?
Similar logic. If you find a row that matches, start at 0 and go down by 10, then find that pixel's match in Image A.
Edit
The methods I provided are generic methods to work with looking for any image inside any other image. As you can imagine this is performance intensive. I don't know what image you're trying to detect but if there are common shapes, sometimes you can do alternative algorithms. If you have a circle, for example, you can just check that there are pixels that match outside a radius and pixels that are the same within.
The methods I presented also don't compensate for warping. Method 2 should be fine if the image is stretched but keeps a rectangular ratio. If the image has for example been warped into a circle shape, things get infinitely more complicated. For that case, the only hint I could give would be to check pixels within a radius of the original for matches.

Javascript bmi calculator pointer position

I'm building a BMI (Body Mass Index) Calculator and everything works fine but now I want to add an image with a pointer on it indicating the result of BMI.
My problem is that I don't know what formula to use in order to calculate where the pointer will fall and to position the pointer correctly on image.
So if the result is 21.5 I want the pointer to be somewhere where the 21.5 will be on the image.
Please see the image attached to see exactly what I want to achieve
thank you
Seeing how I myself am very new to javascript and I'm not really sure how you image is constructed (if it's all a big box or several lesser boxes), I'll just give you my point of view.
Assuming you have four seperate boxes and we take the green one as an example.
If the box range is from 20 to 25 BMI then I would approach it as followed
MaxBMI - MinBMI = Range (in the case 20 and 25, Range is 5)
then take your current BMI (in this case 21.5)
CurBMI - MinBMI = DistanceFromMin (in this case Distance is 1.5)
Then simply take (lengthOfBox / Range) * DistanceFromMin and you know the position of the arrow.
If this didn't answer your question at all I hope you can specify the problem a bit better.
(This was really my first answer ever on StackOverflow :P)
How about using percentages?
lets say your image is 200px, have a bmi of 20 at left/margin-left:20% of your 200px image?
If you can provide more details on you iomplementation with a link of some code I can be more clear with the answer

How to get the maximum width of a single character in JavaScript?

How can I get the maximum width of a single character in JavaScript? I have a text painted in an unknown font, but I know what the text length and font size is.
Now I want the to get the largest character in that font, so I can make sure the parent element (a div for example) is not too narrow (it has an absolute width). The widest character is usually the M or W, but I'm not sure, perhaps there are fonts which paints wider characters.
Now how do I do that? Is there a fast method for?
Use the CSS width: 1em;. em is a relative measurement and is the width of the 'm' character

Positioning SVG Elements

In the course of toying with SVG for the first time (using the Raphael library), I've run into a problem positioning dynamic elements on the canvas in such a way that they're completely contained within the canvas. What I'm trying to do is randomly position n words/short phrases.
Since the text is variable, its position needs to be variable as well so what I'm doing is:
Initially creating the text at point 0,0 with no opacity.
Checking the width of the drawn text element using text.getBBox().width.
Setting a new x coordinate as Math.random() * (canvas_width - ( text_width/2 ) - pad).
Altering the x coordinate of the text to the newly set value (text.attr( 'x', x ) ).
Setting the opacity attribute of the text to 1.
I'll be the first to admit that my math acumen is limited, but this seems pretty straightforward. Somehow, I still end up with text running off beyond the right edge of my canvas. For simplicity above, I removed the bit that also sets a minimum x value by adding it to the Math.random() result. It is there, though, and I see the same problem on the leading edge of the canvas.
My understanding (such as it is), is that the Math.random() bits would generate a number between 0 and 1 which could then be multiplied by some number (in my case, the canvas width - half of the text width - some arbitrary padding) to get the outer bound. I'm dividing the width of the text in half because its position on the grid is set at its center.
I hope I've just been staring at this for too long, but is my math that rusty or am I misunderstanding something about the behavior of Math.random(), SVG, text or anything else that's under the hood of this solution?
The answer turned out to be how I was thinking about the Math.random() equation. It's not quite as simple as multiplying by the max and then adding the minimum value (of course). It's really more like establishing a double wide gutter on the right end of the container and then shifting the entire boundary to eat up half of that gutter:
var x = Math.random() * ( canvas_w - 20 - ( text.getBBox().width ) ) + ( text.getBBox().width/2 + 10 );
In English...
You have to double the width of each element you want to account for so you can shift the entire range back by that width to keep things nice and equal. In my case, I want to account for half of the width of the text plus a padding of 10.
For example...
Given a canvas width of 500, a text width of 50 and a desired "gutter" of 10, I create a random number between 0 and 430 (500 - 20 - 50). By adding back the widths I need to account for--half of the text width (25) + the padding (10)--I'm left with a random number between 35 and 465. If my text sits at the outer edges of that boundary, it can only reach as far as the 10 or 490.
Hopefully that's clear enough to make sense. Although it makes sense when I think about it, this kind of thing isn't immediately intuitive to me, so I'm sure I'll be referring back here often.

Categories