|
|
|
@ -13,34 +13,65 @@ export class SelectionObserver {
|
|
|
|
right: number
|
|
|
|
right: number
|
|
|
|
] = [70, 40, 10, 20]
|
|
|
|
] = [70, 40, 10, 20]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private selectionContainer: Element | Document
|
|
|
|
private rangeManager: RangeManager
|
|
|
|
private rangeManager: RangeManager
|
|
|
|
private requestAnimationFrameId: number | null
|
|
|
|
private requestAnimationFrameId: number | null
|
|
|
|
private isMousedown: boolean
|
|
|
|
private isMousedown: boolean
|
|
|
|
private isMoving: boolean
|
|
|
|
private isMoving: boolean
|
|
|
|
|
|
|
|
private clientWidth: number
|
|
|
|
|
|
|
|
private clientHeight: number
|
|
|
|
|
|
|
|
private containerRect: DOMRect | null
|
|
|
|
|
|
|
|
|
|
|
|
constructor(draw: Draw) {
|
|
|
|
constructor(draw: Draw) {
|
|
|
|
|
|
|
|
this.rangeManager = draw.getRange()
|
|
|
|
|
|
|
|
// 优先使用配置的滚动容器dom
|
|
|
|
|
|
|
|
const { scrollContainerSelector } = draw.getOptions()
|
|
|
|
|
|
|
|
this.selectionContainer = scrollContainerSelector
|
|
|
|
|
|
|
|
? document.querySelector(scrollContainerSelector) || document
|
|
|
|
|
|
|
|
: document
|
|
|
|
this.requestAnimationFrameId = null
|
|
|
|
this.requestAnimationFrameId = null
|
|
|
|
this.isMousedown = false
|
|
|
|
this.isMousedown = false
|
|
|
|
this.isMoving = false
|
|
|
|
this.isMoving = false
|
|
|
|
this.rangeManager = draw.getRange()
|
|
|
|
// 缓存尺寸
|
|
|
|
|
|
|
|
this.clientWidth = 0
|
|
|
|
|
|
|
|
this.clientHeight = 0
|
|
|
|
|
|
|
|
this.containerRect = null
|
|
|
|
|
|
|
|
// 添加监听
|
|
|
|
this._addEvent()
|
|
|
|
this._addEvent()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private _addEvent() {
|
|
|
|
private _addEvent() {
|
|
|
|
document.addEventListener('mousedown', this._mousedown)
|
|
|
|
const container = <Document>this.selectionContainer
|
|
|
|
document.addEventListener('mousemove', this._mousemove)
|
|
|
|
container.addEventListener('mousedown', this._mousedown)
|
|
|
|
document.addEventListener('mouseup', this._mouseup)
|
|
|
|
container.addEventListener('mousemove', this._mousemove)
|
|
|
|
|
|
|
|
container.addEventListener('mouseup', this._mouseup)
|
|
|
|
|
|
|
|
document.addEventListener('mouseleave', this._mouseup)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public removeEvent() {
|
|
|
|
public removeEvent() {
|
|
|
|
document.removeEventListener('mousedown', this._mousedown)
|
|
|
|
const container = <Document>this.selectionContainer
|
|
|
|
document.removeEventListener('mousemove', this._mousemove)
|
|
|
|
container.removeEventListener('mousedown', this._mousedown)
|
|
|
|
document.removeEventListener('mouseup', this._mouseup)
|
|
|
|
container.removeEventListener('mousemove', this._mousemove)
|
|
|
|
|
|
|
|
container.removeEventListener('mouseup', this._mouseup)
|
|
|
|
|
|
|
|
document.removeEventListener('mouseleave', this._mouseup)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private _mousedown = () => {
|
|
|
|
private _mousedown = () => {
|
|
|
|
this.isMousedown = true
|
|
|
|
this.isMousedown = true
|
|
|
|
|
|
|
|
// 更新容器宽高
|
|
|
|
|
|
|
|
this.clientWidth =
|
|
|
|
|
|
|
|
this.selectionContainer instanceof Document
|
|
|
|
|
|
|
|
? document.documentElement.clientWidth
|
|
|
|
|
|
|
|
: this.selectionContainer.clientWidth
|
|
|
|
|
|
|
|
this.clientHeight =
|
|
|
|
|
|
|
|
this.selectionContainer instanceof Document
|
|
|
|
|
|
|
|
? document.documentElement.clientHeight
|
|
|
|
|
|
|
|
: this.selectionContainer.clientHeight
|
|
|
|
|
|
|
|
// 更新容器位置信息
|
|
|
|
|
|
|
|
if (!(this.selectionContainer instanceof Document)) {
|
|
|
|
|
|
|
|
const rect = this.selectionContainer.getBoundingClientRect()
|
|
|
|
|
|
|
|
this.containerRect = rect
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private _mouseup = () => {
|
|
|
|
private _mouseup = () => {
|
|
|
|
@ -50,16 +81,18 @@ export class SelectionObserver {
|
|
|
|
|
|
|
|
|
|
|
|
private _mousemove = (evt: MouseEvent) => {
|
|
|
|
private _mousemove = (evt: MouseEvent) => {
|
|
|
|
if (!this.isMousedown || this.rangeManager.getIsCollapsed()) return
|
|
|
|
if (!this.isMousedown || this.rangeManager.getIsCollapsed()) return
|
|
|
|
const { x, y } = evt
|
|
|
|
let { x, y } = evt
|
|
|
|
const clientWidth = document.documentElement.clientWidth
|
|
|
|
if (this.containerRect) {
|
|
|
|
const clientHeight = document.documentElement.clientHeight
|
|
|
|
x = x - this.containerRect.x
|
|
|
|
|
|
|
|
y = y - this.containerRect.y
|
|
|
|
|
|
|
|
}
|
|
|
|
if (y < this.thresholdPoints[0]) {
|
|
|
|
if (y < this.thresholdPoints[0]) {
|
|
|
|
this._startMove(MoveDirection.UP)
|
|
|
|
this._startMove(MoveDirection.UP)
|
|
|
|
} else if (clientHeight - y <= this.thresholdPoints[1]) {
|
|
|
|
} else if (this.clientHeight - y <= this.thresholdPoints[1]) {
|
|
|
|
this._startMove(MoveDirection.DOWN)
|
|
|
|
this._startMove(MoveDirection.DOWN)
|
|
|
|
} else if (x < this.thresholdPoints[2]) {
|
|
|
|
} else if (x < this.thresholdPoints[2]) {
|
|
|
|
this._startMove(MoveDirection.LEFT)
|
|
|
|
this._startMove(MoveDirection.LEFT)
|
|
|
|
} else if (clientWidth - x < this.thresholdPoints[3]) {
|
|
|
|
} else if (this.clientWidth - x < this.thresholdPoints[3]) {
|
|
|
|
this._startMove(MoveDirection.RIGHT)
|
|
|
|
this._startMove(MoveDirection.RIGHT)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
this._stopMove()
|
|
|
|
this._stopMove()
|
|
|
|
@ -67,16 +100,27 @@ export class SelectionObserver {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private _move(direction: MoveDirection) {
|
|
|
|
private _move(direction: MoveDirection) {
|
|
|
|
const x = window.scrollX
|
|
|
|
// Document使用window
|
|
|
|
const y = window.scrollY
|
|
|
|
const container =
|
|
|
|
|
|
|
|
this.selectionContainer instanceof Document
|
|
|
|
|
|
|
|
? window
|
|
|
|
|
|
|
|
: this.selectionContainer
|
|
|
|
|
|
|
|
const x =
|
|
|
|
|
|
|
|
this.selectionContainer instanceof Document
|
|
|
|
|
|
|
|
? window.scrollX
|
|
|
|
|
|
|
|
: (<Element>container).scrollLeft
|
|
|
|
|
|
|
|
const y =
|
|
|
|
|
|
|
|
this.selectionContainer instanceof Document
|
|
|
|
|
|
|
|
? window.scrollY
|
|
|
|
|
|
|
|
: (<Element>container).scrollTop
|
|
|
|
if (direction === MoveDirection.DOWN) {
|
|
|
|
if (direction === MoveDirection.DOWN) {
|
|
|
|
window.scrollTo(x, y + this.step)
|
|
|
|
container.scrollTo(x, y + this.step)
|
|
|
|
} else if (direction === MoveDirection.UP) {
|
|
|
|
} else if (direction === MoveDirection.UP) {
|
|
|
|
window.scrollTo(x, y - this.step)
|
|
|
|
container.scrollTo(x, y - this.step)
|
|
|
|
} else if (direction === MoveDirection.LEFT) {
|
|
|
|
} else if (direction === MoveDirection.LEFT) {
|
|
|
|
window.scrollTo(x - this.step, y)
|
|
|
|
container.scrollTo(x - this.step, y)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
window.scrollTo(x + this.step, y)
|
|
|
|
container.scrollTo(x + this.step, y)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.requestAnimationFrameId = window.requestAnimationFrame(
|
|
|
|
this.requestAnimationFrameId = window.requestAnimationFrame(
|
|
|
|
this._move.bind(this, direction)
|
|
|
|
this._move.bind(this, direction)
|
|
|
|
|