diff --git a/CHANGELOG.md b/CHANGELOG.md
index 04fccf1..521e1d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,3 +12,4 @@
- add SlotStyleHandler
- edit container folder animation
- optimize strategy of container
+- add delay exchange feature
diff --git a/src/components/grid-container/README.md b/src/components/grid-container/README.md
new file mode 100644
index 0000000..d456ccc
--- /dev/null
+++ b/src/components/grid-container/README.md
@@ -0,0 +1,64 @@
+# star-container
+
+容器组件提供了一个便捷易用的拖拽容器组件,可以根据传参不同,将在指定位置生成不同的子节点
+
+## 组件结构
+
+1. `container-page`: 分页组件,用于创建、管理、删除容器分页
+2. `container-child`: 子节点组件,通过传参可以指定节点大小、位置,也用于给图标、组件定位
+3. `container-folder`: 文件夹组件,用于创建、管理、删除文件夹
+4. `gesture-manager`: 手势管理,用于提供多指手势判断
+5. `element-exchange-strategy`: 子节点之间的交换规则
+
+## 基本用法
+
+在`HTML`文件下添加该`container`文件即可使用:
+
+```html
+
+
+
+
+
+
+
+```
+
+之后可以在`js`中添加子节点:
+
+```js
+const container = document.querySelector('star-container')
+container.appendContainerChild(element)
+```
+
+方法`appendContainerChild`可以接收第二个参数`options`,用以定制子节点的位置、大小、添加完成回调、文件名:
+
+```ts
+interface options {
+ row: number // 节点占的行数
+ column: number // 节点占的列数
+ anchorCoordinate: {
+ portrait: [number, number] // 竖屏时,节点左上角占据的位置
+ landscape: [number, number] // 横屏时,节点左上角占据的位置
+ }
+ callback: Function // 添加完成回调
+ folderName: string // 该图标所在的文件夹,若文件夹不存在则该图标所在位置自动生成一个文件夹
+}
+```
+
+## 拖拽换位规则
+
+交换、放置、移动规则,情景重合时,以越下方的规则为准:
+
+1. 优先级高的可以挤占优先级低的子节点位置(gridId)
+2. 图标节点、拖拽中的子节点可以挤占同优先级的子节点位置
+3. 因位置被挤占而需要寻位的元素依照优先级(priority)的降序,依次寻位
+4. 被挤占节点(A)的寻位时的方向,与挤占节点(B)的 GridID 对比获得:
+ 1. A.gridId < B.gridId: 向上
+ 2. A.gridId % container.column < B.gridId % container.column:
+ 向左
+ 3. 以上两条,若其一的条件相反,相对应的方向也取反
+5. 寻位时,优先尝试水平方向移动,后尝试垂直方向移动
+6. 寻位方向并非绝对方向,以移动网格数量最短为优先条件
+7. 为满足规则 5,规则 6 的寻位方向变化以顺时针方向转变,如:上左 → 上右 → 下右 → 下左
+8. 图标节点被另一个图标节点挤占位置时,仅能再去挤占相邻网格的图标的位置(即不允许挤占上下相邻图标)
diff --git a/src/components/grid-container/container.ts b/src/components/grid-container/container.ts
index 787a281..1e1c0ad 100644
--- a/src/components/grid-container/container.ts
+++ b/src/components/grid-container/container.ts
@@ -57,6 +57,11 @@ const MERGE_FORDER_TIME = 700
*/
const FORDER_OPERATE_TIME = 500
+/**
+ * 悬停交换时长
+ */
+const EXCHANGETIMEOUT = 300
+
/**
* The minimum time between sending move events during drag-and-drop.
*/
@@ -196,6 +201,10 @@ class GaiaContainer extends LitElement {
childCoordinate: {[gridId: number]: GaiaContainerChild | undefined}[] = []
// 交换策略
exchangeStratege: ExchangeStrategy
+ // 正在交换的网格
+ exchangeGridId: number | undefined
+ // 交换计时器
+ exchangeTimer: number | undefined
constructor(row = 6, column = 4) {
super()
this.row = row
@@ -210,8 +219,8 @@ class GaiaContainer extends LitElement {
firstUpdated() {
slotStyleHandler.injectGlobalCss(this, containerStyle.cssText, this.name)
let dndObserverCallback = () => {
- if (this._dnd.enabled !== this.dragAndDrop) {
- this._dnd.enabled = this.dragAndDrop
+ if (this._dnd.enabled !== this['drag-and-drop']) {
+ this._dnd.enabled = this['drag-and-drop']
if (this._dnd.enabled) {
this.addEventListener('touchstart', this)
this.addEventListener('touchmove', this)
@@ -256,10 +265,10 @@ class GaiaContainer extends LitElement {
}
}
this.dndObserver = new MutationObserver(dndObserverCallback)
- this.dndObserver.observe(this, {
- attributes: true,
- attributeFilter: ['drag-and-drop'],
- })
+ // this.dndObserver.observe(this, {
+ // attributes: true,
+ // attributeFilter: ['drag-and-drop'],
+ // })
dndObserverCallback()
this.changeLayout()
@@ -437,7 +446,7 @@ class GaiaContainer extends LitElement {
}
// TODO:用于适应旋转屏幕时,改变行数与列数,需要配合row、column属性
- changeLayout() {
+ changeLayout = () => {
// this.styleDom.innerHTML = this.shadowStyle;
const {height, width} = this.getBoundingClientRect()
this.height = height
@@ -452,7 +461,8 @@ class GaiaContainer extends LitElement {
this.style.setProperty('--grid-height', this.gridHeight + 'px')
this.style.setProperty('--grid-width', this.gridWidth + 'px')
- this._children.forEach((child) => child.changeSize())
+ // this._children.forEach((child) => child.changeSize())
+ this.synchronise()
}
get containerChildren(): HTMLElement[] {
@@ -576,7 +586,7 @@ class GaiaContainer extends LitElement {
return length ? this._children[length - 1].element : null
}
- @property({type: Boolean}) dragAndDrop!: boolean
+ @property({type: Boolean}) 'drag-and-drop'!: boolean
get dragAndDropTimeout() {
return this._dnd.delay
@@ -986,25 +996,8 @@ class GaiaContainer extends LitElement {
childToInsert.gridId = this.getGridIdByCoordinate(
childToInsert._lastMasterLeft!,
childToInsert._lastMasterTop!,
- pagination
+ childToInsert.pagination
)
- this.recordChildGridId(childToInsert)
- }
-
- recordChildGridId = (
- child: GaiaContainerChild,
- {gridId, pagination}: {gridId: number; pagination: number} = {
- gridId: child.gridId,
- pagination: this.pagination,
- }
- ) => {
- const recorder = this.childCoordinate[pagination]
- const {row, column} = child
- for (let i = 0; i < row; i++) {
- for (let j = 0; j < column; j++) {
- recorder[gridId + i + j * this.column] = child
- }
- }
}
/**
@@ -1453,18 +1446,21 @@ class GaiaContainer extends LitElement {
}
}
- dropElement() {
- let {dropTarget, dropChild, isPage, pagination, gridId} =
- this.getChildFromPoint(
- this._dnd.gridPosition.x +
- (this._dnd.last.pageX - this._dnd.start.pageX),
- this._dnd.gridPosition.y +
- (this._dnd.last.pageY - this._dnd.start.pageY)
- )
-
+ // 此次交换是否向前挤压
+ pushAhead: boolean = true
+ // 此次交换是否向上挤压
+ pushUp: boolean = true
+ dropElement(mode: 'delay' | 'immediately' = 'delay') {
+ const distanceX =
+ this._dnd.gridPosition.x + this._dnd.last.pageX - this._dnd.start.pageX
+ const distanceY =
+ this._dnd.gridPosition.y + this._dnd.last.pageY - this._dnd.start.pageY
+ const {dropTarget, dropChild, isPage, pagination, gridId} =
+ this.getChildFromPoint(distanceX, distanceY)
+ const child = this._dnd.child
if (
this._staticElements.includes(dropTarget) &&
- (this._dnd.child !== dropChild || gridId == dropChild.gridId)
+ (child !== dropChild || gridId == dropChild.gridId)
) {
return
}
@@ -1472,7 +1468,7 @@ class GaiaContainer extends LitElement {
this._dnd.dropTarget = dropTarget
// 拖拽元素悬浮页面默认为当前页面
const suspendingPage = isPage ? dropTarget! : this.pages[this.pagination]
- if (this._dnd.child.isTail && isPage) {
+ if (child.isTail && isPage) {
if (this._dnd.lastDropChild) {
this._dnd.lastDropChild.master.classList.remove('merging')
this._dnd.lastDropChild = null
@@ -1480,36 +1476,73 @@ class GaiaContainer extends LitElement {
this.clearMergeTimer()
// return
}
- if (dropChild?.priority && dropChild.priority > this._dnd.child.priority) {
+ if (dropChild?.priority && dropChild.priority > child.priority) {
return this._staticElements.push(dropTarget)
}
- // TODO: 图标与图标之间不应该立即进行尝试交换,而是给予一定时间,一定时间内没有进入
- // 合并文件夹状态才进行尝试,同时判断图标间的挤占方向
- let {canPlace, placedRecorder, childCoordinate} =
- this.exchangeStratege.tryToPlace(
- this._dnd.child,
- gridId,
- this.pagination,
- 'place'
- )
- if (canPlace) {
- this._dnd.child.gridId = gridId
- childCoordinate && (this.childCoordinate = childCoordinate)
- if (placedRecorder) {
- for (const pagination in placedRecorder) {
- for (const gridId in placedRecorder[pagination]) {
- const child = placedRecorder[pagination][gridId]
- if (child.pagination != +pagination) {
- this.pages[pagination].appendChild(child.master)
+ const exchange = (gridId: number) => {
+ // TODO: 图标与图标之间不应该立即进行尝试交换,而是给予一定时间,一定时间内没有进入
+ // 合并文件夹状态才进行尝试,同时判断图标间的挤占方向
+ let {canPlace, placedRecorder, childCoordinate} =
+ this.exchangeStratege.tryToPlace(
+ child,
+ gridId,
+ this.pagination,
+ 'place',
+ [this.pushAhead, this.pushUp]
+ )
+
+ if (canPlace) {
+ child.gridId = gridId
+ childCoordinate && (this.childCoordinate = childCoordinate)
+ if (placedRecorder) {
+ for (const pagination in placedRecorder) {
+ for (const gridId in placedRecorder[pagination]) {
+ const child = placedRecorder[pagination][gridId]
+ if (child.pagination != +pagination) {
+ this.pages[pagination].appendChild(child.master)
+ }
+ child.gridId = +gridId
}
- child.gridId = +gridId
}
+ this.synchronise()
}
- this.synchronise()
}
}
+ const openChangeTimer = (gridId: number) => {
+ if (mode !== 'immediately' && gridId == this.exchangeGridId) {
+ return
+ }
+ const change = () => {
+ exchange(gridId)
+ this.exchangeTimer = undefined
+ this.exchangeGridId = undefined
+ }
+ this.exchangeGridId = gridId
+ clearTimeout(this.exchangeTimer)
+ if (mode === 'immediately') {
+ change()
+ } else {
+ this.exchangeTimer = setTimeout(change, EXCHANGETIMEOUT)
+ }
+ }
+
+ // 落点网格的中心位置
+ const gridCenter = {
+ x: ((gridId % this.column) + 0.5) * this.gridWidth,
+ y: (Math.floor(gridId / this.column) + 0.5) * this.gridHeight,
+ }
+
+ if (
+ Math.abs(distanceX - gridCenter.x) < 0.5 * this.gridWidth &&
+ Math.abs(distanceY - gridCenter.y) < 0.5 * this.gridHeight
+ ) {
+ this.pushAhead = distanceX > gridCenter.x
+ this.pushUp = distanceY > gridCenter.y
+ openChangeTimer(gridId)
+ }
+
// let children = this._children
// let folderPosition = {left: 0, top: 0}
// if (this.openedFolder) {
@@ -1518,9 +1551,9 @@ class GaiaContainer extends LitElement {
// folderPosition.top = this.openedFolder.element.offsetTop
// }
// if (isPage) {
- // this._dnd.child.isWidget && (this._dnd.child.isStatic = false)
- // this.realAppendChild(pagination, this._dnd.child.master)
- // this._dnd.child.isWidget && (this._dnd.child.isStatic = 'current')
+ // child.isWidget && (child.isStatic = false)
+ // this.realAppendChild(pagination, child.master)
+ // child.isWidget && (child.isStatic = 'current')
// return this.synchronise()
// }
// if (dropTarget) {
@@ -1532,7 +1565,7 @@ class GaiaContainer extends LitElement {
// this._dnd.last.pageX + this.pages[this.pagination].offsetLeft
// const lastY = this._dnd.last.pageY
// for (let i = 0, iLen = children.length; i < iLen; i++) {
- // if (children[i] === this._dnd.child) {
+ // if (children[i] === child) {
// childIndex = i
// }
@@ -1585,35 +1618,35 @@ class GaiaContainer extends LitElement {
// !this.mergeTimer &&
// dropChild.position === 'page' &&
// !dropChild.isFolder &&
- // !this._dnd.child.isFolder &&
+ // !child.isFolder &&
// !dropChild.isWidget &&
- // !this._dnd.child.isWidget
+ // !child.isWidget
// ) {
// // 图标悬浮于另一个图标正上方
// dropChild.master.classList.add('merging')
// this.mergeTimer = setTimeout(() => {
- // if (!this._dnd.child) return
+ // if (!child) return
// this.mergeFolder(
// (dropChild as GaiaContainerChild).master,
- // this._dnd.child.master
+ // child.master
// )
// this.clearMergeTimer()
// }, MERGE_FORDER_TIME)
// } else if (
// dropChild.position === 'page' &&
// dropChild.isFolder &&
- // !this._dnd.child.isFolder &&
+ // !child.isFolder &&
// !dropChild.isWidget &&
- // !this._dnd.child.isWidget
+ // !child.isWidget
// ) {
// this.clearMergeTimer()
// dropChild.master.classList.add('merging')
// this.mergeTimer = setTimeout(() => {
- // if (!this._dnd.child) return
+ // if (!child) return
// ;(dropChild as GaiaContainerFolder).open()
// this.mergeFolder(
// (dropChild as GaiaContainerFolder).master,
- // this._dnd.child.master
+ // child.master
// )
// this.clearMergeTimer()
// }, MERGE_FORDER_TIME)
@@ -1744,7 +1777,7 @@ class GaiaContainer extends LitElement {
endDrag(event: Event) {
if (this._dnd.active) {
- this.dropElement()
+ this.dropElement('immediately')
this.dispatchEvent(
new CustomEvent('drag-end', {
cancelable: true,
diff --git a/src/components/grid-container/element-exchange-strategy.ts b/src/components/grid-container/element-exchange-strategy.ts
index b57b32f..3a2309f 100644
--- a/src/components/grid-container/element-exchange-strategy.ts
+++ b/src/components/grid-container/element-exchange-strategy.ts
@@ -87,7 +87,8 @@ export default class ExchangeStrategy {
pickChildren(childrenArr: Set[], pagination: number) {
const recorder = this.coordinate[pagination]
for (const children of childrenArr) {
- for (const child of children) {
+ if (!children) continue
+ for (const child of [...children]) {
if (!this.pickChild(child, recorder)) {
return false
}
@@ -115,28 +116,42 @@ export default class ExchangeStrategy {
}
/**
- * 获取交换元素的移动方向
- * @param child
- * @param dropChild
+ * 获取交换节点的移动方向
+ * @param child 交换节点
+ * @param dropChild 落点节点
+ * @param directed 与拖拽节点直接接触节点的移动方向,暂时仅用于图标间的交换
* @returns
*/
getExchangeDirection(
child: GaiaContainerChild,
- dropChild: GaiaContainerChild | undefined
+ dropChild: GaiaContainerChild | undefined,
+ directed?: [boolean, boolean]
): [Directions, Directions] {
if (!dropChild) return [0, 0]
const mColumn = this.manager.column
- const horizontalDir =
- child.gridId % mColumn <= dropChild.gridId % mColumn
+ let horizontalDir, verticalDir
+ if (child.priority + dropChild.priority == 2) {
+ // 两个图标在进行交换
+ horizontalDir = directed
+ ? directed[0]
+ ? Directions.FORWARD
+ : Directions.BACKWARD
+ : child.gridId < dropChild.gridId
? Directions.BACKWARD
: Directions.FORWARD
- // 当垂直方向为0时,表示为图标间的交换,比起上下移动,更优先横向、换行移动
- const verticalDir =
- child.priority + dropChild.priority == 2
- ? 0
- : child.gridId > dropChild.gridId
- ? Directions.UPWARD
- : Directions.DOWN
+
+ // 当垂直方向为0时,比起上下移动,更优先横向、换行移动
+ verticalDir = 0
+ } else {
+ // 小组件参与交换
+ horizontalDir =
+ child.gridId % mColumn <= dropChild.gridId % mColumn
+ ? Directions.BACKWARD
+ : Directions.FORWARD
+ verticalDir =
+ child.gridId > dropChild.gridId ? Directions.UPWARD : Directions.DOWN
+ }
+
return [horizontalDir, verticalDir]
}
@@ -172,8 +187,9 @@ export default class ExchangeStrategy {
if (!this.suspendChild[priority]) {
this.suspendChild[priority] = new Set(children)
} else {
- const suspending = [...this.suspendChild[priority]]
- this.suspendChild[priority] = new Set([...suspending, ...children])
+ children.forEach((child) => {
+ this.suspendChild[priority].add(child)
+ })
}
})
@@ -235,6 +251,7 @@ export default class ExchangeStrategy {
// 优先级足以放置的网格
let access: Set = new Set()
const recorder = this.coordinate[pagination]
+ const mColumn = this.manager.column
this.pickChild(dropChild, recorder)
// 以二维网格的方式遍历格子
const BFS = (
@@ -242,7 +259,6 @@ export default class ExchangeStrategy {
[horizontalDir, verticalDir]: [Directions, Directions],
callback: () => number[][] | undefined
) => {
- const mColumn = this.manager.column
const threshold = origin % mColumn
// 象限旋转方法,是否为0来决定方向 direction 逆时针变换时采用的变换矩阵顺序
const quadrantType = horizontalDir + verticalDir
@@ -262,10 +278,10 @@ export default class ExchangeStrategy {
const hdir = dir[0] * convert[0]
const vdir = dir[1] * convert[1]
dir = [hdir, vdir]
- // 沿着列
- for (let j = 0; j <= step; j++) {
- // 沿着行
- for (let i = 0; i > -1; i++) {
+ // 沿着行
+ for (let i = 0; i <= step; i++) {
+ // 沿着列
+ for (let j = 0; j > -1; j++) {
if (i + j > step) break
if (i + j !== step) continue
@@ -277,8 +293,12 @@ export default class ExchangeStrategy {
continue
if (
- ((hdir > 0 && testId % mColumn >= threshold) ||
- (hdir < 0 && testId % mColumn <= threshold)) &&
+ ((hdir > 0 &&
+ testId > dropChild.gridId &&
+ testId % mColumn >= threshold) || // 向后移动,测试网格应大于原网格,且取余后也比原处取余大
+ (hdir < 0 &&
+ testId < dropChild.gridId &&
+ testId % mColumn <= threshold)) && // 向前移动,测试网格应小于原网格,且取余后也比原处取余小
testId >= 0 &&
testId <= 23
) {
@@ -293,20 +313,20 @@ export default class ExchangeStrategy {
return methods?.length ? methods : undefined
}
// 以一维轴的方式遍历格子
- const DFS = (origin: number, direction: number) => {
- let gridId
+ const BFSinAxios = (origin: number, direction: number) => {
+ let gridId: number | undefined
const ergodic = (direction: number) => {
for (
let i = 1, testId = origin + i * direction;
testId < 24 && testId > -1;
- i++
+ i++, testId = origin + i * direction
) {
- testId = origin + i * direction
-
+ // 获取测试网格之中的子节点
const dropGrid = this.coordinate[pagination][testId]
+
if (
- !dropGrid ||
- (!this.placedChild.has(dropChild) && dropGrid.priority < 2)
+ !dropGrid || // 测试网格为空格子时
+ (!this.placedChild.has(dropGrid) && dropGrid.priority < 2) // 子节点为图标节点,且未移动过
) {
gridId = testId
break
@@ -332,18 +352,19 @@ export default class ExchangeStrategy {
preserve,
access
)
- console.log('gridMethods', gridMethods)
if (gridMethods.length) {
- const dropChildren = this.getChildrenByGridArea(
- grid,
- dropChild.row,
- dropChild.column,
- pagination,
- dropChild.priority
- )
- if (dropChildren.canPlace) {
- methods.push(...gridMethods)
+ for (let grids of gridMethods) {
+ const dropChildren = this.getChildrenByGridArea(
+ grids[0],
+ dropChild.row,
+ dropChild.column,
+ pagination,
+ dropChild.priority
+ )
+ if (dropChildren.canPlace) {
+ methods.push(...gridMethods)
+ }
}
}
}
@@ -352,20 +373,28 @@ export default class ExchangeStrategy {
return methods
}
- // TODO:需要测试是否不需要选择,直接使用第一个方法?
const chooseMethod = (methods: number[][]) => {
let gridId: number | undefined
+ let step = 9
if (methods) {
for (const method of methods) {
+ const diff = Math.abs(method[0] - dropChild.gridId)
+ const methodStep = (diff % mColumn) + Math.floor(diff / mColumn)
+ // 保证取所有方法中移动步数最少的
+ if (step >= methodStep) {
+ step = methodStep
+ } else {
+ continue
+ }
if (
- Math.floor(method[0] / this.manager.column) ==
- Math.floor(dropChild.gridId / this.manager.column) // 优先选择同行位移(gridId 左右移动)
+ Math.floor(method[0] / mColumn) ==
+ Math.floor(dropChild.gridId / mColumn) // 优先选择同行位移(gridId 左右移动)
) {
gridId = method[0]
- break
+ // break
} else if (
- Math.abs(method[0] - dropChild.gridId) % this.manager.column ==
+ Math.abs(method[0] - dropChild.gridId) % mColumn ==
0 // 其次选择同列位移(gridId 上下移动)
) {
gridId = method[0]
@@ -378,7 +407,7 @@ export default class ExchangeStrategy {
}
const methods = direction[1]
? BFS(dropChild.gridId, direction, place)
- : DFS(dropChild.gridId, direction[0])
+ : BFSinAxios(dropChild.gridId, direction[0])
const gridId = methods ? chooseMethod(methods) : undefined
if (typeof gridId == 'number') {
if (this.placedRecorder[pagination]) {
@@ -393,7 +422,7 @@ export default class ExchangeStrategy {
pagination,
dropChild.priority
)
- if (!conflictChildren) return false
+ this.placedChild.add(dropChild)
this.pickChildren(conflictChildren.dropChildren, pagination)
this.concatSuspendingChild(conflictChildren.dropChildren)
this.placeChild(dropChild, gridId, pagination)
@@ -496,7 +525,8 @@ export default class ExchangeStrategy {
child: GaiaContainerChild,
gridId: number,
pagination: number,
- mode: 'place' | 'move'
+ mode: 'place' | 'move',
+ direction: [boolean, boolean]
): {
canPlace: boolean
placedRecorder?: PlacedRecorder
@@ -515,9 +545,10 @@ export default class ExchangeStrategy {
return {canPlace: false}
}
+ const recorder = this.coordinate[pagination]
this.placedRecorder = {}
this.placedChild.add(child)
- const recorder = this.coordinate[pagination]
+ this.pickChild(child, recorder)
const dropChild = recorder[gridId]
// 获取被挤占位置的元素,按照优先级排序
const pickChildren = this.getChildrenByGridArea(
@@ -530,7 +561,7 @@ export default class ExchangeStrategy {
)!
// 检查该子节点与被挤占位置的元素之间的优先级,若存在优先级高的元素,该次放置失败
const canPlace = this.allowPlace(child, pickChildren.dropChildren, mode)
- if (!canPlace) {
+ if (!canPlace || !pickChildren.canPlace) {
return {canPlace: false}
}
@@ -539,27 +570,32 @@ export default class ExchangeStrategy {
this.pickChildren(this.suspendChild, pagination)
// 放置该子节点
- this.pickChild(child, recorder)
this.placeChild(child, gridId, pagination)
// 尝试移动并放置被挤出去的子节点
- for (let i = 0; i < this.suspendChild.length; i++) {
- let j = this.suspendChild.length - i
- let suspendArr = this.suspendChild[j]
- if (suspendArr?.size) {
- for (let suspendChild of [...suspendArr]) {
- const exchangeDirection = this.getExchangeDirection(
- child,
- suspendChild
- )
- if (!this.moveChild(suspendChild, exchangeDirection, pagination)) {
- // 移动失败
-
- return {canPlace: false}
- }
+ try {
+ for (let i = 0; i < this.suspendChild.length; i++) {
+ let j = this.suspendChild.length - i
+ let suspendArr = this.suspendChild[j]
+ if (suspendArr?.size) {
+ suspendArr.forEach((suspendChild) => {
+ const exchangeDirection = this.getExchangeDirection(
+ child,
+ suspendChild,
+ direction
+ )
+ if (!this.moveChild(suspendChild, exchangeDirection, pagination)) {
+ // 移动失败
+ throw suspendChild
+ }
+ })
}
}
+ } catch (placeFaild) {
+ console.info('try to place failed!')
+ return {canPlace: false}
}
+
return {
canPlace: true,
placedRecorder: this.placedRecorder,
@@ -584,18 +620,20 @@ export default class ExchangeStrategy {
let children: Set[] = []
let canPlace = true
for (let i = 0; i < row; i++) {
- for (let j = 0; j < column; j++) {
+ for (let j = 0; j < column && canPlace; j++) {
const targetGrid = gridId + j + i * this.manager.column
const child = recorder[targetGrid]
- if (
- child &&
- (child.priority < priority ||
- (mode == 'place' && child.priority == priority))
- ) {
- if (this.placedChild.has(child)) {
+ if (child) {
+ if (
+ this.placedChild.has(child) ||
+ child.priority > priority ||
+ (mode == 'move' &&
+ child.priority == priority &&
+ child.priority != 1)
+ ) {
canPlace = false
- continue
+ break
}
if (children[child.priority]) {
children[child.priority].add(child)
diff --git a/src/components/grid-container/gaia-container-child.ts b/src/components/grid-container/gaia-container-child.ts
index 4caf4cc..285b9b9 100644
--- a/src/components/grid-container/gaia-container-child.ts
+++ b/src/components/grid-container/gaia-container-child.ts
@@ -158,11 +158,14 @@ export default class GaiaContainerChild {
const area = this.getArea(type)
if (!area) return
- const [rowStart, columStart] = area
+ const [rowStart, columnStart] = area
const rowEnd = rowStart + this.row
- const columEnd = columStart + this.column
- this.master.style.gridArea = `${rowStart} / ${columStart} / ${rowEnd} / ${columEnd}`
+ const columnEnd = columnStart + this.column
+ this.center.x = columnStart + this.column / 2 - 1
+ this.center.y = rowStart + this.row / 2 - 1
+
+ this.master.style.gridArea = `${rowStart} / ${columnStart} / ${rowEnd} / ${columnEnd}`
;(this._element as HTMLElement).dataset.static = type
}
@@ -333,21 +336,6 @@ export default class GaiaContainerChild {
this.curGridId = gridId
}
- // for (let i = 0; i < this.row; i++) {
- // for (let j = 0; j < this.column; j++) {
- // if (position == 'page') {
- // this.manager.childCoordinate[this.pagination][
- // gridId + i + j * this.manager.column
- // ] = this
- // } else {
- // // TODO:文件夹分页
- // this.manager.folders[this.folderName].childCoordinate[0][
- // gridId + i + j
- // ] = this
- // }
- // }
- // }
-
if (this._lastMasterTop !== top || this._lastMasterLeft !== left) {
this._lastMasterTop = top
this._lastMasterLeft = left
diff --git a/src/test/panels/container/homescreen-container.ts b/src/test/panels/container/homescreen-container.ts
index c00acf1..5b68b31 100644
--- a/src/test/panels/container/homescreen-container.ts
+++ b/src/test/panels/container/homescreen-container.ts
@@ -32,8 +32,6 @@ export class PanelContainer extends LitElement {
x =
typeof x == 'number' ? x : this.rowInput.value ? +this.rowInput.value : 1
y = y ? y : this.columnInput.value ? +this.columnInput.value : 1
- console.log(x, y)
- ;(window as any).panel = this
const icon = document.createElement('site-icon')
icon.setAttribute('color', this.createRandomColor())
@@ -53,7 +51,7 @@ export class PanelContainer extends LitElement {
this.indicator.appendChild(index)
}
this.container = new GaiaContainer()
- this.container.setAttribute('dragAndDrop', 'true')
+ this.container.setAttribute('drag-and-drop', '')
this.shadowRoot?.appendChild(this.container)
this.container.sortMode = true
;(window as any).container = this.container
@@ -95,7 +93,7 @@ export class PanelContainer extends LitElement {
-
+
diff --git a/src/test/panels/container/icon.ts b/src/test/panels/container/icon.ts
index 173fe62..6708625 100644
--- a/src/test/panels/container/icon.ts
+++ b/src/test/panels/container/icon.ts
@@ -53,7 +53,7 @@ export default class SiteIcon extends LitElement {
return html`
-
+