Word Wrap in Raphael JS / SVG - javascript

How do you get words to wrap inside a box in RaphaelJS? Or in browser-based SVG in general?
I found this thread on it, but it doesn't make any sense. They say to use "widthToCharNum" but as far as I can tell, this thread is the only place those words have ever been used on the internet. They suggest using a "width" attribute, but this has no effect.

Text-wrapping is not built into Raphael or the SVG spec. Period. Coming from the HTML world, I found the absence of text wrapping pretty shocking.
However, you can do it yourself without too much difficulty. See this question for details and an example. Unfortunately, you have to burn some client-side cycles to make it work dynamically.

The svg.js library has a svg.textflow.js plugin. It's not ultra fast but it does the trick. It even stores overflowing text in a data attribute so you can use it to create continuously flowing columns. Here the text flow example page.

The tspan tag can give the illusion of word wrap, but there is no built in word wrap functionality.
The tspan tag is identical to the text tag but can be nested inside text tags and inside itself. Coupled with the 'dy' attribute this allows the illusion of word wrap in SVG 1.1. Note that 'dy' is relative to the last glyph (character) drawn. There is a tutorial on how to use tspan at http://tutorials.jenkov.com/svg/text-element.html.
The article at http://www.xml.com/pub/a/2002/09/11/quint.html might also be useful.

I know it's a little belated now, but you might be interested in my Raphael-paragraph project.
It's a small library that allows you to create auto-wrapped multiline text with maximum width and height constraints, line height and text style configuration. It's still quite beta-ish and requires a lot of optimization, but it should work for your purposes.
Usage examples and documentation are provided on the GitHub page.

Related

SVG - how to set text line-height

It seems line-height is the one CSS property absent from svg text. The best resource on SVG I have found is: Jenkov.com SVG Tutorials and there is no mention of it, neither could I find mention of it on MDN.
So if anyone can shed definitive light on this or share a technique. I am basically interested in the spacing between lines of text that wrap, not independent text elements.
Thanks
SVG 1.1 (officially) only supports single line text, hence no line-height setting.
I've just tried creating a block of text in Inkscape, and it's using a flowRoot element (containing a flowPara element with the actual text in it). Then the flowRoot element actually has line-height assigned to it (in %).
I don't know how wide-spread support for that way is, since it used to be part of SVG 1.2. You might also want to have a look here: Auto line-wrapping in SVG text

How to manually manage text wrapping in HTML

When working with designers, they often are very picky about word wrap in the completed HTML page. Assuming that I'm working on a fixed layout (not-responsive), and the designer does not like the way text is wrapping, I can:
Adjust padding-right
Add manual <br> to break a line
Add manual to avoid a break (typically for orphan control)
(In my case, I'm designing for a specific mobile device, so I know the screen size, and can control the fonts. Also, making the designers happy is non-negotiable.)
The issue that I keep running into is that the text or layout will be updated later, and relics of this specific word wrap concern, which no longer apply, introduce issues we then need to fix.
So I'm wondering if anyone can suggest a strategy that:
Allows completely arbitrary control of word wrap in individual
cases; but,
Doesn't make everything so hard to maintain going forward
I'm open to procedural, algorithmic (javascript), or CSS-oriented suggestions.
Here is the strategy I chose. Time will tell how maintainable it is.
Do not edit the text content
Fix wrapping by adding CSS classes that change the way the text flows, but do not use attributes like width or padding that are already being used to control layout
Specifically:
.tighten {
letter-spacing: -0.011em;
}
.loosen {
letter-spacing: 0.011em;
}
.hyphenate {
-webkit-hyphens: auto;
-webkit-hyphenate-limit-after: 4;
-webkit-hyphenate-limit-before: 4;
}
It turns out that these imperceptible changes in spacing can make a huge difference in wrap. I actually have several variations of these classes, so I can try progressively more or less space to fix wrapping.
In severe cases, I use the hyphenate class (I'm only targeting iOS in this case).
In a future revision, when we change the text in a div, we can just remove the tighten, loosen, or hyphenate class from that div, and see if there are any wrap issues we need to correct. If there are, we go through the original trial-and-error of seeing which class gives the best look.
Use <pre> tag so you can insert preformated text.

Placing text characters w/ javascript without using a div

I am going to be placing a lot of characters and words all over a web page using absolute positioning. I could put each character in it's own div, then set it's position. Is there any other way to place an individual word or character on a page without putting it in a div (to save memory). I figure not (which is fine), but if there is another way I'd like to explore it.
Try using html canvas. It will allow you to draw text to it at any position you want. https://developer.mozilla.org/en/Drawing_text_using_a_canvas
You can use tags like <b> and set their css to font-weight: normal;.
If you are going to be worry about the DOM tree size, you can go ahead with this way of implementation. But what is the use of implementing this? There are plenty of jQuery and JavaScript snippets available right?
You will need some type of html tag surrounding the text or else you will have no way to apply CSS.
This cannot be done in the manner you are imagining. Anonymous boxes cannot be manipulated and, generally speaking, do not carry traditional properties. You will have to use a wrapper tag.
you can read more here: http://www.w3.org/TR/CSS2/visuren.html#anonymous-block-level

Converting html to svg using javascript/jquery

Is there a way to convert an html snippet to svg?
for example:
<b>This is bolded</b>
I want to make an svg document with the html snippet above... is this possible?
I would suggest that you should edit your question to describe the actual use case and goal you are trying to achieve, as directly implementing what you seem to ask for is hard (see below). Some combination of SVG-in-XHTML or XHTML-in-SVG (for example, this) are far more likely to give you want you want.
We can only help you achieve your goals if you tell us your goals instead of asking us help you to solve a particular implementation you thought of to achieve them.
As I mentioned above, There is not an easy way to do what you suggest. In particular, HTML has automatic line wrapping, floating and general positioning concepts, as well as explicit z-indexing, that are not present in SVG.
The following madness would mostly work, however:
Create an iframe or div on your page and set the HTML to your snippet.
Loop through every element and convert wrap a margin:0;padding:0;border:0 span around every word in the text.
Loop through every element (including your created spans) and calculate the absolute position on the page. (jQuery has a method to do this, or you could use the combination of offsetLeft/offsetTop and offsetParent to walk up the positioned tree and calculate it yourself.)
Calculate the equivalent z-index for each element by walking up the tree and using the getComputedStyle() and creating a chain of the local z-index.
For each of these elements, create the equivalent element in SVG with absolute positioning.
Re-sort the SVG elements you created by the hierarchy of z-indices.
Check this html to SVG demo, (using HiQPDF, a commercial product). You can find there code samples for C# and VB.NET. You can convert an URL or a HTML code snippet as you requested.
There are JS libs, that convert html to canvas:
http://html2canvas.hertzen.com/
But until now, I did not found something similar for svg.

One <span> per character in web-based text editor

I'm developing a web-based text editor without any contentEditable, textarea or input things. The biggest portion of my work is to measure widths of text on the left (right) side from the current caret position and moving the caret in the text.
For example when user presse the DOWN key a current left-offset of the caret must be computed and on the line below a character which's position is most similar must be found.
One very convenient way to do is to use one DOM element per character - I can just look at the offsetLeft property. Also, positioning the caret is much easier. Actually, everything is easier.
However I'm very unsure about the performance implications. I have seen this technique (or similar) used on some web-based JavaScript "IDE"s and it works just fine there.
Do you have any hints, tips?
Do you know some other fast way how to measure width of text. I want to avoid putting sections of a line to a DOM element and measuring its width each time as I think it will be much slower.
EDIT: I'm mostly asking about the main fact of EXISTENCE of many dom elements. How to do the measuring is a different thing.
I've seen this done (unfortunately can't find the link now) by using a canvas object and its measureText() method - basically you can ask a canvas "what size would this piece of text be if i rendered it in this style?" and use that to determine your caret position on the surrounding lines. This is performant, but of course it will only work in HTML5-capable browsers, and maybe not all of them.
But frankly this sounds like a big pain in the neck and probably more trouble than it's worth for an in-browser editor :)
You might be interested in this, which is a javascript implementation of the VI text editor. Unfortunately it does use a textarea, however not in the typical manner.

Categories