How to Curve/Arc Text Using CSS3/Canvas

Is there a way to curve / arc / bend only the bottom or top of text using CSS3

If you don't care about browser support, i.e. if this only need to work in modern browser, then you may be able to do this by using SVG.

First, you'll need to create the curved text in SVG. Then you SMIL animate the individual SVG element or CSS animate the individual SVG element.

Draw a Curved text using CSS

It isn't super straightforward, but I suppose it could be done. Take a look at this article: Set Text on a Circle. Not the exact same thing, but same idea. You'd need to do it per character or section of words to do it.

A potentially easier solution would be to use Javascript/jQuery. But I know this doesn't meet your CSS only requirement. Consider looking at ArcText.js as an option if you feel CSS isn't doable for you.

There is also a tool that does this for you: CSS Warp - CSS Text to Path Generator. This would match exactly what you want, and generate the code for you for various browsers. I've never used it before, but seems nearly fool-proof.

Here is an example using CSS Warp. I spent about 5 minutes. It gets you pretty close to what you want, and you can polish it up more. Then just use CSS to add the rest of the styling.
CSS Warp

Curved Menu in CSS

You might be able to do it with canvas. See the answer to Is there a way to curve / arc text using CSS3 / Canvas for a sample. Note that canvas is not supported by IE8 and earlier, but it is otherwise pretty widely supported in modern browsers.

You might also want to look at this tutorial on drawing a sine wave with canvas since the menu in your image is somewhat sine wave shaped.

That's a lot of work though for something like this, though. Instead, you can just make it a big image and use a map element to make an image map.

You could also consturct it out of a series of small images.

Text with arc direction in Canvas, but letters should keep vertical

The tool works by drawing the text normally, slicing it into 1px wide vertical strips, then redrawing those strips with vertical scaling and offset. Knowing how .drawImage() functions helps a lot in making this possible. Changing this algorithm to your needs is a matter of changing how the scaling and offset are calculated.

Two parameters are calculated for each strip: Offset and height. y controls the arc but is used directly to set the target height. h * 0.5 - offsetY / textHeight * y scales and offsets y to produce the offset.

Since y is derived almost directly from sin(), we can use that as the offset instead. The height would remain fixed so we use textHeight for that.

Changing

ctx.drawImage(os, i, 0, 1, textHeight,
i, h * 0.5 - offsetY / textHeight * y, 1, y);

to

ctx.drawImage(os, i, 0, 1, textHeight,
i, y, 1, textHeight);

does the trick.

This is the minimum change necessary. I'll leave it as an exercise for yourself as to how to further clean up the code.

Make text curved with SVG, HTML and CSS for a web page title

First of all you can use text-anchor in combination with pathLength and startOffset to place the text in the middle. Here the the path length is 2, so the start offset is 1 and the anchor is set to "middle".

Second I changed the path a bit; scaled it and placed it in the top of the SVG (the arch hits y=0 in the middle). It is still the same shape. I used dominant-baseline to let the text "hang" under the path.

Now the viewbox can be scaled as well. If it has the height of 5 you can see the entire path, bit if you set it to 3 (second example) the following content will move closer.

An alternative could be to place the SVG as part of the CSS as a background in the content.

svg {
display: block;
}
<svg viewBox="0 0 30 5" xmlns="http://www.w3.org/2000/svg">
<path id="MyPath" fill="none" stroke="red" stroke-width=".1" d="M 0 5 Q 15 -5 30 5" pathLength="2" />
<text class="title is-4" font-size="2" dominant-baseline="hanging" text-anchor="middle">
<textPath href="#MyPath" startOffset="1">
Curved Title
</textPath>
</text>
</svg>
<div style="background:silver">More content</div>


Related Topics



Leave a reply



Submit