Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修复绘制画笔、涂鸦、矩形、椭圆等模糊的问题 #245

Open
xieerduos opened this issue Sep 21, 2024 · 1 comment
Open

修复绘制画笔、涂鸦、矩形、椭圆等模糊的问题 #245

xieerduos opened this issue Sep 21, 2024 · 1 comment

Comments

@xieerduos
Copy link

xieerduos commented Sep 21, 2024

修复canvas画布绘制图形模糊的问题,原因是没有对画布进行缩放

效果对比

左边为不模糊的效果 - 右边为当前效果

image

修改代码1,增加scale缩放比

需要在绘制的时候添加如下代码

   const dpr = window.devicePixelRatio || 1 // 获取设备的像素比
      // 调整 canvas 的尺寸以匹配设备的像素比
      ctx.canvas.width = bounds.width * dpr
      ctx.canvas.height = bounds.height * dpr
      // 缩放 canvas 的绘图上下文,使绘制内容的分辨率与屏幕相匹配
      ctx.scale(dpr, dpr)

修改后完整的代码如下:

    const draw = useCallback(() => {
      if (!bounds || !ctxRef.current) {
        return
      }

      const ctx = ctxRef.current
      const dpr = window.devicePixelRatio || 1 // 获取设备的像素比
      // 调整 canvas 的尺寸以匹配设备的像素比
      ctx.canvas.width = bounds.width * dpr
      ctx.canvas.height = bounds.height * dpr
      // 缩放 canvas 的绘图上下文,使绘制内容的分辨率与屏幕相匹配
      ctx.scale(dpr, dpr)
      // 开启图像平滑
      ctx.imageSmoothingEnabled = true
      ctx.imageSmoothingQuality = 'low'
      // 清除整个画布区域
      ctx.clearRect(0, 0, bounds.width, bounds.height)
      // 绘制历史记录中的每个 item
      history.stack.slice(0, history.index + 1).forEach((item) => {
        if (item.type === HistoryItemType.Source) {
          item.draw(ctx, item)
        }
      })
    }, [bounds, ctxRef, history])

修改代码2

因为上面修改了缩放比,这里也需要同步修改,否则拖拽会出现问题

let x = childrenRect.left + childrenRect.width / 2

    const dpr = window.devicePixelRatio || 1 // 获取设备像素比

    // 对尺寸和坐标进行缩放比调整
    let x = (childrenRect.left + childrenRect.width / 2) * dpr
    let y = (childrenRect.top + childrenRect.height) * dpr

完整的代码如下:

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => {
    if (!open || !operationsRect || !childrenRef.current || !contentRef.current) {
      return
    }

    const childrenRect = childrenRef.current.getBoundingClientRect()
    const contentRect = contentRef.current.getBoundingClientRect()

    let currentPlacement = placement
    const dpr = window.devicePixelRatio || 1 // 获取设备像素比

    // 对尺寸和坐标进行缩放比调整
    let x = (childrenRect.left + childrenRect.width / 2) * dpr
    let y = (childrenRect.top + childrenRect.height) * dpr
    let currentOffsetX = offsetX

    // 如果左右都越界了,就以左边界为准
    if (x + contentRect.width / 2 > operationsRect.x + operationsRect.width) {
      const ox = x
      x = operationsRect.x + operationsRect.width - contentRect.width / 2
      currentOffsetX = ox - x
    }

    // 左边不能超出
    if (x < operationsRect.x + contentRect.width / 2) {
      const ox = x
      x = operationsRect.x + contentRect.width / 2
      currentOffsetX = ox - x
    }

    // 如果上下都越界了,就以上边界为准
    if (y > window.innerHeight - contentRect.height) {
      if (currentPlacement === Placement.Bottom) {
        currentPlacement = Placement.Top
      }
      y = childrenRect.top - contentRect.height
    }

    if (y < 0) {
      if (currentPlacement === Placement.Top) {
        currentPlacement = Placement.Bottom
      }
      y = childrenRect.top + childrenRect.height
    }
    if (currentPlacement !== placement) {
      setPlacement(currentPlacement)
    }
    if (position?.x !== x || position.y !== y) {
      setPosition({
        x,
        y
      })
    }

    if (currentOffsetX !== offsetX) {
      setOffsetX(currentOffsetX)
    }
  })

最后

感谢作者提供的源码,2021年基于该项目代码实现了,截图功能,并对其中的代码进行过优化

现在再次做一个更加优化版本的截图,再次打开项目发现作者已经更新了react代码,非常感谢

@nashaofu
Copy link
Owner

辛苦提交一个pr吧

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants