How to get text weight on canvas element - javascript

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()).

Related

How to set font-size for svg without unit in javascript

I'm editing plotly.js library source code to have scalable plots, I set viewBox and preserveAspectRatio (plotly.js use d3 library) but have problem with font-size if I use no unit the property get changed to px
I've tried to test from console if font is changed to have no unit using this:
[...document.querySelectorAll('text')].forEach((text) => {
text.style.fontSize = text.style.fontSize.replace('px', '')
});
but it seems that if you don't use unit, the px is added automatically.
I've also tried to use rem unit and set 62.5% on html where original font size is divided by 10 but it don't scale when I resize the plot.
Also tried this new CSS typed OM API:
[...document.querySelectorAll('text')].forEach((text) => {
var size = +text.style.fontSize.replace('px', '');
text.attributeStyleMap.set('font-size', CSS.number(size))
});
but got error:
Failed to execute 'set' on 'StylePropertyMap': Invalid type for property
Any solution to have font-size without unit set from javascript, or other way to proportional text?
In SVG, having no units specifier is the same as using px. So font-size: 10 and font-size: 10px mean the same. They will behave the same.
I don't know why it matters to you that the value has no units. It sounds like you think that it is why your text is not scaling. That will not be why. There must be something else going on. If you want help with that problem, then add a MCVE to your question.
in svg each style property have corresponding attribute so you can use:
d3.select('text').attr('font-size', 10);
and it will set font-size without unit. The plot still don't scale but this was the question.

Write curved text within a circle with PaperJS

The title basically outlines all the details of my problem. I'm trying to write text within a circle that curves with the outline of the circle. Something very similar to the image bellow.
You can actually do this with a little hack.
Here is how to proceed:
Get the offset to the x-center of each glyph in the text. This can be done by using the with of a PointText for the substring until the glyph.
Find the point for the offset on the path that you want your text to align to.
Place the single centered glyph at the just found point. Rotate the glyph by the path's tangent angle.
Here is the Paper Sketch: Align Text to Path Sketch
And here is the result of a simple test:
You can use the code with an arbitrary path, not only with circles.

Change the background colour of a Raphael "Label"

If I create a Label using Raphael, the default style is a black block with white text.
How can I change the background box colour, but not the text colour? I've tried:
paper.label(x, y, value).attr("fill", colour)
but that also fills the text and I end up with invisible text.
I also can't simply change the default colour in this function because I need to have a few different ones depending on a line that it's added to:
As you noticed,
Paper.label(x, y, value).attr(
fill : color
);
changes both the background fill color and the text fill color, resulting in invisible text.
Unspecified correctly explained that this is an array, so each portion must be altered separately, as they illustrated. However, they didn't mention the easiest way to change update both sets of attributes, so I wanted to share this tip. In order to do this, change the attributes into an array with two sets. The first element is the background, and the second is the text.
Paper.label(x, y, value).attr([{
fill : backgroundColor
}, {
fill : textColor
}]);
You can add any other applicable attributes to each part. Here is a working example: http://jsfiddle.net/VzpeG/1/
I was working on a graph similar to this and used:
.attr({fill: "#EF7C4D"})
Let me know how this goes...
var r = Raphael('divID', 320, 220);
text = r.text(100,100,"Hello").attr({fill:"#fff"});​​​​
text.label().attr({fill:"#f00"});
Here's a working fiddle http://jsfiddle.net/vpGyL/216/
Set any color on text or on label both apply separately...Hope this helps !
Digging in furthur...Paper.label(x,y,text) is different from Element.label()
If you look at the source code Paper.Label(x,y,text) is a set of rectangle element & text element, so doing .attr({fill:"SomeColor"}) applies to the entire set, hence both rectangle & text share same color(Hence the invisibility).
Oh yeah If you just want to change the text color do this Raphael.g.txtattr.fill = "#yourColorCode" But this changes the text color globally on all the charts and tooltips(don't seem to be a good idea).
While Element.Label as the documentation says is takes the context element & embed in a label tooltip, basically whatever element you use, applying .label will embed it inside a rectangle

How to draw text fitting in a given rectangle on a canvas?

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.

How to generate a Color Sequence in javascript?

I have to display a number whose color changes from Red to Green uniformly as the value of the number decreases.
Is there any way to generate the font color of that number according to the value ?
Decreasing number equals red to green, I'd guess?
Why not make it simple, start out with your all red #FF0000, and work yourself down
to green at #00FF00?
Between the two there are FF*FF (256*256 = 65536) steps; adapt this to your needs and the JavaScript needed to get color should be simple.
ColorCalc - Nice tool for playing with/understanding hex v colors
I would approach this using CSS. I would create a set of styles, in the gradients of the colours that you need. Then using javascript I would apply the style which matched the number.
This way you can seperate your presentation, structure and js logic from each other, whilst keeping your js simple :)

Categories