feat: 楼层选择组件 & fix: 滚动条交互错位

This commit is contained in:
AncTe committed 2025-08-18 18:14:08 +08:00
1 parent 936c909451
commit b7c7cdeca0
10 files changed
+1209 -798

No files matched your search

+42
View File
@@ -151,8 +151,23 @@ export type CustomContainerRenderFn = (
transform: Transform
) => void;
export type CustomContainerPropagateOrigin = <T extends ActionType>(
type: T,
progress: EventProgress,
event: ActionEventMap[T]
) => void;
export type CustomContainerPropagateFn = <T extends ActionType>(
type: T,
progress: EventProgress,
event: ActionEventMap[T],
container: ContainerCustom,
origin: CustomContainerPropagateOrigin
) => void;
export class ContainerCustom extends Container {
private renderFn?: CustomContainerRenderFn;
private propagateFn?: CustomContainerPropagateFn;
protected render(
canvas: MotaOffscreenCanvas2D,
@@ -165,6 +180,20 @@ export class ContainerCustom extends Container {
}
}
protected propagateEvent<T extends ActionType>(
type: T,
progress: EventProgress,
event: ActionEventMap[T]
): void {
if (this.propagateFn) {
this.propagateFn(type, progress, event, this, () => {
super.propagateEvent(type, progress, event);
});
} else {
super.propagateEvent(type, progress, event);
}
}
/**
* 设置这个自定义容器的渲染函数
* @param render 渲染函数
@@ -173,6 +202,14 @@ export class ContainerCustom extends Container {
this.renderFn = render;
}
/**
* 设置这个自定义容器的事件传递函数
* @param propagate 事件传递函数
*/
setPropagateFn(propagate: CustomContainerPropagateFn) {
this.propagateFn = propagate;
}
protected handleProps(
key: string,
prevValue: any,
@@ -184,6 +221,11 @@ export class ContainerCustom extends Container {
this.setRenderFn(nextValue);
return true;
}
case 'propagate': {
if (!this.assertType(nextValue, 'function', key)) return false;
this.setPropagateFn(nextValue);
return true;
}
}
return super.handleProps(key, prevValue, nextValue);
}
+2 -2
View File
@@ -73,11 +73,11 @@ export interface IActionEventBase {
ctrlKey: boolean;
/** 触发时是否按下了 Windows(Windows) / Command(Mac) 键 */
metaKey: boolean;
/** 这次操作的标识符,在按下、移动、抬起阶段中保持不变 */
identifier: number;
}
export interface IActionEvent extends IActionEventBase {
/** 这次操作的标识符,在按下、移动、抬起阶段中保持不变 */
identifier: number;
/** 相对于触发元素左上角的横坐标 */
offsetX: number;
/** 相对于触发元素左上角的纵坐标 */
+29 -5
View File
@@ -165,14 +165,19 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
}
this.checkMouseEnterLeave(
ev,
event,
this.beforeHovered,
this.hoveredElement
);
});
canvas.addEventListener('mouseleave', ev => {
ev.preventDefault();
const id = this.getMouseIdentifier(
ActionType.Leave,
this.getMouseType(ev)
);
this.hoveredElement.forEach(v => {
v.emit('leave', this.createMouseActionBase(ev, v));
v.emit('leave', this.createMouseActionBase(ev, id, v));
});
this.hoveredElement.clear();
this.beforeHovered.clear();
@@ -210,6 +215,7 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
this.captureEvent(ActionType.Move, v);
this.checkTouchEnterLeave(
ev,
v,
this.beforeHovered,
this.hoveredElement
);
@@ -308,10 +314,12 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
private createMouseActionBase(
event: MouseEvent,
id: number,
target: RenderItem = this,
mouse: MouseType = this.getMouseType(event)
): IActionEventBase {
return {
identifier: id,
target: target,
touch: false,
type: mouse,
@@ -325,9 +333,11 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
private createTouchActionBase(
event: TouchEvent,
id: number,
target: RenderItem
): IActionEventBase {
return {
identifier: id,
target: target,
touch: false,
type: MouseType.Left,
@@ -480,36 +490,50 @@ export class MotaRenderer extends Container implements IRenderTreeRoot {
private checkMouseEnterLeave(
event: MouseEvent,
ev: IActionEvent,
before: Set<RenderItem>,
now: Set<RenderItem>
) {
// 先 leave,再 enter
before.forEach(v => {
if (!now.has(v)) {
v.emit('leave', this.createMouseActionBase(event, v));
v.emit(
'leave',
this.createMouseActionBase(event, ev.identifier, v)
);
}
});
now.forEach(v => {
if (!before.has(v)) {
v.emit('enter', this.createMouseActionBase(event, v));
v.emit(
'enter',
this.createMouseActionBase(event, ev.identifier, v)
);
}
});
}
private checkTouchEnterLeave(
event: TouchEvent,
ev: IActionEvent,
before: Set<RenderItem>,
now: Set<RenderItem>
) {
// 先 leave,再 enter
before.forEach(v => {
if (!now.has(v)) {
v.emit('leave', this.createTouchActionBase(event, v));
v.emit(
'leave',
this.createTouchActionBase(event, ev.identifier, v)
);
}
});
now.forEach(v => {
if (!before.has(v)) {
v.emit('enter', this.createTouchActionBase(event, v));
v.emit(
'enter',
this.createTouchActionBase(event, ev.identifier, v)
);
}
});
}