Designing with text
-
Hello, I'm currently starting to work with text to create 2d effects. I thought I could isolate each letter then translate/rotate/scale it as needed, but apparently the function that makes the paths from the vectorText data doesn't return one path by letter but sometimes more. Apparently I need to change my code and get the path for each letter separately.
Here's what I did :
function main() { const jscad = require('@jscad/modeling') const { vectorText } = jscad.text const { geom2, path2 } = jscad.geometries const { align, rotateX, rotateZ } = jscad.transforms const { arc } = jscad.primitives const { colorize } = jscad.colors function texte (ch) { const outlines = vectorText(ch); const segmentToPath = (segment) => { return path2.fromPoints({close: false}, segment) } const paths = outlines.map((segment) => segmentToPath(segment)) return paths } const t1 = texte("012345"); const t2 = align({grouped:true}, t1); const nbL = t2.length; let t3 = []; t2.forEach((p, index) => { t3.push(rotateZ(index/nbL, p)); }); console.log(t3) return t3 } module.exports = { main }
On the snapshot the 4 is apparently made of 2 paths, and the console output shows that there are 7 paths for 6 characters.What I would like to do is to have curve that could be handled by parameters, and then the letters will follow that curves, first curve for the placement, second for the scale, I hope that it will be possible using Bezier.
-
@hrgdavor That would be great. For the moment I'm certainly going to try to do the same thing using svg into vanilla js.
-
@gilboonet I have on my list adding better support for ttf fonts, google fonts, but it will be some time until I get to it. There is also a bug in JSCAD bezier svg handling, that caused some of fonts to display differently than originally designed.
-
I didn't take care that text vectors are only line segments, so they won't produce nice designs when curves will be needed. So I will try at one moment of this project to use curves for my text output, but it's still early for that.
-
@z3dev Thank you for the link to the project, looks promising.
-
For those looking for support for fonts, there's a little library that can be used in projects.
-
@hrgdavor I'm trying to create small scripts to easily create design from text, just like those you can do with Inkscape using path effects, or the very old WordArt from MS Word. The main weakness of using JSCAD for that is that for the moment it is not possible to choose a font that is installed into the pc as .ttf, I'm starting to look at this file format to see it I can use it directly to use its vectors.
-
@gilboonet VectorChar seems to work better, so you have a solution Please share results of what you are aiming to create.
-
@hrgdavor I think I understand your statement, first rotate then translate, but for this example I didn't start from a curve, so I didn't have translation coordinates.
-
Here is the result using VectorChar instead of VectorText
function main() { const jscad = require('@jscad/modeling') const { vectorText, vectorChar } = jscad.text const { geom2, path2 } = jscad.geometries const { align, translateX, rotateZ, center } = jscad.transforms const { arc } = jscad.primitives const { colorize } = jscad.colors const { measureAggregateBoundingBox } = jscad.measurements //const { union } = jscad.booleans function lettre (ch) { const outlines = vectorChar(ch); const segmentToPath = (segment) => { return path2.fromPoints({close: false}, segment) } const paths = outlines.segments.map((segment) => segmentToPath(segment)) return paths } let t = "MAKE IT REAL"; let t1 = t.split(""); let t2 = []; let x = 0; let nbL = 0; t1.forEach((l, index) => { if (l == ' ') { x += 10; } else { nbL++; let L = lettre(l); let b = measureAggregateBoundingBox(L); if (index == 0) { t2.push(L); x = b[0][1]; } else { let b = measureAggregateBoundingBox(t2); x+= b[1][1] t2.push(translateX(x, L)); } } }); let t3 = []; t2.forEach((p, index) => { t3.push(rotateZ(Math.PI*index/(nbL-1), p)); }); return [ t2 , colorize([0,1,0], t3) ]; } module.exports = { main }
Now I can start using control curves.
-
@hrgdavor Thank you, the only problem seems to be the fact that a character can have more than one segment and there is no way to know it with VectorText, so I'm doing it with VectorChar, almost done. About bezier, I hope that bezierAt() and tangentAt() could give the data I need, I prefer to avoid using librairies whenever possible.
-
@gilboonet taking a quick glance at the screenshot, you would not have issues with "4" if the sequence of transformations is rotation first, then translation. Using bezier is ok, but I am not sure there is anything to directly get value you need from bezier control points. But there are few bezier libs in JS that you could use to do whatever you might need.