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
Related
If we use character from other languages like Danish then characters accent gets out of the text box, is there a way to detect if text is overflowing height wise?
My element is wrapped inside g element with clip path.
This is required output
But when we use clip path we don't get if text is overflowing outside clip path
I am creating some images using the canvas. I would like to be able to draw text in given rect (i.e. offset x, offset y, width and height) on a canvas and that text to be as large as possible without overflowing and if possible, with word wrapping. Is it possible?
It's possible.
no-wrapping:
You can use CanvasRenderingContext2D.measureText() method, which accepts a string, and returns a object { width: float }. You have to find out the height by doing some math using font's size. Then just enumerate the font sizes in a binary search way. soon you will find the best size for the canvas.
wrapping:
You have to find out the wrapping point in the string and calculate their width and height you self.
but there is a better easier way to do this.
create a hidden(visibility: hidden not display: none) div, defines its width, and put your text inside. enumerates font's size, and check if it overflows or grows too high.
I'm trying to implements css text-decoration on canvas text. what I did is stroking a line under/over/through the text.
I want to make the line looks like css decoration line, but I find it difficult to control the thickness of the line.
I'm trying to take text height and weight as factors of the line thickness, and I made it to get the height.
I wonder anyone could give me a way to measure the text weight, and I don't wanna change the way I set text font which is using css font string like: "900 30px Georgia, serif". It would be perfect if I don't need to analyze the css string... thanks
#neo108
The code is simply using HTML5 canvas API, font is set by canvas.getContext("2d").font(), I need to write a function to get the actual font weight then I can calculate a proper line thickness to underline the text(the line is draw by canvas.getContext("2d").stroke()).
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.
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.