TASK: #103600 - add delay exchange feature

This commit is contained in:
luojiahao 2022-09-06 19:54:05 +08:00
parent 30f071d0cf
commit fe5a857be2
7 changed files with 290 additions and 168 deletions

View File

@ -12,3 +12,4 @@
- add SlotStyleHandler
- edit container folder animation
- optimize strategy of container
- add delay exchange feature

View File

@ -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
<head>
<script src="grid-container/container.js"></script>
</head>
<body>
<star-container drag-and-drop></star-container>
</body>
```
之后可以在`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. 图标节点被另一个图标节点挤占位置时,仅能再去挤占相邻网格的图标的位置(即不允许挤占上下相邻图标)

View File

@ -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,

View File

@ -87,7 +87,8 @@ export default class ExchangeStrategy {
pickChildren(childrenArr: Set<GaiaContainerChild>[], 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<number> = 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<GaiaContainerChild>[] = []
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)

View File

@ -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

View File

@ -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 {
<button class="add" @click=${this.addAppIcon}></button>
<button class="reset" @click=${() => this.addAppIcon(1, 1)}>1×1</button>
<button class="reset" @click=${() => this.addAppIcon(2, 2)}>2×2</button>
<input id="row" placeholder="row" value="2" />
<input id="row" placeholder="row" value="3" />
<input id="column" placeholder="column" value="2" />
<div id="indicator"></div>
</div>

View File

@ -53,7 +53,7 @@ export default class SiteIcon extends LitElement {
return html`
<div id="image-container">
<div id="spinner"></div>
<img id="display" src="./asserts/icon.png" />
<img id="display" />
</div>
<div>
<div dir="auto" id="subtitle">${this.name}</div>