You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fabric.js IText交互异常:可移动但无法编辑、缩放及旋转

问题:Fabric.js 5.3.0中单个IText无法编辑、缩放/旋转,成组后恢复正常

在Vue.js + TypeScript + Vite项目中使用Fabric.js 5.3.0,添加的单个IText仅能移动,无法触发编辑、缩放或旋转交互;但将多个文本选中成组后,每个文本又能正常进行所有交互操作。已配置相关属性但问题依旧,现贴出代码寻求原因:

useCanvas组合式函数

import { fabric } from 'fabric'
import { ref, Ref } from 'vue'
import { useElementSize } from '@vueuse/core'

const MIN_CANVAS_HEIGHT = 500

export function useCanvas(
  canvasRef: Ref<HTMLCanvasElement | null>,
  canvasContainerRef: Ref<HTMLElement | null>,
  minHeight = MIN_CANVAS_HEIGHT,
) {
  const canvas = ref<fabric.Canvas | null>(null)

  const { width: containerWidth, height: containerHeight } =
    useElementSize(canvasContainerRef)

  const init = () => {
    canvas.value = new fabric.Canvas(canvasRef.value, {
      width: containerWidth.value,
      height: minHeight,
    })
  }

  const addText = (value: string, isEditable = true) => {
    if (!canvas.value) return

    const text = new fabric.IText(value, {
      left: 50,
      top: 50,
      fill: '#000000',
      fontFamily: 'Arial',
      fontSize: 24,
      fontWeight: 'normal',
      editable: isEditable,
      centeredRotation: true,
      padding: 10,
    })

    // 移除非等比缩放控件
    text.setControlsVisibility({
      mt: false,
      mb: false,
      ml: false,
      mr: false,
    })

    canvas.value.add(text)
  }
}

return {
    canvas,

    init,
    addText,
  }

Vue组件代码

Template

<template>
  <div ref="editorContainerRef" class="image-editor">
    <canvas ref="editorCanvasRef" class="image-editor__canvas" />
     <button class="button" type="button" @click="handleTextAdd">
      <span>{{ 'add text' }}</span>
    </button>
  </div>
</template>

Script

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useCanvas } from './composables'

const DEFAULT_TEXT = 'Your unique signature'
const editorContainerRef = ref<HTMLElement | null>(null)
const editorCanvasRef = ref<HTMLCanvasElement | null>(null)

const canvasInstance = useCanvas(editorCanvasRef, editorContainerRef)

const { init, addText } = canvasInstance

const handleTextAdd = () => {
  addText(DEFAULT_TEXT)
}

onMounted(() => {
  if (!editorCanvasRef.value) return

  init()
})
</script>

原因及解决方案

核心问题:useCanvas函数的return位置错误

useCanvas组合式函数中,return语句写在了函数外部,导致组件无法正确获取到init和addText的有效引用。表面上能调用addText添加文本,但Fabric.js画布实例的交互事件绑定出现隐性异常——单个文本的交互逻辑未被正确注册;而成组后Fabric的组交互逻辑覆盖了单个元素的异常,因此成组后功能恢复正常。

修复步骤

  1. 将return语句移到useCanvas函数内部,确保所有导出的方法和变量都在函数作用域内:
export function useCanvas(
  canvasRef: Ref<HTMLCanvasElement | null>,
  canvasContainerRef: Ref<HTMLElement | null>,
  minHeight = MIN_CANVAS_HEIGHT,
) {
  const canvas = ref<fabric.Canvas | null>(null)

  const { width: containerWidth, height: containerHeight } =
    useElementSize(canvasContainerRef)

  const init = () => {
    canvas.value = new fabric.Canvas(canvasRef.value, {
      width: containerWidth.value,
      height: minHeight,
    })
  }

  const addText = (value: string, isEditable = true) => {
    if (!canvas.value) return

    const text = new fabric.IText(value, {
      left: 50,
      top: 50,
      fill: '#000000',
      fontFamily: 'Arial',
      fontSize: 24,
      fontWeight: 'normal',
      editable: isEditable,
      centeredRotation: true,
      padding: 10,
    })

    text.setControlsVisibility({
      mt: false,
      mb: false,
      ml: false,
      mr: false,
    })

    canvas.value.add(text)
  }

  // 将return移入函数内部
  return {
    canvas,
    init,
    addText,
  }
}
  1. 额外检查项:
    • 确保canvas元素和容器未设置pointer-events: none,避免遮挡交互
    • IText编辑需要双击触发,确认操作方式正确

内容的提问来源于stack exchange,提问作者mark woyshvillo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:45:02