mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 22:39:39 +00:00
[API] Add DragAndScale onChanged callback (#1055)
This commit is contained in:
@@ -7,7 +7,7 @@ export interface DragAndScaleState {
|
||||
* The offset from the top-left of the current canvas viewport to `[0, 0]` in graph space.
|
||||
* Or said another way, the inverse offset of the viewport.
|
||||
*/
|
||||
offset: Point
|
||||
offset: [number, number]
|
||||
/** The scale of the graph. */
|
||||
scale: number
|
||||
}
|
||||
@@ -28,6 +28,10 @@ export class DragAndScale {
|
||||
* Implemented as a POCO that can be proxied without side-effects.
|
||||
*/
|
||||
state: DragAndScaleState
|
||||
lastState: DragAndScaleState = {
|
||||
offset: [0, 0],
|
||||
scale: 0,
|
||||
}
|
||||
|
||||
/** Maximum scale (zoom in) */
|
||||
max_scale: number
|
||||
@@ -41,13 +45,15 @@ export class DragAndScale {
|
||||
viewport?: Rect
|
||||
|
||||
onredraw?(das: DragAndScale): void
|
||||
onChanged?(scale: number, offset: Point): void
|
||||
|
||||
get offset(): Point {
|
||||
get offset(): [number, number] {
|
||||
return this.state.offset
|
||||
}
|
||||
|
||||
set offset(value: Point) {
|
||||
this.state.offset = value
|
||||
this.state.offset[0] = value[0]
|
||||
this.state.offset[1] = value[1]
|
||||
}
|
||||
|
||||
get scale(): number {
|
||||
@@ -60,7 +66,7 @@ export class DragAndScale {
|
||||
|
||||
constructor(element: HTMLCanvasElement) {
|
||||
this.state = {
|
||||
offset: new Float32Array([0, 0]),
|
||||
offset: [0, 0],
|
||||
scale: 1,
|
||||
}
|
||||
this.max_scale = 10
|
||||
@@ -72,23 +78,43 @@ export class DragAndScale {
|
||||
this.element = element
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if the current state has changed from the previous state.
|
||||
* @returns `true` if the current state has changed from the previous state, otherwise `false`.
|
||||
*/
|
||||
#stateHasChanged(): boolean {
|
||||
const current = this.state
|
||||
const previous = this.lastState
|
||||
|
||||
return current.scale !== previous.scale ||
|
||||
current.offset[0] !== previous.offset[0] ||
|
||||
current.offset[1] !== previous.offset[1]
|
||||
}
|
||||
|
||||
computeVisibleArea(viewport: Rect | undefined): void {
|
||||
const { scale, offset } = this
|
||||
|
||||
if (this.#stateHasChanged()) {
|
||||
this.onChanged?.(scale, offset)
|
||||
copyState(this.state, this.lastState)
|
||||
}
|
||||
|
||||
if (!this.element) {
|
||||
this.visible_area[0] = this.visible_area[1] = this.visible_area[2] = this.visible_area[3] = 0
|
||||
return
|
||||
}
|
||||
let width = this.element.width
|
||||
let height = this.element.height
|
||||
let startx = -this.offset[0]
|
||||
let starty = -this.offset[1]
|
||||
let startx = -offset[0]
|
||||
let starty = -offset[1]
|
||||
if (viewport) {
|
||||
startx += viewport[0] / this.scale
|
||||
starty += viewport[1] / this.scale
|
||||
startx += viewport[0] / scale
|
||||
starty += viewport[1] / scale
|
||||
width = viewport[2]
|
||||
height = viewport[3]
|
||||
}
|
||||
const endx = startx + width / this.scale
|
||||
const endy = starty + height / this.scale
|
||||
const endx = startx + width / scale
|
||||
const endy = starty + height / scale
|
||||
this.visible_area[0] = startx
|
||||
this.visible_area[1] = starty
|
||||
this.visible_area[2] = endx - startx
|
||||
@@ -274,3 +300,14 @@ export class DragAndScale {
|
||||
this.offset[1] = 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the values of one state into another, preserving references.
|
||||
* @param from The state to copy values from.
|
||||
* @param to The state to copy values into.
|
||||
*/
|
||||
function copyState(from: DragAndScaleState, to: DragAndScaleState): void {
|
||||
to.scale = from.scale
|
||||
to.offset[0] = from.offset[0]
|
||||
to.offset[1] = from.offset[1]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user