初始化模版工程
This commit is contained in:
82
components/html-editor/hooks/useToolPostion.ts
Normal file
82
components/html-editor/hooks/useToolPostion.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { HTMLEditor } from '../lib'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
export const useToolPostion = (editor: HTMLEditor | null, isDoc: boolean) => {
|
||||
const [position, setPosition] = useState<{ left: number; top: number, bottom: number, right: number, width: number, height: number } | null>(null)
|
||||
// 标识是否从编辑器内开始选择
|
||||
const isSelectingRef = useRef(false)
|
||||
const updatePositionFromSelection = () => {
|
||||
if (!editor) {
|
||||
return
|
||||
}
|
||||
const view = editor.getDoc().view
|
||||
if (!view) {
|
||||
return
|
||||
}
|
||||
const selection = view.getSelection()
|
||||
if (!selection) return
|
||||
// 如果选区为空,不需要更新
|
||||
const hasSelectAnything = selection.rangeCount === 0 || selection.toString().trim() === ''
|
||||
if (selection.isCollapsed || selection.rangeCount === 0 || hasSelectAnything) {
|
||||
setPosition(null)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取选区的 Range 对象
|
||||
const range = selection.getRangeAt(0);
|
||||
// 获取选区末尾的位置
|
||||
// 创建一个新的 Range,只包含选区的末尾点
|
||||
const endRange = range.cloneRange();
|
||||
endRange.collapse(false); // false 表示折叠到末尾
|
||||
const rect = endRange.getBoundingClientRect();
|
||||
|
||||
const { top, left, bottom, right, width, height } = rect
|
||||
setPosition({ top, left, bottom, right, width, height })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!editor || !isDoc) {
|
||||
return
|
||||
}
|
||||
const dom = editor.getDoc().document
|
||||
if (!dom) {
|
||||
return
|
||||
}
|
||||
|
||||
const onMouseDown = () => {
|
||||
isSelectingRef.current = true
|
||||
}
|
||||
|
||||
const onMouseUp = () => {
|
||||
// 只有从编辑器内开始选择时才处理
|
||||
if (!isSelectingRef.current) {
|
||||
return
|
||||
}
|
||||
isSelectingRef.current = false
|
||||
setTimeout(() => {
|
||||
updatePositionFromSelection()
|
||||
}, 50)
|
||||
}
|
||||
|
||||
const onScrollOrResize = () => {
|
||||
updatePositionFromSelection()
|
||||
}
|
||||
|
||||
dom.addEventListener('mousedown', onMouseDown)
|
||||
dom.addEventListener('mouseup', onMouseUp)
|
||||
dom.addEventListener('scroll', onScrollOrResize)
|
||||
|
||||
window.addEventListener('scroll', onScrollOrResize, true)
|
||||
window.addEventListener('resize', onScrollOrResize)
|
||||
|
||||
return () => {
|
||||
dom.removeEventListener('mousedown', onMouseDown)
|
||||
dom.removeEventListener('mouseup', onMouseUp)
|
||||
dom.removeEventListener('scroll', onScrollOrResize)
|
||||
window.removeEventListener('scroll', onScrollOrResize, true)
|
||||
window.removeEventListener('resize', onScrollOrResize)
|
||||
}
|
||||
}, [editor, updatePositionFromSelection, isDoc])
|
||||
|
||||
return position
|
||||
}
|
||||
Reference in New Issue
Block a user