有用过fabricjs的吗?有一个还原的小问题?

下面是源码,现在有一个小问题,就是我有一个还源,我想要的的把下面的图片不管怎么操作,点“还原”就重新加载图片显示,现在的问题是我操作过“还原”以后,我再去下面放大缩小操作图片,我发现图片还是以他没还原前的状态显示的,感觉canvas!.on('mouse:wheel', (options) => {})这个操作保存了之前的图片的状态或者说我逻辑上那里没有清除原来的?有看出我逻辑哪里不对的吗???

image.png

<script setup lang="ts">
import { ContentWrap } from '@/components/ContentWrap'
import { ElRow, ElCol, ElButton } from 'element-plus'
import { onMounted, ref } from 'vue'
import { fabric } from 'fabric'

const canvasAll = ref<HTMLDivElement | null>(null)
let canvas: fabric.Canvas | null = null
onMounted(() => {
  if (canvasAll.value) {
    init()
  }
})
const init = () => {
  canvas = new fabric.Canvas('canvas')
  if (canvasAll.value) {
    canvas.setWidth(canvasAll.value.$el.offsetWidth)
    canvas.setHeight(800)
  }
  fabric.Image.fromURL('https://www.chunshu.net/2.png', (img) => {
    canvas!.add(img)
    canvas!.renderAll()
    addScrollListener()
  })
}
const addScrollListener = () => {
  canvas!.on('mouse:wheel', (options) => {
    console.log(options)
    options.e.preventDefault()
    options.e.stopPropagation()
    let pointer: fabric.Point | undefined = options.pointer
    if (options.e.deltaY > 0) {
      canvas!.zoomToPoint(pointer!, canvas!.getZoom() / 1.1)
    } else {
      canvas!.zoomToPoint(pointer!, canvas!.getZoom() * 1.1)
    }
  })
}
const restorex = () => {
  init()
}
</script>

<template>
  <ContentWrap title="Canvas">
    <ElRow>
      <ElCol :span="4" />
      <ElCol :span="4" />
      <ElCol ref="canvasAll" :span="16">
        <ContentWrap class="m-auto">
          <ElButton @click="restorex">还原</ElButton>
          <hr />
          <canvas id="canvas"></canvas>
        </ContentWrap>
      </ElCol>
    </ElRow>
  </ContentWrap>
</template>
阅读 712
avatarAI BotBETA

你的问题在于,当你点击“还原”按钮时,你重新初始化了canvas,但并没有清除之前添加到canvas上的图片对象。这意味着,即使你重新初始化了canvas,之前的图片对象仍然存在于内存中,并且当你尝试放大或缩小图片时,它仍然会按照之前的状态进行操作。

为了解决这个问题,你需要在restorex函数中清除canvas上的所有对象。你可以使用canvas.clear()方法来完成这个操作。这将从canvas中删除所有对象,包括你的图片。然后,你可以再次调用init函数来重新加载图片。

以下是修改后的restorex函数:

const restorex = () => {
  if (canvas) {
    canvas.clear().renderAll(); // 清除canvas上的所有对象
  }
  init(); // 重新初始化canvas并加载图片
}

此外,你需要注意的是,在你的代码中,你在init函数中设置了canvas的宽度和高度。但是,当canvasAll的宽度发生变化时,你可能需要更新canvas的宽度。否则,如果canvasAll的宽度发生了变化,但是canvas的宽度没有更新,那么canvas可能会显示不正确。你可能需要在addScrollListener函数中添加一些代码来监听canvasAll的宽度变化,并相应地更新canvas的宽度。

最后,你的代码中没有显示地处理canvas的销毁。如果你的组件被销毁或卸载,你可能需要销毁canvas以释放资源。你可以在onUnmounted生命周期钩子中做这个操作。

希望这个答案对你有所帮助!如果你还有其他问题,欢迎继续提问。

1 个回答
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进