Skip to content

Commit

Permalink
Merge pull request #246 from logisky/jh/click
Browse files Browse the repository at this point in the history
fix: click canvas
  • Loading branch information
ImJeremyHe authored Dec 27, 2024
2 parents 3c4159b + f258b31 commit 5156d0c
Showing 11 changed files with 94 additions and 105 deletions.
61 changes: 40 additions & 21 deletions src/components/canvas/defs/match.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {LeftTop, SETTINGS} from '@/core/settings'
import {LeftTop} from '@/core/settings'
import {Range} from '@/core/standable'
import {Cell} from './cell'
import {CellViewData} from '@/core/data2'
@@ -16,30 +16,49 @@ export function getOffset(
}

export function match(
clientX: number,
clientY: number,
canvas: HTMLCanvasElement,
canvasX: number,
canvasY: number,
anchorX: number,
anchorY: number,
data: readonly CellViewData[]
) {
const {x, y} = getOffset(clientX, clientY, canvas)
if (canvasX <= LeftTop.width && canvasY <= LeftTop.height)
return new Cell('LeftTop')
if (canvasX <= LeftTop.width) {
// clicking a row
const clickPosition = new Range()
.setStartCol(0)
.setStartRow(canvasY + anchorY - LeftTop.height)
.setEndCol(0)
.setEndRow(canvasY + anchorY - LeftTop.height)
const row = data
.flatMap((d) => d.rows)
.find((r) => r.position.cover(clickPosition))
if (row) return new Cell('FixedLeftHeader').copyByRenderCell(row)
return new Cell('unknown')
}

if (canvasY <= LeftTop.height) {
// clicking a col
const clickPosition = new Range()
.setStartCol(canvasX + anchorX - LeftTop.width)
.setStartRow(0)
.setEndCol(canvasX + anchorX - LeftTop.width)
.setEndRow(0)
const col = data
.flatMap((d) => d.cols)
.find((c) => c.position.cover(clickPosition))
if (col) return new Cell('FixedTopHeader').copyByRenderCell(col)
return new Cell('unknown')
}
const clickPosition = new Range()
.setStartCol(x)
.setStartRow(y)
.setEndCol(x)
.setEndRow(y)
const col = data
.flatMap((d) => d.cols)
.find((c) => c.position.cover(clickPosition))
const row = data
.flatMap((d) => d.rows)
.find((r) => r.position.cover(clickPosition))
.setStartCol(canvasX + anchorX - LeftTop.width)
.setStartRow(canvasY + anchorY - LeftTop.height)
.setEndCol(canvasX + anchorX - LeftTop.width)
.setEndRow(canvasY + anchorY - LeftTop.height)
const renderCell = data
.flatMap((d) => d.cols)
.flat()
.flatMap((d) => d.cells)
.find((c) => c.position.cover(clickPosition))
if (x <= LeftTop.width && y <= LeftTop.height) return new Cell('LeftTop')
else if (row) return new Cell('FixedLeftHeader').copyByRenderCell(row)
else if (col) return new Cell('FixedTopHeader').copyByRenderCell(col)
else if (renderCell) return new Cell('Cell').copyByRenderCell(renderCell)
if (renderCell) return new Cell('Cell').copyByRenderCell(renderCell)
return new Cell('unknown')
}
24 changes: 6 additions & 18 deletions src/components/canvas/store/dnd.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {action, makeObservable, observable} from 'mobx'
import {Range} from '@/core/standable'
import {CanvasStore} from './store'
import {Cell, match} from '../defs'
import {getPosition, getSelector} from './selector'
import {Cell} from '../defs'
import {getPosition} from './selector'
import {AttributeName} from '@/core'

export class Dnd {
@@ -51,13 +51,9 @@ export class Dnd {
y: e.clientY - this._mousedownStart.y,
}
if (startCell.type !== 'Cell') return true
const endCell = match(
const endCell = this.store.match(
oldEnd.position.startCol + moved.x,
oldEnd.position.startRow + moved.y,
this.store.render.canvas,
this.store.dataSvc.getCurrentCellView(
this.store.dataSvc.getCurrentSheetIdx()
)
oldEnd.position.startRow + moved.y
)
if (endCell.type !== 'Cell') return true
this._setEnd({start: startCell, end: endCell})
@@ -73,11 +69,7 @@ export class Dnd {
private _setRange(selector?: _Selector) {
this._selector = selector
const sel = selector
? getSelector(
this.store.render.canvas,
selector.start,
selector.end
)
? this.store.selector?.getSelector(selector.start, selector.end)
: undefined
const newRange = sel ? getPosition(sel) : undefined
this.range = newRange
@@ -91,11 +83,7 @@ export class Dnd {
private _setEnd = (selector?: _Selector) => {
this._endSelector = selector
const sel = selector
? getSelector(
this.store.render.canvas,
selector.start,
selector.end
)
? this.store.selector?.getSelector(selector.start, selector.end)
: undefined
const draggingRange = sel ? getPosition(sel) : undefined
this.dragging = draggingRange
8 changes: 4 additions & 4 deletions src/components/canvas/store/render.ts
Original file line number Diff line number Diff line change
@@ -92,8 +92,8 @@ export class Render {
)
this._painterService.line([
[pos.startCol, pos.startRow],
[pos.endCol, pos.startRow],
[pos.endCol, pos.endRow],
[LeftTop.width, pos.startRow],
[LeftTop.width, pos.endRow],
[pos.startCol, pos.endRow],
])
const box = new Box()
@@ -120,9 +120,9 @@ export class Render {
)
this._painterService.line([
[pos.endCol, pos.startRow],
[pos.endCol, pos.endRow],
[pos.endCol, LeftTop.height],
[pos.startCol, pos.endRow],
[pos.startCol, pos.startRow],
[pos.startCol, LeftTop.height],
])
const a1Notation = toA1notation(c.coordinate.startCol)
const box = new Box()
2 changes: 1 addition & 1 deletion src/components/canvas/store/resizer.ts
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@ import {
SetRowHeightBuilder,
Transaction,
} from 'logisheets-web'
import {getOffset} from '../defs'
import {isErrorMessage} from 'packages/web/src/api/utils'
import {getOffset} from '../defs'

interface ResizerProps {
readonly range: Range
70 changes: 18 additions & 52 deletions src/components/canvas/store/selector.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import {CanvasStore} from './store'
import {SelectorProps} from '@/components/selector'
import {Range} from '@/core/standable'
import {Cell} from '../defs'
import {LeftTop} from '@/core/settings'

export class Selector {
constructor(public readonly store: CanvasStore) {
@@ -87,15 +88,25 @@ export class Selector {

@action
updateSelector(start?: Cell, end?: Cell) {
if (!this.selector) return
const selector = this.getSelector(start, end)
this.selector = selector
return selector
}

getSelector(start?: Cell, end?: Cell) {
if (!start) return
const {type, width, height, position: startPos} = start
const {type, width, height, position: sp} = start
if (type === 'unknown') return

const selector = new SelectorProps()
const endCellInner = end ?? start
const {position: endPos} = endCellInner
if (type === 'unknown' || !this.selector) return
const selector = this.selector
const {position: ep} = endCellInner
const startPos = this.store.convertToCanvasPosition(sp, type)
const endPos = this.store.convertToCanvasPosition(ep, type)
selector.width = width
selector.height = height
// 在单元格内框选

if (endPos.startRow < startPos.startRow) {
selector.borderTopWidth = startPos.startRow - endPos.startRow
selector.y = endPos.startRow
@@ -110,17 +121,15 @@ export class Selector {
selector.borderRightWidth = endPos.endCol - startPos.endCol
selector.x = startPos.startCol
}
// 起始点在左固定栏、上固定栏、leftTop

const {width: totalWidth, height: totalHeight} =
this.store.render.canvas.getBoundingClientRect()
if (type === 'LeftTop') {
selector.x = startPos.startRow
selector.y = startPos.startCol
selector.borderRightWidth = totalWidth - width
selector.borderBottomWidth = totalHeight - height
}
// 起始点在左固定栏、上固定栏时,x,y的判断和type==='cell'一致
else if (type === 'FixedLeftHeader')
} else if (type === 'FixedLeftHeader')
selector.borderRightWidth = totalWidth - width
else if (type === 'FixedTopHeader')
selector.borderBottomWidth = totalHeight - height
@@ -145,46 +154,3 @@ export const getPosition = (selector: SelectorProps) => {
selector.borderRightWidth
)
}
export const getSelector = (
canvas: HTMLCanvasElement,
start?: Cell,
end?: Cell
) => {
if (!start) return
const {type, width, height, position: startPos} = start
const endCellInner = end ?? start
const {position: endPos} = endCellInner
if (type === 'unknown') return
const selector = new SelectorProps()
selector.width = width
selector.height = height
if (endPos.startRow < startPos.startRow) {
selector.borderTopWidth = startPos.startRow - endPos.startRow
selector.y = endPos.startRow
} else {
selector.borderBottomWidth = endPos.endRow - startPos.endRow
selector.y = startPos.startRow
}
if (endPos.startCol < startPos.startCol) {
selector.borderLeftWidth = startPos.startCol - endPos.startCol
selector.x = endPos.startCol
} else {
selector.borderRightWidth = endPos.endCol - startPos.endCol
selector.x = startPos.startCol
}
// 起始点在左固定栏、上固定栏、leftTop
const {width: totalWidth, height: totalHeight} =
canvas.getBoundingClientRect()
if (type === 'LeftTop') {
selector.x = startPos.startRow
selector.y = startPos.startCol
selector.borderRightWidth = totalWidth - width
selector.borderBottomWidth = totalHeight - height
}
// 起始点在左固定栏、上固定栏时,x,y的判断和type==='cell'一致
else if (type === 'FixedLeftHeader')
selector.borderRightWidth = totalWidth - width
else if (type === 'FixedTopHeader')
selector.borderBottomWidth = totalHeight - height
return selector
}
25 changes: 23 additions & 2 deletions src/components/canvas/store/store.ts
Original file line number Diff line number Diff line change
@@ -3,12 +3,14 @@ import {createContext, type MouseEvent} from 'react'
import {Render} from './render'
import {Resizer} from './resizer'
import {Highlights} from './highlights'
import {Cell, match} from '../defs'
import {Cell, CellType, getOffset, match} from '../defs'
import {Selector} from './selector'
import {Dnd} from './dnd'
import {ScrollBar} from './scrollbar'
import {Textarea} from './textarea'
import {RenderCell, DataService, CellViewData} from '@/core/data2'
import {Range} from '@/core/standable'
import {LeftTop} from '@/core/settings'

export class CanvasStore {
constructor(public readonly dataSvc: DataService) {
@@ -52,8 +54,27 @@ export class CanvasStore {
}

match(clientX: number, clientY: number) {
const {x, y} = getOffset(clientX, clientY, this.render.canvas)
const data = this.getCurrentCellView()
return match(clientX, clientY, this.render.canvas, data)
return match(x, y, this.anchorX, this.anchorY, data)
}

convertToCanvasPosition(p: Range, ty: CellType): Range {
let xOffset = 0
let yOffset = 0
if (ty === 'Cell') {
xOffset = LeftTop.width
yOffset = LeftTop.height
} else if (ty === 'FixedLeftHeader') {
yOffset = LeftTop.height
} else if (ty === 'FixedTopHeader') {
xOffset = LeftTop.width
}
return new Range()
.setEndCol(p.endCol - this.anchorX + xOffset)
.setStartCol(p.startCol - this.anchorX + xOffset)
.setEndRow(p.endRow - this.anchorY + yOffset)
.setStartRow(p.startRow - this.anchorY + yOffset)
}

@action
1 change: 0 additions & 1 deletion src/components/content/edit-bar.tsx
Original file line number Diff line number Diff line change
@@ -26,7 +26,6 @@ export const EditBarComponent: FC<EditBarProps> = ({
const cell = dataSvc.getCellInfo(dataSvc.getCurrentSheetIdx(), row, col)
cell.then((c) => {
if (isErrorMessage(c)) return
console.log(c)
if (c.getFormula() === '') setFormula(c.getText())
else setFormula(c.getFormula())
})
1 change: 0 additions & 1 deletion src/components/selector/index.tsx
Original file line number Diff line number Diff line change
@@ -47,7 +47,6 @@ export const SelectorComponent = observer((props: ISelectorProps) => {
position: 'absolute',
top: 0,
left: 0,
// box-shadow: rgb(255 255 255) 0 0 0 1px, rgb(31 187 125) 0 0 0 3px;
border: 'solid rgba(31, 187, 125, 0.1)',
width: '100%',
height: '100%',
2 changes: 2 additions & 0 deletions src/core/data2/render.ts
Original file line number Diff line number Diff line change
@@ -35,6 +35,8 @@ export class RenderCell {
public coordinate = new Range()
/**
* start/end row/col pixel distance
*
* Note: this is the position in the whole sheet
*/
public position = new Range()
public info?: StandardCell
4 changes: 0 additions & 4 deletions src/core/data2/workbook/workbook.worker.ts
Original file line number Diff line number Diff line change
@@ -73,9 +73,7 @@ class WorkerService implements IWorkbookWorker {
}

public async init() {
console.log(',,,,,,,,')
await initWasm()
console.log('1111111')
this._workbookImpl = new Workbook()
this._workbookImpl.registerCellUpdatedCallback(() => {
ctx.postMessage({id: WorkerUpdate.Cell})
@@ -85,7 +83,6 @@ class WorkerService implements IWorkbookWorker {
})
// Inform the client that service is ready
ctx.postMessage({id: WorkerUpdate.Ready})
console.log('????')
}

public handleTransaction(params: HandleTransactionParams): ActionEffect {
@@ -199,7 +196,6 @@ class WorkerService implements IWorkbookWorker {
// Worker thread execution
const workerService = new WorkerService()

console.log('sssssssss')
workerService.init().then(() => {
ctx.onmessage = (e) => {
const request = e.data
1 change: 0 additions & 1 deletion src/core/ioc/config.ts
Original file line number Diff line number Diff line change
@@ -13,7 +13,6 @@ import {TYPES} from './types'
export const CONTAINER = new Container()

export async function setup() {
console.log('gggggnew web worker')
const workbook = new WorkbookClient()
CONTAINER.bind<IWorkbookClient>(TYPES.Workbook).toConstantValue(workbook)
return workbook.isReady().then((_) => {

0 comments on commit 5156d0c

Please sign in to comment.