如何使用Fabric.JS实现Canvas文本沿圆弧/圆形弯曲并通过滑块调节弧度
Fabric JS 弧形/圆形弯曲文本实现方案
Fabric JS 未内置弧形文本组件,可通过自定义扩展类实现字符沿圆弧排布的效果,具体实现如下:
1. 自定义弧形文本扩展类
// 自定义弧形文本类 fabric.CurvedText = fabric.util.createClass(fabric.Object, { type: 'curved-text', initialize: function(text, options) { options || (options = {}); this.text = text; this.fontSize = options.fontSize || 50; this.fill = options.fill || '#000'; this.fontFamily = options.fontFamily || 'Arial'; this.radius = options.radius || 200; // 圆弧半径,越小弧度越大 this.spacing = options.spacing || 2; // 字符间距 this.callSuper('initialize', options); this._calcDimensions(); }, _calcDimensions: function() { const tempCanvas = document.createElement('canvas'); const tempCtx = tempCanvas.getContext('2d'); tempCtx.font = `${this.fontSize}px ${this.fontFamily}`; this.charWidths = this.text.split('').map(c => tempCtx.measureText(c).width + this.spacing); this.totalWidth = this.charWidths.reduce((a, b) => a + b, 0); this.angleRange = (this.totalWidth / (Math.PI * this.radius)) * 180; // 总占角度 this.set('width', this.radius * 2); this.set('height', this.radius * 2); }, _render: function(ctx) { ctx.save(); ctx.font = `${this.fontSize}px ${this.fontFamily}`; ctx.fillStyle = this.fill; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; let currentAngle = -this.angleRange / 2; // 从中间向左开始排布 for (let i = 0; i < this.text.length; i++) { const char = this.text[i]; const charWidth = this.charWidths[i]; const angleRad = currentAngle * Math.PI / 180; ctx.save(); ctx.translate(this.radius * Math.cos(angleRad), this.radius * Math.sin(angleRad)); ctx.rotate(angleRad + Math.PI / 2); // 字符沿圆弧切线方向旋转 ctx.fillText(char, 0, 0); ctx.restore(); // 计算下一个字符的角度 currentAngle += (charWidth / (Math.PI * this.radius)) * 180; } ctx.restore(); }, // 更新弧度(调整半径) setRadius: function(newRadius) { this.radius = Math.max(50, newRadius); // 最小半径限制,避免字符重叠 this._calcDimensions(); this.dirty = true; } }); // 支持从JSON反序列化(可选) fabric.CurvedText.fromObject = function(object, callback) { return callback(new fabric.CurvedText(object.text, object)); };
2. 替换原有文本实例
将你原有的IText替换为CurvedText实例即可生成弧形文本:
// 替换原来的IText实例 const curvedText = new fabric.CurvedText('Lorem Ipsum', { fill: 'black', fontSize: 50, radius: 250, // 初始半径,值越小弧度越大 id: 'text' }); canvas.add(curvedText); canvas.centerObject(curvedText); canvas.requestRenderAll();
3. 滑块调整弧度实现
HTML部分 新增范围输入控件
<!-- 范围输入滑块,min越小弧度越大,max越大弧度越平 --> <input type="range" id="radiusSlider" min="50" max="500" value="250">
JS部分 监听滑块变化
const slider = document.getElementById('radiusSlider'); slider.addEventListener('input', function(e) { const newRadius = parseInt(e.target.value); curvedText.setRadius(newRadius); canvas.centerObject(curvedText); // 调整后保持居中 canvas.requestRenderAll(); });
效果调整说明
- 滑块的
min值越小,对应圆弧半径越小,文本弧度越大 - 滑块的
max值越大,对应圆弧半径越大,文本越接近平直 - 若要实现文本向下弯曲的效果,修改
_render方法中字符的旋转角度偏移量即可,将ctx.rotate(angleRad + Math.PI / 2)调整为ctx.rotate(angleRad - Math.PI / 2)即可反转弯曲方向 - 如果需要可编辑的弧形文本,可以监听画布双击事件,临时将弧形文本替换为IText供用户编辑,编辑完成后再重新生成CurvedText实例即可
内容的提问来源于stack exchange,提问作者Faizan
相关产品推荐
相关产品推荐

