feat:drag and drop element
This commit is contained in:
@@ -122,8 +122,7 @@ export class CheckboxControl implements IControlInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public cut(): number {
|
public cut(): number {
|
||||||
const { endIndex } = this.control.getRange()
|
return -1
|
||||||
return endIndex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,36 +1,88 @@
|
|||||||
import { EDITOR_ELEMENT_STYLE_ATTR } from '../../../dataset/constant/Element'
|
import { EDITOR_ELEMENT_STYLE_ATTR } from '../../../dataset/constant/Element'
|
||||||
|
import { ControlComponent, ControlType } from '../../../dataset/enum/Control'
|
||||||
|
import { ElementType } from '../../../dataset/enum/Element'
|
||||||
import { IElement } from '../../../interface/Element'
|
import { IElement } from '../../../interface/Element'
|
||||||
|
import { deepClone, getUUID } from '../../../utils'
|
||||||
|
import { formatElementList } from '../../../utils/element'
|
||||||
import { CanvasEvent } from '../CanvasEvent'
|
import { CanvasEvent } from '../CanvasEvent'
|
||||||
|
|
||||||
|
type IDragElement = IElement & { dragId: string }
|
||||||
|
|
||||||
|
function createDragId(element: IElement): string {
|
||||||
|
const dragId = getUUID()
|
||||||
|
Reflect.set(element, 'dragId', dragId)
|
||||||
|
return dragId
|
||||||
|
}
|
||||||
|
|
||||||
|
function getElementIndexByDragId(dragId: string, elementList: IElement[]) {
|
||||||
|
return (<IDragElement[]>elementList).findIndex((el) => el.dragId === dragId)
|
||||||
|
}
|
||||||
|
|
||||||
export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
||||||
// 判断是否允许拖放
|
// 判断是否允许拖放
|
||||||
if (host.isAllowDrop) {
|
if (host.isAllowDrop) {
|
||||||
const draw = host.getDraw()
|
const draw = host.getDraw()
|
||||||
const position = draw.getPosition()
|
const position = draw.getPosition()
|
||||||
|
const positionList = position.getPositionList()
|
||||||
const rangeManager = draw.getRange()
|
const rangeManager = draw.getRange()
|
||||||
const cacheRange = host.cacheRange!
|
const cacheRange = host.cacheRange!
|
||||||
const cacheElementList = host.cacheElementList!
|
const cacheElementList = host.cacheElementList!
|
||||||
const cachePositionList = host.cachePositionList!
|
const cachePositionList = host.cachePositionList!
|
||||||
// 如果同一上下文拖拽位置向后移动,则重置光标位置
|
|
||||||
const range = rangeManager.getRange()
|
const range = rangeManager.getRange()
|
||||||
const elementList = draw.getElementList()
|
// 是否是不可拖拽的控件结构元素
|
||||||
const positionList = position.getPositionList()
|
const dragElementList = cacheElementList.slice(cacheRange.startIndex + 1, cacheRange.endIndex + 1)
|
||||||
const startPosition = positionList[range.startIndex]
|
const isContainControl = dragElementList.find(element =>
|
||||||
const cacheStartElement = cacheElementList[cacheRange.startIndex]
|
element.type === ElementType.CONTROL ||
|
||||||
const startElement = elementList[range.startIndex]
|
element.type === ElementType.DATE
|
||||||
let curIndex = range.startIndex
|
)
|
||||||
if (cacheStartElement.tdId === startElement.tdId && range.startIndex > cacheRange.endIndex) {
|
if (isContainControl) {
|
||||||
curIndex -= (cacheRange.endIndex - cacheRange.startIndex)
|
// 仅允许 (最前/后元素不是控件 || 在控件前后 || 文本控件且是值) 拖拽
|
||||||
|
const cacheStartElement = cacheElementList[cacheRange.startIndex + 1]
|
||||||
|
const cacheEndElement = cacheElementList[cacheRange.endIndex]
|
||||||
|
const isAllowDragControl =
|
||||||
|
(
|
||||||
|
(
|
||||||
|
cacheStartElement.type !== ElementType.CONTROL ||
|
||||||
|
cacheStartElement.controlComponent === ControlComponent.PREFIX
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
cacheEndElement.type !== ElementType.CONTROL ||
|
||||||
|
cacheEndElement.controlComponent === ControlComponent.POSTFIX
|
||||||
|
) &&
|
||||||
|
cacheStartElement.type !== ElementType.DATE &&
|
||||||
|
cacheEndElement.type !== ElementType.DATE
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
cacheStartElement.controlId === cacheEndElement.controlId &&
|
||||||
|
cacheStartElement.controlComponent === ControlComponent.PREFIX &&
|
||||||
|
cacheEndElement.controlComponent === ControlComponent.POSTFIX
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
cacheStartElement.control?.type === ControlType.TEXT &&
|
||||||
|
cacheStartElement.controlComponent === ControlComponent.VALUE &&
|
||||||
|
cacheEndElement.control?.type === ControlType.TEXT &&
|
||||||
|
cacheEndElement.controlComponent === ControlComponent.VALUE
|
||||||
|
)
|
||||||
|
if (!isAllowDragControl) {
|
||||||
|
draw.render({
|
||||||
|
curIndex: range.startIndex,
|
||||||
|
isCompute: false,
|
||||||
|
isSubmitHistory: false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 删除原有拖拽元素
|
|
||||||
const deleteElementList = cacheElementList.splice(cacheRange.startIndex + 1, cacheRange.endIndex - cacheRange.startIndex)
|
|
||||||
// 格式化元素
|
// 格式化元素
|
||||||
|
const editorOptions = draw.getOptions()
|
||||||
|
const elementList = draw.getElementList()
|
||||||
|
const anchorElement = elementList[range.startIndex]
|
||||||
let restArg = {}
|
let restArg = {}
|
||||||
if (startElement.tableId) {
|
if (anchorElement.tableId) {
|
||||||
const { tdId, trId, tableId } = startElement
|
const { tdId, trId, tableId } = anchorElement
|
||||||
restArg = { tdId, trId, tableId }
|
restArg = { tdId, trId, tableId }
|
||||||
}
|
}
|
||||||
const replaceElementList = deleteElementList.map(el => {
|
const replaceElementList = dragElementList.map(el => {
|
||||||
|
if (!el.type || el.type === ElementType.TEXT || el.control?.type === ControlType.TEXT) {
|
||||||
const newElement: IElement = {
|
const newElement: IElement = {
|
||||||
value: el.value,
|
value: el.value,
|
||||||
...restArg
|
...restArg
|
||||||
@@ -42,9 +94,57 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
return newElement
|
return newElement
|
||||||
|
} else {
|
||||||
|
const newElement = deepClone(el)
|
||||||
|
formatElementList([newElement], {
|
||||||
|
isHandleFirstElement: false,
|
||||||
|
editorOptions,
|
||||||
})
|
})
|
||||||
elementList.splice(curIndex + 1, 0, ...replaceElementList)
|
return newElement
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 缓存拖拽选区开始结束id
|
||||||
|
const cacheRangeStartId = createDragId(cacheElementList[cacheRange.startIndex])
|
||||||
|
const cacheRangeEndId = createDragId(cacheElementList[cacheRange.endIndex])
|
||||||
|
// 设置拖拽值
|
||||||
|
const replaceLength = replaceElementList.length
|
||||||
|
let rangeStart = range.startIndex
|
||||||
|
let rangeEnd = rangeStart + replaceLength
|
||||||
|
const control = draw.getControl()
|
||||||
|
const activeControl = control.getActiveControl()
|
||||||
|
if (activeControl && cacheElementList[rangeStart].controlComponent !== ControlComponent.POSTFIX) {
|
||||||
|
rangeEnd = activeControl.setValue(replaceElementList)
|
||||||
|
rangeStart = rangeEnd - replaceLength
|
||||||
|
} else {
|
||||||
|
elementList.splice(rangeStart + 1, 0, ...replaceElementList)
|
||||||
|
}
|
||||||
|
if (!~rangeEnd) {
|
||||||
|
draw.render({
|
||||||
|
isSetCursor: false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 缓存当前开始结束id
|
||||||
|
const rangeStartId = createDragId(elementList[rangeStart])
|
||||||
|
const rangeEndId = createDragId(elementList[rangeEnd])
|
||||||
|
// 删除原有拖拽元素
|
||||||
|
const cacheRangeStartIndex = getElementIndexByDragId(cacheRangeStartId, cacheElementList)
|
||||||
|
const cacheRangeEndIndex = getElementIndexByDragId(cacheRangeEndId, cacheElementList)
|
||||||
|
const cacheEndElement = cacheElementList[cacheRangeEndIndex]
|
||||||
|
if (cacheEndElement.type === ElementType.CONTROL && cacheEndElement.controlComponent !== ControlComponent.POSTFIX) {
|
||||||
|
rangeManager.replaceRange({
|
||||||
|
...cacheRange,
|
||||||
|
startIndex: cacheRangeStartIndex,
|
||||||
|
endIndex: cacheRangeEndIndex
|
||||||
|
})
|
||||||
|
control.getActiveControl()?.cut()
|
||||||
|
} else {
|
||||||
|
cacheElementList.splice(cacheRangeStartIndex + 1, cacheRangeEndIndex - cacheRangeStartIndex)
|
||||||
|
}
|
||||||
// 重设上下文
|
// 重设上下文
|
||||||
|
const startElement = elementList[range.startIndex]
|
||||||
|
const cacheStartElement = cacheElementList[cacheRange.startIndex]
|
||||||
|
const startPosition = positionList[range.startIndex]
|
||||||
const cacheStartPosition = cachePositionList[cacheRange.startIndex]
|
const cacheStartPosition = cachePositionList[cacheRange.startIndex]
|
||||||
const positionContext = position.getPositionContext()
|
const positionContext = position.getPositionContext()
|
||||||
let positionContextIndex = positionContext.index
|
let positionContextIndex = positionContext.index
|
||||||
@@ -52,12 +152,12 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
|||||||
if (startElement.tableId && !cacheStartElement.tableId) {
|
if (startElement.tableId && !cacheStartElement.tableId) {
|
||||||
// 表格外移动到表格内&&表格之前
|
// 表格外移动到表格内&&表格之前
|
||||||
if (cacheStartPosition.index < positionContextIndex) {
|
if (cacheStartPosition.index < positionContextIndex) {
|
||||||
positionContextIndex -= deleteElementList.length
|
positionContextIndex -= replaceLength
|
||||||
}
|
}
|
||||||
} else if (!startElement.tableId && cacheStartElement.tableId) {
|
} else if (!startElement.tableId && cacheStartElement.tableId) {
|
||||||
// 表格内移到表格外&&表格之前
|
// 表格内移到表格外&&表格之前
|
||||||
if (startPosition.index < positionContextIndex) {
|
if (startPosition.index < positionContextIndex) {
|
||||||
positionContextIndex += deleteElementList.length
|
positionContextIndex += replaceLength
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
position.setPositionContext({
|
position.setPositionContext({
|
||||||
@@ -65,25 +165,24 @@ export function mouseup(evt: MouseEvent, host: CanvasEvent) {
|
|||||||
index: positionContextIndex
|
index: positionContextIndex
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 设置选区
|
// 重设选区
|
||||||
|
const rangeStartIndex = getElementIndexByDragId(rangeStartId, elementList)
|
||||||
|
const rangeEndIndex = getElementIndexByDragId(rangeEndId, elementList)
|
||||||
rangeManager.setRange(
|
rangeManager.setRange(
|
||||||
curIndex,
|
rangeStartIndex,
|
||||||
curIndex + deleteElementList.length,
|
rangeEndIndex,
|
||||||
range.tableId,
|
range.tableId,
|
||||||
range.startTdIndex,
|
range.startTdIndex,
|
||||||
range.endTdIndex,
|
range.endTdIndex,
|
||||||
range.startTrIndex,
|
range.startTrIndex,
|
||||||
range.endTrIndex
|
range.endTrIndex
|
||||||
)
|
)
|
||||||
// 重新渲染&重设状态
|
// 重新渲染
|
||||||
draw.render({
|
draw.render({
|
||||||
isSetCursor: false
|
isSetCursor: false
|
||||||
})
|
})
|
||||||
host.isAllowDrag = false
|
|
||||||
host.isAllowDrop = false
|
|
||||||
} else if (host.isAllowDrag) {
|
} else if (host.isAllowDrag) {
|
||||||
// 如果是允许拖拽不允许拖放则光标重置
|
// 如果是允许拖拽不允许拖放则光标重置
|
||||||
host.mousedown(evt)
|
host.mousedown(evt)
|
||||||
host.isAllowDrag = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +103,18 @@ export class RangeManager {
|
|||||||
control.destroyControl()
|
control.destroyControl()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public replaceRange(range: IRange) {
|
||||||
|
this.setRange(
|
||||||
|
range.startIndex,
|
||||||
|
range.endIndex,
|
||||||
|
range.tableId,
|
||||||
|
range.startTdIndex,
|
||||||
|
range.endTdIndex,
|
||||||
|
range.startTrIndex,
|
||||||
|
range.endTrIndex
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
public setRangeStyle() {
|
public setRangeStyle() {
|
||||||
if (!this.listener.rangeStyleChange) return
|
if (!this.listener.rangeStyleChange) return
|
||||||
let curElementList = this.getSelection()
|
let curElementList = this.getSelection()
|
||||||
|
|||||||
Reference in New Issue
Block a user