FabricJS 自由绘图在触摸屏(iOS/Android)失效的完整解决方案

11次阅读

FabricJS 自由绘图在触摸屏(iOS/Android)失效的完整解决方案

fabricjs 的 `freedrawingbrush` 在桌面端正常,但在移动设备上无法响应触摸事件,根本原因在于默认构建版本未启用触摸交互模块(如 `Event.js` 和 `interaction`),需手动启用手势支持或升级至 v5+ 并配置正确构建。

FabricJS 默认的 cdn 构建(如 v4.0.0-beta.12)为减小体积,移除了移动端必需的触摸事件处理模块(Interaction + Event.js),导致 isDrawingMode = true 在 ios/android 上完全无响应——此时触摸 canvas 仅触发浏览器默认行为(如页面滚动),而非画笔事件。

✅ 正确解决方案(三步走)

1. 升级至 FabricJS v5.0.0 或更高版本(推荐)

v5+ 已重构触摸事件系统,原生增强对 pointer Events 和多点触控的支持,并修复了大量移动端兼容性问题(如 #6980)。使用官方 CDN:

⚠️ 注意:v5+ 中 freeDrawingBrush 默认启用 enablePointerEvents: true,但仍需确保 canvas 容器阻止默认触摸行为。

2. 主动禁用页面滚动干扰

canvas 容器上添加 css 并监听 touchstart 阻止冒泡:

并在 JS 初始化后添加:

const canvas = new fabric.Canvas('c', {   // v5+ 关键配置:显式启用指针事件   enablePointerEvents: true,   // 可选:提升触摸响应灵敏度   perPixelTargetFind: true,   targetFindTolerance: 4 });  canvas.freeDrawingBrush.width = 5; canvas.isDrawingMode = true;  // 防止触摸 canvas 时页面滚动(iOS/Android 通杀) document.getElementById('c').addEventListener('touchstart', (e) => {   e.preventDefault(); }, { passive: false });  // 清空按钮逻辑保持不变 document.getElementById('clear').addEventListener('click', () => canvas.clear());

3. (可选)定制构建(适用于 v4 且无法升级场景)

若必须使用 v4.x,请前往 FabricJS Build Tool,勾选 Interaction、Event、Gesture 模块,生成自定义 fabric.min.js 替换 CDN 链接。

? 验证要点

  • ✅ touch-action: none 必须作用于 canvas 或其父容器;
  • ✅ passive: false + e.preventDefault() 是阻止滚动的关键;
  • ✅ 使用 fabric.Canvas 构造函数传参配置 enablePointerEvents: true(v5+);
  • ❌ 避免使用已废弃的 canvas.calcOffset() 手动修正坐标(v5+ 已自动处理)。

升级至 v5.3.1 并按上述配置后,自由绘图将在 iphoneipad、主流 Android 设备上稳定工作,支持单指绘制、双指缩放(若启用)及压感笔(部分设备)。建议始终以 FabricJS 官方移动端示例 为基准校验环境。

text=ZqhQzanResources