-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(item): add moving on same track
refs: #4
- Loading branch information
1 parent
883293d
commit 605d328
Showing
6 changed files
with
200 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import type { LitElement, ReactiveController } from "lit"; | ||
import { delta, equal, fromEvent, Point, zero } from "../core/point.js"; | ||
|
||
export type PointerHandler = (e: Event, delta: Point) => void; | ||
|
||
export interface PointerControllerConfig { | ||
disabled?: boolean; | ||
stopPropagation?: boolean; | ||
startHandler: PointerHandler; | ||
moveHandler: PointerHandler; | ||
doneHandler: PointerHandler; | ||
} | ||
|
||
export class PointerController implements ReactiveController { | ||
private isPointerDown = false; | ||
private pointerPos = zero; | ||
private startingPos = this.pointerPos; | ||
|
||
public stopPropagation: boolean; | ||
public disabled: boolean; | ||
|
||
constructor( | ||
private readonly host: LitElement, | ||
private readonly config?: Partial<PointerControllerConfig> | ||
) { | ||
host.addController(this); | ||
this.stopPropagation = config?.stopPropagation ?? false; | ||
this.disabled = config?.disabled ?? false; | ||
} | ||
|
||
hostConnected() { | ||
this.host.addEventListener("pointerdown", this.handlePointerDown); | ||
this.host.addEventListener("pointermove", this.handlePointerMove); | ||
this.host.addEventListener("pointerup", this.handlePointerUp); | ||
this.host.addEventListener("pointerleave", this.handlePointerUp); | ||
} | ||
|
||
hostDisconnected() { | ||
this.host.removeEventListener("pointerdown", this.handlePointerDown); | ||
this.host.removeEventListener("pointermove", this.handlePointerMove); | ||
this.host.removeEventListener("pointerup", this.handlePointerUp); | ||
this.host.removeEventListener("pointerleave", this.handlePointerUp); | ||
} | ||
|
||
private handlePointerDown = (e: PointerEvent) => { | ||
if (this.isPointerDown || this.disabled) return; | ||
if (this.stopPropagation) e.stopPropagation(); | ||
|
||
this.isPointerDown = true; | ||
|
||
this.startingPos = this.pointerPos = fromEvent(e); | ||
(e.target as HTMLElement).setPointerCapture(e.pointerId); | ||
this.config?.startHandler?.(e, zero); | ||
}; | ||
|
||
private handlePointerUp = (e: PointerEvent) => { | ||
if (!this.isPointerDown || this.disabled) return; | ||
if (this.stopPropagation) e.stopPropagation(); | ||
|
||
this.isPointerDown = false; | ||
(e.target as HTMLElement).releasePointerCapture(e.pointerId); | ||
|
||
if (equal(fromEvent(e), this.startingPos)) return; | ||
this.config?.doneHandler?.(e, zero); | ||
}; | ||
|
||
private handlePointerMove = (e: PointerEvent) => { | ||
if (!this.isPointerDown || this.disabled) return; | ||
if (this.stopPropagation) e.stopPropagation(); | ||
|
||
const newP = fromEvent(e); | ||
const deltaP: Point = delta(this.pointerPos, newP); | ||
this.pointerPos = newP; | ||
this.config?.moveHandler?.(e, deltaP); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export interface Point { | ||
x: number; | ||
y: number; | ||
} | ||
|
||
export const zero: Point = { x: 0, y: 0 }; | ||
|
||
export function point(x: number, y: number) { | ||
return { x, y }; | ||
} | ||
|
||
export function fromEvent(e: PointerEvent): Point { | ||
return point(e.pageX, e.pageY); | ||
} | ||
|
||
export function delta(p1: Point, p2: Point): Point { | ||
return point(p2.x - p1.x, p2.y - p1.y); | ||
} | ||
|
||
export function equal(p1: Point, p2: Point): boolean { | ||
return p1.x === p2.x && p1.y === p2.y; | ||
} |