Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text on paths #6543

Merged
merged 21 commits into from
Oct 26, 2020
Merged

Text on paths #6543

merged 21 commits into from
Oct 26, 2020

Conversation

asturur
Copy link
Member

@asturur asturur commented Aug 24, 2020

@melchiar This PR contains the progress of text on a path, that i started right now.
i ll push up every time i do a small progress.

closes #729
closes #5900
closes #2544

@asturur
Copy link
Member Author

asturur commented Aug 24, 2020

step 1, we are here:

image

that is not bad, if you look at the commit changes.

@melchiar
Copy link
Member

looking good so far 👍

In having path be a property of text, will the path itself to be styleable (ie. strokes, fills), or will it just be used for text coordinates? (similar to how clipPaths aren't styleable)

@asturur
Copy link
Member Author

asturur commented Aug 25, 2020

image

step 2!

@asturur
Copy link
Member Author

asturur commented Aug 25, 2020

@melchiar let's see where we get, is all yet to be decided. having the path renderable makes things easier for devs, rather than aligning objects.

@emielmolenaar
Copy link

Awesome work! My math skills are a bit meh, but when I see chance to collaborate on this one I will.

@asturur
Copy link
Member Author

asturur commented Aug 25, 2020

Another small improvement.
image

Next thing i would look at is the bounding box.

@asturur
Copy link
Member Author

asturur commented Aug 26, 2020

image

@andrewzolotukhin
Copy link

Looks great!

@stale
Copy link

stale bot commented Sep 11, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale Issue marked as stale by the stale bot label Sep 11, 2020
@stale stale bot closed this Sep 18, 2020
@melchiar melchiar reopened this Sep 18, 2020
@stale stale bot removed the stale Issue marked as stale by the stale bot label Sep 18, 2020
@asturur
Copy link
Member Author

asturur commented Sep 18, 2020

Yeah i have to get back to this, i m really under a train of work lately

@thobn24h
Copy link

Impressive !
@asturur, Have you had any draft document or guideline about this new feature, yet?

@asturur
Copy link
Member Author

asturur commented Sep 28, 2020

Isn't working properly yet. the idea is to get underline/striketrough/overline working and the release for text only, meaning that for Itext and textbox will work badly and is on the dev to not update it.

thereisn't match to say about it, you take a fabric.Path, and you do Text.set('path', myPath) that's it.
No options for now about being over or under the path.

@asturur
Copy link
Member Author

asturur commented Oct 3, 2020

Ok after long time, here i am back.
I changed the implementation to be a measure time more than at render time.
Added support for text decoration.
Now i will write tests and merge as it is, then improve.
Next step is correct bounding box.
Then multi line.

Editing will come later or maybe not come at all, since is really edgy.

@asturur
Copy link
Member Author

asturur commented Oct 3, 2020

This is with underline and overline applied

image

@asturur
Copy link
Member Author

asturur commented Feb 19, 2021

no not yet

@vijaygurjar
Copy link

vijaygurjar commented Feb 24, 2021

Hello
I want to scale path not textbox. After scale how i will get updated path co-ordinates or (path string) and also i want to align text like right,center,left.
Sample fiddle:
https://jsfiddle.net/vijaygurjar/9mtcuzv4/18/

Require output like below:
sample

@billensley
Copy link

billensley commented Feb 24, 2021 via email

@asturur
Copy link
Member Author

asturur commented Feb 24, 2021

@vijaygurjar transforming a fabric path to a scaled path is entirely possible with fabric tools is not something i can explain in a message or an email.
You have to look for transformPoint util and transform each point of the path ( including controls point ).

@fran1990Web
Copy link

Thanks you @asturur for the work.
This solution. Could be apply on Textbox?
Thanks you very much!

@asturur
Copy link
Member Author

asturur commented Mar 4, 2021

Editing still does not work properly.

@fran1990Web
Copy link

Thanks you @asturur. Do you think this could be a new feature to add? Meanwhile I can use it in text :)

@asturur
Copy link
Member Author

asturur commented Mar 4, 2021

yes it will. My priority is RTL support and fixing something in selections interactions

@fran1990Web
Copy link

Thanks! :)

@melchiar
Copy link
Member

melchiar commented Jun 17, 2021

I've just opened a discussion thread for textAlign and startOffset support if anyone cares to provide feedback.
#7128

edit - side has now been added as well

You're welcome to experiment with my work in progress integration of these features:
https://jsfiddle.net/melchiar/vhgtesoy/

image

@billensley
Copy link

billensley commented Jun 17, 2021 via email

@tran-ngoc-phuong-dang
Copy link

Has there been any new progress on this? When will this have support for SVG export?

@melchiar
Copy link
Member

The next release will include additional property support for textAlign, pathStartOffset, and pathSide, along with a util for transforming path data. They're in the current master branch if you want to grab them early, otherwise the next release should be here soon.

No work done yet on svg export though as it hasn't been a priority.

@tran-ngoc-phuong-dang
Copy link

hi. Any news on the svg export for this feature? What's the next update for the textpath?

@melchiar
Copy link
Member

No news on svg yet.

@emielmolenaar
Copy link

emielmolenaar commented Nov 2, 2021

We have been experimenting with text on paths and we use this to properly export text on paths to SVG:

fabric.Text.prototype._wrapSVGTextAndBg = function (textAndBg) {
    var noShadow = true, textDecoration = this.getSvgTextDecoration(this);

    const elements = [
        textAndBg.textBgRects.join(''),
        '\t\t<text xml:space="preserve" ',
        (this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, '\'') + '" ' : ''),
        (this.fontSize ? 'font-size="' + this.fontSize + '" ' : ''),
        (this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : ''),
        (this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : ''),
        (textDecoration ? 'text-decoration="' + textDecoration + '" ' : ''),
        'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >',
    ];

    if (!this.path) {
        elements.push(textAndBg.textSpans.join(''));
    } else {
        /**
         * There is a path, make sure that:
         *
         * 1. A <textpath> surrounds the tspans containing a link to the <path>
         * 2. Every X and Y of every <tspan> is 0
         * 3. The <path> is added
         */
        const id = Date.now() + '-' + Math.random().toString(36).substr(2, 9);

        elements.push('<textPath xlink:href="#path-' + id + '">');
        elements.push(textAndBg.textSpans.join('').replace(/x="[^"]+"/, 'x="0"').replace(/y="[^"]+"/, 'y="0"'));
        elements.push('</textPath>');

        const path = this.path.path
            .map(function (path) {
                return path.join(' ');
            })
            .join(' ');

        elements.push('<path id="path-' + id + '" d="' + path + '" fill="none"></path>');
    }

    elements.push('</text>\n');

    return elements;
}

Although it is a bit hacky (especially the coordinate replacing with regexes), this works for us. Maybe this might be helpful for others.

@mafna-air
Copy link

thank you. Hope there will be official support for svg export soon.

@tran-ngoc-phuong-dang
Copy link

has there been any more progress on this feature? With the SVG export function?

@egemenerd
Copy link

@av01d
Copy link

av01d commented Jun 19, 2023

This looks interesting;

https://stackblitz.com/edit/web-platform-n8kzvg?file=script.js

This does indeed look promising. But it isn't finished yet, you can't move/resize the curved text and the toSVG function doesn't yield results (yet). Hopefully the creator of this code will keep working on it...

@umashankar-pardhi-amla
Copy link

Any update on SVG export? Text on path

@ShaMan123
Copy link
Contributor

If you are using node I can point out a solution

@umashankar-pardhi-amla
Copy link

@ShaMan123 : Yes please

@ShaMan123
Copy link
Contributor

#9185 is what you need, look at the repro in the description for POC

@ShaMan123
Copy link
Contributor

I am not sure about rendering to text though (paths work), you will need to investigate if that is important for you

@umashankar-pardhi-amla
Copy link

@emielmolenaar emielmolenaar : The SVG is rendering, but it's not positioned correctly. Could you explain how you've configured the object, including user selection, scaling, and all? I'd appreciate your help with this.

We have been experimenting with text on paths and we use this to properly export text on paths to SVG:

fabric.Text.prototype._wrapSVGTextAndBg = function (textAndBg) {
    var noShadow = true, textDecoration = this.getSvgTextDecoration(this);

    const elements = [
        textAndBg.textBgRects.join(''),
        '\t\t<text xml:space="preserve" ',
        (this.fontFamily ? 'font-family="' + this.fontFamily.replace(/"/g, '\'') + '" ' : ''),
        (this.fontSize ? 'font-size="' + this.fontSize + '" ' : ''),
        (this.fontStyle ? 'font-style="' + this.fontStyle + '" ' : ''),
        (this.fontWeight ? 'font-weight="' + this.fontWeight + '" ' : ''),
        (textDecoration ? 'text-decoration="' + textDecoration + '" ' : ''),
        'style="', this.getSvgStyles(noShadow), '"', this.addPaintOrder(), ' >',
    ];

    if (!this.path) {
        elements.push(textAndBg.textSpans.join(''));
    } else {
        /**
         * There is a path, make sure that:
         *
         * 1. A <textpath> surrounds the tspans containing a link to the <path>
         * 2. Every X and Y of every <tspan> is 0
         * 3. The <path> is added
         */
        const id = Date.now() + '-' + Math.random().toString(36).substr(2, 9);

        elements.push('<textPath xlink:href="#path-' + id + '">');
        elements.push(textAndBg.textSpans.join('').replace(/x="[^"]+"/, 'x="0"').replace(/y="[^"]+"/, 'y="0"'));
        elements.push('</textPath>');

        const path = this.path.path
            .map(function (path) {
                return path.join(' ');
            })
            .join(' ');

        elements.push('<path id="path-' + id + '" d="' + path + '" fill="none"></path>');
    }

    elements.push('</text>\n');

    return elements;
}

Although it is a bit hacky (especially the coordinate replacing with regexes), this works for us. Maybe this might be helpful for others.

@aswanth6000
Copy link

Screenshot 2024-04-16 223348 How can i add control points like this, like in the middle of the text.

@00cyberghost
Copy link

Screenshot 2024-04-16 223348 How can i add control points like this, like in the middle of the text.

i am also interested in this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

How to Generate Curved Text ? SVG text on path is not working Curve Text Feature [$200]