A JavaScript library for creating multiline SVG <text>
elements. Works seamlessly alongside SVG manipulation libraries such as Snap.svg and D3.
Quick example:
import SvgText from 'svg-text';
// Will render a multiline <text> element into the document's first SVG element.
const text = new SvgText({
text: 'Lorem ipsum dolor <a href="http://wsj.com">sit amet</a>, consectetur adipiscing elit.',
element: document.querySelector('svg'),
maxWidth: 100,
textOverflow: 'ellipsis',
});
console.log(text.bounds);// { x: 0, y: 0, width: 100, height: 20 }
console.log(text.lines);// 2
console.log(text.text);// Reference to the SVG <text> element
To import into a client-side that is compiled with Webpack or another module bundling tool:
npm install svg-text --save
import SvgText from 'svg-text';
const text = new SvgText({options});
It can also be used directly in the browser, in which case it will be available as window.SvgText.default
:
<script src="svg-text.js"></script>
<script>
var SvgText = SvgText.default;
var text = new SvgText(options);
</script>
Compiling and testing are both enabled from the command line. To compile:
webpack
or (to watch):
npm run watch
...which is the same as:
webpack --watch
To run the demo:
npm run demo
To run unit tests:
npm run test
SvgText must be instantiated with an options object as a parameter. This options object has one property that is mandatory: text
.
string
The text to render into the text
element.
SVG element
The element that the text
element will be appended to. If not set, svg
element will be used.
SVG element
If not set, it will be created and appended to document.body
. It used as a container for the text
and style
elements and for namespacing.
number
Defaults to 0
for both properties.
number
Defaults to 'auto' for both properties.
number
Defaults to 'auto' for both properties.
number
Constrains the overall width or height, including the margin. For example, if the outerWidth is set to 100 and the margin is set to 10, then the width of the actual text will be constrained to 80 pixels. Defaults to 'auto' for both properties.
number
If not set, possible lines of text are unlimited.
string
Values: "left", "center", "right". Defaults to "left". Relative to options.x
, so if the value is "right" then the text will appear to the left of x, if "center" then it will appear centered over x, and if "left" then it will appear to the right of x.
string
Values: "top", "middle", "bottom". Defaults to "top". Relative to options.y
, so if the value is "bottom" then the text will appear above y, if "middle" then it will appear centered vertically over y, and if "top" then it will appear below y.
string
Values: "ellipsis", "clip", or a custom value. A string that is appended to the text if the text overflows the size constraints. "ellipsis" will result in "…" and "clip" in an empty string (""). Examples:
options.textOverflow = 'ellipsis';
options.textOverflow = ' »';
string
An optional selector that will be prefixed to all style selectors to serve as a namespace so that custom styling will apply only to a specific scope. Default is "svg[data-svgtext="[unique id]"]", where "unique id" is set automatically by SvgText. Example:
options.selectorNamespace = 'svg#mySvg';
string
An optional class name to attach to the text
element. This will be used for custom styling. Default is "svg-text".
options.className = 'demo';
object
Custom styles to apply to the text
element. Note that because the text
element is an SVG and not an HTML element, "fill" and not "color" is the correct property to use to color text. Example:
options.style = { fill: 'red', font-family: 'serif', };
HTMLElement
A style
element into which custom styles will be written. By default, SvgText will use the first style
element found inside a container svg
or, if no style
element exists, create one. Example:
options.style = document.querySelector('svg#mySvg style');
object
Attributes to attach to the text
element. Example:
options.attrs = { 'data-foo': 'bar' };
object
Attributes to attach to a background rect
element. If not specified, no rect
will be drawn. If "x" or "y" is defined, then these values will be added to the SvgText instance's x and y values. In other words, rect.x or rect.y will be treated as offsets or relative positioning values. If "width" or "height" are defined, these values will override any width or height set by the SvgText instance. Example:
options.rect = {
fill: '#9cf',
rx: 10,
ry: 10,
x: 15
};
number|string
An optional value that will add space inside of a background rect
or text
(if no rect
is drawn). Examples:
options.padding = 10;
options.padding = '15 20';
options.padding = '10px 5px 15px 20px';
number|string
An optional value that will add space outside of a background rect
or text
(if no rect
is drawn). Examples:
options.margin = 10;
options.margin = '15 20';
options.margin = '10px 5px 15px 20px';
Read/write. The container svg
element into which SvgText instances will be appended and in which a style
element will be found or created if one is not explicitly defined.
Read/write. The style
element into which styles for SvgText instances will be written.
Writes CSS styles into a style
element. It takes two mandatory arguments and one options argument:
selector
The CSS selector (appended to selector for the containersvg
).css
A JavaScript object of styles to write.style
Thestyle
element to write the styles into. If not defined, the value ofSvgText.style
will be used. Example:
SvgText.writeStyle('text#myText', { fill: 'red' });
Result:
<style>
svg[data-svgtext="1"] text#myText { fill: red };
</style>
Prepares a text
element for opening in Adobe Illustrator (tested in CS6 and CS2014), with the correct font, weight, style, etc. It takes three arguments:
textWeb
A text element that serves as a model.textAi
A text element that will be transformed.postScriptFontName
A PostScript font name that Illustrator will recognize. Example:
const svg = document.querySelector('svg');
const text = new SvgText({
text: 'Hello, world!',
element: svg,
style: {
fontFamily: 'Helvetica',
fontWeight: 'bold',
},
});
const svgForAi = svg.cloneNode(true);
const el1 = svg.querySelector(`text[ai-id="${text.uid}"]`);
const el2 = svgForAi.querySelector(`text[ai-id="${text.uid}"]`);
SvgText.forIllustrator(el1, el2, 'Helvetica-Bold');
// Now `svgForAi` can be opened in Illustrator and the text element will render
// correctly with Helvetica Bold.
Utility methods used by SvgText and exposed because they may be useful in other contexts. To import into a project build with modules:
import { SvgUtil } from 'svg-text';
To use directly in a web browser:
<script src="svg-text.js"></script>
<script>
var SvgUtil = SvgText.SvgUtil;
var prop = SvgUtil.toJs('font-size'));
</script>
Converts a CSS-style property name to a JavaScript-compatible property name. Example:
const prop = SvgUtil.toJs('font-size');
console.log(prop); // 'fontSize'
Converts a JavaScript-compatible property name to a CSS-style property name. Example:
const prop = SvgUtil.toCss('fontSize');
console.log(prop); // 'font-size'
Copies an object and returns the copy with keys transformed to the desired style, either 'js' or 'css'. Default style is 'css'. In addition, it adds 'px' to the values of font-size
and line-height
and properties if the original values are raw numbers.
const obj = { 'font-size': '12', 'background-color': 'red' };
const a = SvgUtil.normalizeKeys(obj, 'js');
console.log(a); // { fontSize: '12px', backgroundColor: 'red' }
const b = SvgUtil.normalizeKeys(a);
console.log(b); // { 'font-size': '12px', 'background-color': 'red' }
Creates an SVG element with the namespace http://www.w3.org/2000/svg
. Example:
const attrs = { width: 100, height: 100, rx: 5, ry: 5 };
const el = SvgUtil.createElement('rect', attrs);
// <rect width="100" height="100" rx="5" ry="5"/>
Returns true
is value is both a number (not NaN
) and is >= 0.
Returns the minimum numeric value amongst the arguments, or else "auto".
console.log(SvgUtil.minNum(5, 10, -10)) // 5
console.log(SvgUtil.minNum(-5, -10)) // 'auto'
Returns the maximum numeric value amongst the arguments, or else "auto".
console.log(SvgUtil.minNum(5, 10, -10)) // 10
console.log(SvgUtil.minNum(-5, -10)) // 'auto'
If value is not a positive number, returns altNum instead.
console.log(SvgUtil.autoNum('auto', 5)); // 5
console.log(SvgUtil.autoNum(10, 5)); // 10
console.log(SvgUtil.autoNum(-5, 5)); // 5
Transforms value into an array with 4 numbers.
console.log(SvgUtil.toArrayLen4(10)); // [10, 10, 10, 10]
console.log(SvgUtil.toArrayLen4(undefined)); // [0, 0, 0, 0]
console.log(SvgUtil.toArrayLen4(null)); // [0, 0, 0, 0]
console.log(SvgUtil.toArrayLen4('10px 20px')); // [10, 20, 10, 20]
console.log(SvgUtil.toArrayLen4("10% 20rem")); // [10, 20, 10, 20]
console.log(SvgUtil.toArrayLen4("10px 20px 15px")); // [10, 20, 15, 20]
Initial release.
Simplify style options and add an optional option: "svg".
Fix bug when writing className to the text
element.
For selectorNamespace, use id
if present before data-svgtext
.
Add writeStyle static method.
Fix bug in setting SVG ID.
Write nodes instead of using innerHTML
.
Fix demo on older Android devices.
Solve bug: non-closing inline tags.
- Add support for right-to-left languages.
- Implement unit testing on all applicable code.
Special thanks to Elliot Bentley for a ton of great feedback.