Is there a way to curve / arc text using CSS3 / Canvas
I'm trying to make a curved text effect using CSS3, HTML Canvas, or even SVG (see image below for example)? Is this possible? If so, how can I achieve this effect?
Update: To clarify: The text that will be style开发者_运维百科d this way will be dynamic.
SVG supports text-on-a-path directly, though it does not 'bend' the individual glyphs along the path. Here's an example of how you create it:
...
<defs>
<path id="textPath" d="M10 50 C10 0 90 0 90 50"/>
</defs>
<text fill="red">
<textPath xlink:href="#textPath">Text on a Path</textPath>
</text>
...
You can certainly do it with canvas, try out this code as an example:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Testing min-width and max-width</title>
<style type="text/css">
</style>
</head>
<body>
<canvas id="cnv"></canvas>
<script type="text/javascript" charset="utf-8">
cnv = document.getElementById("cnv");
cnv.width = 500;
cnv.height = 300;
ctx = cnv.getContext("2d");
ctx.font = "bold 12px sans-serif";
text = "abcdefghijklm"
for (i = 0; i < text.length; i++) {
ctx.fillText(text[i], 300, 100);
ctx.rotate(0.1);
}
</script>
</body>
</html>
It doesn't do it exactly right, but I'm certain you'll manage to tweak it to your likening ;)
You can do it using some CSS, however I'm sure you won't get it running on IE any time soon. On the other hand, the cool thing is that the text is selectable :D
.num1 {
-webkit-transform: translate(0px, 30px) rotate(-35deg);
}
.num2 {
-webkit-transform: translate(0px, 25px) rotate(-25deg);
}
.num3 {
-webkit-transform: translate(0px, 23px) rotate(0deg);
}
.num4 {
-webkit-transform: translate(0px, 25px) rotate(25deg);
}
.num5 {
-webkit-transform: translate(0px, 30px) rotate(35deg);
}
span {display: inline-block; margin: 1px;}
<div style="width: 300px; height: 300px; margin: 50px auto">
<span class="num1">a</span><span class="num2">b</span><span class="num3">c</span><span class="num4">d</span><span class="num5">e</span>
</div>
It's not a pure CSS solution but CircleType.js works great for arced text.
http://circletype.labwire.ca/
There is a jQuery Plugin to curve text using CSS3 called arctext.js. It's pretty good and has a range of configuration options. I guess it won't work on IE8 but I guess most CSS3 thing don't!
There's also a demo page with some example of it in action here.
This tutorial shows you exactly how to do it using HTML5 and canvas. One of the other answers presented a similar idea, which is to use the canvas.rotate method. This one also uses canvas.translate.
The full code from the tutorial is:
function drawTextAlongArc(context, str, centerX, centerY, radius, angle) {
var len = str.length,
s;
context.save();
context.translate(centerX, centerY);
context.rotate(-1 * angle / 2);
context.rotate(-1 * (angle / len) / 2);
for (var n = 0; n < len; n++) {
context.rotate(angle / len);
context.save();
context.translate(0, -1 * radius);
s = str[n];
context.fillText(s, 0, 0);
context.restore();
}
context.restore();
}
var canvas = document.getElementById('myCanvas'),
context = canvas.getContext('2d'),
centerX = canvas.width / 2,
centerY = canvas.height - 30,
angle = Math.PI * 0.8,
radius = 150;
context.font = '30pt Calibri';
context.textAlign = 'center';
context.fillStyle = 'blue';
context.strokeStyle = 'blue';
context.lineWidth = 4;
drawTextAlongArc(context, 'Text along arc path', centerX, centerY, radius, angle);
// draw circle underneath text
context.arc(centerX, centerY, radius - 10, 0, 2 * Math.PI, false);
context.stroke();
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="578" height="250"></canvas>
</body>
</html>
You can use SVG with <textPath>
like this:
function updateMessage(str) {
document.getElementById("MyMessage").textContent = str;
}
<button onClick="updateMessage('The text has changed');">Change the text</button>
<svg viewBox="0 0 1000 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="CurvedPath"
d="M 0 150 Q 325 50 650 150 " />
</defs>
<text font-size="54" x='325' y='50' text-anchor="middle" fill="darkgreen" font-family=Arial,Helvetica style="text-shadow: 2px 2px 3px gray;">
<textPath id='MyMessage' xlink:href="#CurvedPath">THIS TEXT IS CURVED</textPath>
</text>
</svg>
<embed width="100" height="100" type="image/svg+xml" src="path.svg">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<path id="textPath" d="M10 50 C10 0 90 0 90 50"/>
</defs>
</svg>
</embed>
I used the tutorial mentioned above (by Simon Tewsi) to write a better solution, regarding the kerning issue. Uses no library, pure JS.
See it at http://jsfiddle.net/fidnut/cjccg74f/
function drawTextAlongArcInside(ctx, str, font, color, radius, angle, centerX, centerY, wspace)
Note: SO is demanding that I put all the code from JSFiddle in here too. I don't think this is wise, too much code, so I am adding only the name of the function.
There is also transform: skew(x, y)
, which does not use canvas.
精彩评论