
什么是环形文字?
搜索相关的图片可以看到

从上面可以得知, 环形文字其实就是文字围绕一个中心点或一个圆形区域(如圆形徽章、硬币、印章、表盘、圆形按钮、图标等)进行布局.
在前端中,如果想要实现这种环形文字,我们可以借助canvas
来实现,也可以用传统的css
来实现。
这边采用的是cavans
来实现
最终效果

完整代码
html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文字环绕</title>
<style>
html,
body {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
canvas {
background: #1a1a1a;
}
</style>
</head>
<body>
<canvas id="canvas" height="800px" width="800px"></canvas>
<script>
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const num = 360
if (!ctx) console.log('上下文对象不存在')
ctx.font = '24px 微软雅黑'
ctx.fillStyle = '#fff'
/**
* @function 环形文本
* @param text 文本
* @params spacing 间距
*/
const circularText = (
text,
spacing,
options = {
x: 400,
y: 400,
radius: 250
}
) => {
const num = 360
for (let index = 0; index < num; index += spacing) {
const startAngle = (Math.PI * index) / 180
const angle = parseFloat(startAngle)
ctx.save()
ctx.beginPath()
ctx.translate(
options.x + Math.cos(angle) * options.radius,
options.y + Math.sin(angle) * options.radius
)
ctx.rotate(Math.PI / 2 + angle)
ctx.font = '24px 微软雅黑'
ctx.fillStyle = '#fff'
ctx.fillText(text, 0, 0)
ctx.restore()
}
}
circularText('/', 3.6)
circularText('+', 10, {
x: 400,
y: 400,
radius: 200
})
circularText('{', 20, {
x: 400,
y: 400,
radius: 150
})
circularText('</>', 30, {
x: 400,
y: 400,
radius: 100
})
const poetry = '桃之夭夭,灼灼其华。之子于归,宜其室家。'
const total = num / 20
// 汉字环绕
for (let index = 0; index < total; index++) {
const text = poetry.charAt(index % total)
const startAngle = (Math.PI * index * 20) / 180
const angle = parseFloat(startAngle)
ctx.save()
ctx.beginPath()
ctx.translate(400 + Math.cos(angle) * 300, 400 + Math.sin(angle) * 300)
ctx.rotate(Math.PI / 2 + angle)
ctx.fillText(text, 0, 0)
ctx.restore()
}
;(function () {})()
</script>
</body>
</html>
实现思路
- 根据间距计算在环上面的位置,以及起始弧度
- 文字按照环形排列
- 对每一个字符,进行旋转
js
const total = num / 20
for (let index = 0; index < total; index++) {
// 计算当前文字所在位置的角度(弧度制)。因为每个文字间隔20度,所以当前角度为`index * 20`度,然后转换为弧度(乘以π除以180)
const startAngle = (Math.PI * index * 20) / 180
// 确保是浮点数,可以省略
const angle = parseFloat(startAngle)
// 在通过sin和cos函数计算 对应的文字点在圆周上面的坐标
ctx.fillText(
'A',
400 + Math.cos(angle) * 300,
400 + Math.sin(angle) * 300
)
}
x=400 + Math.cos(angle) * 300
y=400 + Math.sin(angle) * 300
这个x,y就是文字坐标
公式如下:
js
x = 圆心的x坐标+Math.cos(弧度)*半径
y = 圆心的y坐标+Math.cos(弧度)*半径
最终画出来的效果是这样的

这时候文字字符以及围成一个圆形了
但是文字本身还没有旋转到对应的角度,看起来就很奇怪。
这时候需要用到下面几个方法
-
save()
:用于存储当前绘制状态 -
translate()
:修改当前画布原点,这里要注意 这个方法修改的是整个画布的原点 -
rotate()
:根据画布原点旋转画布 -
restore()
:恢复最近的保存状态
旋转字符的步骤如下: 保存状态->将 字符坐标设置画布原点->旋转画布->恢复到上一次的画布绘制状态
js
ctx.save()
ctx.beginPath()
ctx.translate(400 + Math.cos(angle) * 300, 400 + Math.sin(angle) * 300)
ctx.rotate(Math.PI / 2 + angle)
ctx.fillText(text, 0, 0)
ctx.restore()
之前我们将文本按圆心环绕绘制了,那么这里就按前面获取到的字符坐标设置原点
完整代码如下:
html
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文字环绕</title>
<style>
html,
body {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
canvas {
background: #1a1a1a;
}
</style>
</head>
<body>
<canvas id="canvas" height="800px" width="800px"></canvas>
<script>
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const num = 360
if (!ctx) console.log('上下文对象不存在')
ctx.font = '24px 微软雅黑'
ctx.fillStyle = '#fff'
const total = num / 20
// 汉字环绕
for (let index = 0; index < total; index++) {
const startAngle = (Math.PI * index * 20) / 180
const angle = parseFloat(startAngle)
ctx.save()
ctx.beginPath()
ctx.translate(400 + Math.cos(angle) * 300, 400 + Math.sin(angle) * 300)
ctx.rotate(Math.PI / 2 + angle)
ctx.fillText('A', 0, 0)
ctx.restore()
}
;(function () {})()
</script>
</body>
</html>
画出来的效果就是这样的

结尾
到这里环形文本的实现方式已经结束了,下一篇文章我打算用这些知识实现mdn
文档官网首页的这个效果
