I'm working on an Illustrator script (javascript) and I need to measure the width of a letter. This letter is a TextFrameItem with only one character:
The object has an attribute .width which gives the width of the bounding box above.
The length I need to know is the one of the blue baseline.
Any idea to measure it?
The only reliable way I have found to get the width of text is to rasterize the textlayer (dup a copy if you need to retain the original textlayer for later) and then work off the bounds of the rasterized layer.
Related
I'm using Mapbox's queryRenderedFeatures() to handle hovering and clicking.
The issue is that some symbol layers have a fair amount of padding to reduce the density of symbols, and this padding is taken in consideration for the symbol's hitboxes. As a result, a naive implementation will think that the mouse is hovering or has clicked a symbol while it is not the case visually.
Here's an example of the kind of hitbox present in the style (the red ones are from a hidden symbol):
With no filtering on queryRenderedFeatures() results, the mouse will be considered as hovering the point as soon as it enters the hitbox.
I tried filtering out padded features manually by computing the point-to-cursor distance in pixels. It works ok for round or square symbols that are centered on their point, but gives incorrect results for rectangular symbols or those that have a translated position.
I also tried to find a way to get the symbol's position and size in pixels so that I can recheck the collision without padding but couldn't find any method for that.
Is there any way to use queryRenderedFeatures() or an equivalent while ignoring icon padding? Or any alternative to produce the expected result.
I also tried to find a way to get the symbol's position and size in pixels so that I can recheck the collision without padding but couldn't find any method for that.
You can get the anchor position for a symbol, in pixels, by:
Using querySourceFeatures() or queryRenderedFeatures() to obtain the feature.
Using map.project() to convert the feature's lngLat into pixel coordinates.
If your symbol is not placed at the anchor, you will have to perform the same calculation manually.
I don't think you can do much better than this method overall:
Detect a hit within the padded bounding box, find the feature's geometry
Get the pixel coordinates of the feature's anchor
Offset those coordinates using what you know about the symbol's offset etc.
Calculate the distance from there to the mouse cursor.
Is this possible to calculate height of the text BEFORE it is inserted into DOM?
Width of the div container is known, but I need a way to calculate its height before it is inserted.
The heights of the one line of text is also known (css), so the height could be calculated by multiplying the height of one line by the amount of lines, but the question is if this is possible to calculated BEFORE it's DOM.
Since your question explicitly requires the text not to be inserted into the dom this precludes the usually used method of simply inserting it outside the viewport and then measuring there.
An alternative approach: The canvas 2D rendering context's measureText function which can be used to determine the width if you know which styling (font width) will apply in advance.
Some advanced CSS rules such as letter-spacing may make those results inaccurate.
I have big horizontal strip image in photoshop which is made of lots of smaller elements. The background is transparent and the strip goes from smaller elements (left) to bigger elements (right). My goal is to make this strip interactive to mouse events.
Each element is some kind of polygonal image which is trimmed left and right and then exported as a png. It is then imported into a canvas.
The problem is that I can put them side by side but since they are not rectangles I need a way to calculate the offset made up by the transparent pixels on each side of each element to make them stick together correctly... I am using KineticJs to get a precise hitarea for each element... So maybe there is a way to do it automatically with kineticjs,or there is some kind of operation I could do using each image data?
My problem illustrated:
Any ideas?
Also I am doing this simply because I would prefer precise mouseOver bounding box on each item (rather than a simple rectangle) and would rather avoid the solution to calculate each offset manually... But maybe that's not worth it?!
Ok, so you have yourself a custom shape you want to use, here is a tutorial for that: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-shape-tutorial/ , the simplest thing you can do, and even that seems fairly long, is to calculate the bounding lines for that shape. (Two somewhat vertical lines, and two somewhat horizontal lines). Then you test if the right vertical line of shape one crosses with the left vertical line of shape two, if they do, then set the coordinates of the images to be the same coordinate.
http://www.mathopenref.com/coordintersection.html
line1 = ax + b ..... line2 = cx+d //see possible tests
if(...intersection test...){ // or just test if some coordinate is left of some other coordinate
shape2.setX(shape1.getX()+shape1.getWidth()); //account for image width, so they don't overlap
shape2.setY(shape1.getY()) // no need to account for height
}
UPDATE: This is a very rough solution to the workings of the problem. The next step would be to do more fine tuning dependent on each image.
http://jsfiddle.net/9jkr7/15/
If you want precise areas, use an image map. With some clever finagling and a blank image gif you should be able to have the background you want whenever you hover over any particular area of the image map (might require javascript).
The other option I can think of would be to use SVG itself or one of the many libraries in existance to build interactive vector graphics into your page.
You could also write a function that calculates the left most, top most, right most, and bottom most pixel by looking at all of the pixels in the image data. Here's a tutorial on that:
http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-tutorial/
I'm using JavaScript to inflate a span of left-aligned text until it fills its container, or until it reaches variable thresholds in either height or width. This process results in a widely varying font-size.
My problem is that, with certain characters, there is a small amount of padding on the left... and while normally it's not noticeable, with very large font sizes it can reach 10 pixels or more.
I whipped up a page to demonstrate the effect on various characters:
http://jsfiddle.net/kBu7S/
The text span exists in a design where every other element going down the page is aligned pixel for pixel to the left edge, so it's very visually distracting with the larger text sizes.
Can anyone think of a way to calculate the amount of padding, so that I can bump the relative position of the span? Or maybe there's even a CSS solution? (letter-spacing and word-spacing have no effect.)
I'll admit that even a dirty solution seems pretty unlikely... thanks for your consideration though.
The padding is often called the "shoulder" of the type, and it's intrinsic to the design of the typeface. There's no simple way to counter-act it, because it's there for optical reasons, to give the type the right spacing. After all, if you type IIIIIII, you need to have some spacing between the capital I's, and that only comes from this padding. Other characters, like WWWWWW, need none.
Your best bet is to do an experiment with your typeface, and measure the actual padding on each character, then build a table mapping characters to their paddings. Then you can adjust the character's position. This is a lot of work, but I don't know what else you can do.
This worked on the fiddle:
#text:first-letter { margin-left:-3px}
You could expand that to a class...
.fontCorrection:first-letter { margin-left:-3px }
...and apply it as appropriate.
Well, you could build a script to generate an image using the same typeface with the same size (black on white background) and read the bitmap to count the distance from the left edge to the first black pixel.
It's kind of overkill, but it's the only thing I can think of.
I am writing an application, and in it, I would like to have some h1 elements with variable font size.
I use the full width (1000px) of a div as a limiter, and a script that automatically sets the font of the h1-element so that it fits the width of the div without line break.
This is quite easy to do with php GD, but I thought I wanted to do this client side.
See the TextFill jQuery plugin that was created as part of the answer to Auto-size dynamic text to fill fixed size container
I don't think there is a pre-built function for this. I guess you'll have no choice but to run a loop and resize the element until it fits.
It could work like this:
Create a clone of the DIV, with jQuery e.g. element = $('element_id').clone()
Set the clone's font-size to 1
Build a loop that
Increases font-size by one pixel
Checks whether the desired width has been reached
If it has, breaks the loop
the font-size in the cloned element will then be the closest match for your desired width.
Update: The plugin referenced in #Pär's answer does exactly this.