如何通过输入框更新Fabric.js画布生成文本的字号?
实现正确性与优化指导
基础功能正确性
你的代码基本能实现需求:点击生成文本框后,选中它,修改输入框值并触发change事件(回车或失去焦点),文本字号会更新。但存在边界问题和可优化空间。
具体优化点
- 类型转换处理:输入框的值是字符串类型,直接赋值给
fontSize可能引发潜在问题(Fabric.js期望数值类型),需转为数字:sizeFromInput = parseInt(fontsize.value, 10); - 无选中对象的报错防护:如果没有选中任何对象,
canvas.getActiveObject()会返回null,调用.set()会报错,需加判断:const activeObj = canvas.getActiveObject(); if (!activeObj) return; // 额外判断是否为文本类对象,避免给非文本对象设置字号 if (activeObj.type === 'textbox' || activeObj.type === 'text') { activeObj.set("fontSize", sizeFromInput); canvas.renderAll(); } - 事件触发时机优化:
change事件仅在输入框失去焦点或回车时触发,若想实时更新(输入时生效),可改用input事件:$("#fontSize").on("input", () => { // 逻辑同上 }); - jQuery与原生DOM简化混用:既然用了jQuery,无需再用
document.querySelector,直接用jQuery获取值更简洁:const sizeFromInput = parseInt($("#fontSize").val(), 10); - 输入框属性优化:输入框默认值是"1",但生成文本的默认字号是18,建议把输入框默认值改成18保持一致;同时限制输入为正整数,将
type="text"改为type="number"并设置min="1":<input value="18" id="fontSize" type="number" min="1"> - Fabric.js重绘优化:使用
requestRenderAll()替代renderAll(),它会检查是否需要重绘,性能更优:activeObj.set('fontSize', sizeFromInput).requestRenderAll();
优化后的完整代码示例
HTML部分
<input value="18" id="fontSize" type="number" min="1"> <button id="typeTool">生成文本框</button>
JS部分
// 生成文本框 $("#typeTool").click(() => { const textEditable = new fabric.Textbox("ASR Textbox", { width: 500, editable: true, fontFamily: "Delicious_500", left: 100, top: 100, fontSize: 18, fill: "#000", }); canvas.add(textEditable); // 生成后自动选中,方便直接修改字号 canvas.setActiveObject(textEditable); }); // 字号更新事件 $("#fontSize").on("input", () => { const sizeFromInput = parseInt($("#fontSize").val(), 10); // 验证输入是否为有效正整数 if (isNaN(sizeFromInput) || sizeFromInput < 1) return; const activeObj = canvas.getActiveObject(); if (!activeObj || !['textbox', 'text'].includes(activeObj.type)) return; activeObj.set('fontSize', sizeFromInput).requestRenderAll(); });
内容的提问来源于stack exchange,提问作者HungryAlmond
相关产品推荐
相关产品推荐

