mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-10-31 04:02:59 +08:00 
			
		
		
		
	feat: 楼层选择组件 & fix: 滚动条交互错位
This commit is contained in:
		
							parent
							
								
									936c909451
								
							
						
					
					
						commit
						b7c7cdeca0
					
				| @ -75,7 +75,7 @@ | |||||||
|         "markdown-it-mathjax3": "^4.3.2", |         "markdown-it-mathjax3": "^4.3.2", | ||||||
|         "mermaid": "^11.5.0", |         "mermaid": "^11.5.0", | ||||||
|         "postcss-preset-env": "^9.6.0", |         "postcss-preset-env": "^9.6.0", | ||||||
|         "prettier": "^3.5.3", |         "prettier": "^3.6.2", | ||||||
|         "rollup": "^3.29.5", |         "rollup": "^3.29.5", | ||||||
|         "terser": "^5.39.0", |         "terser": "^5.39.0", | ||||||
|         "tsx": "^4.19.3", |         "tsx": "^4.19.3", | ||||||
|  | |||||||
| @ -0,0 +1,202 @@ | |||||||
|  | import { DefaultProps } from '@motajs/render-vue'; | ||||||
|  | import { SetupComponentOptions } from '@motajs/system-ui'; | ||||||
|  | import { clamp, isNil } from 'lodash-es'; | ||||||
|  | import { computed, defineComponent, ref, watch } from 'vue'; | ||||||
|  | import { Scroll, ScrollExpose } from './scroll'; | ||||||
|  | import { Font } from '@motajs/render-style'; | ||||||
|  | import { MotaOffscreenCanvas2D } from '@motajs/render-core'; | ||||||
|  | 
 | ||||||
|  | export interface FloorSelectorProps extends DefaultProps { | ||||||
|  |     floors: FloorIds[]; | ||||||
|  |     now?: number; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export type FloorSelectorEmits = { | ||||||
|  |     /** | ||||||
|  |      * 点击关闭按钮时触发 | ||||||
|  |      */ | ||||||
|  |     close: () => void; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 当选中的楼层改变时触发 | ||||||
|  |      * @param floor 楼层索引 | ||||||
|  |      * @param floorId 楼层 id | ||||||
|  |      */ | ||||||
|  |     update: (floor: number, floorId: FloorIds) => void; | ||||||
|  | 
 | ||||||
|  |     'update:now': (value: number) => void; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const floorSelectorProps = { | ||||||
|  |     props: ['floors', 'now'], | ||||||
|  |     emits: ['close', 'update', 'update:now'] | ||||||
|  | } satisfies SetupComponentOptions< | ||||||
|  |     FloorSelectorProps, | ||||||
|  |     FloorSelectorEmits, | ||||||
|  |     keyof FloorSelectorEmits | ||||||
|  | >; | ||||||
|  | 
 | ||||||
|  | export const FloorSelector = defineComponent< | ||||||
|  |     FloorSelectorProps, | ||||||
|  |     FloorSelectorEmits, | ||||||
|  |     keyof FloorSelectorEmits | ||||||
|  | >((props, { emit }) => { | ||||||
|  |     const listFont = new Font(Font.defaultFamily, 12); | ||||||
|  | 
 | ||||||
|  |     const now = ref(props.now ?? 0); | ||||||
|  |     const selList = ref(0); | ||||||
|  | 
 | ||||||
|  |     const scrollRef = ref<ScrollExpose>(); | ||||||
|  | 
 | ||||||
|  |     const floorId = computed(() => props.floors[now.value]); | ||||||
|  |     const floorName = computed(() => core.floors[floorId.value].title); | ||||||
|  | 
 | ||||||
|  |     watch( | ||||||
|  |         () => props.now, | ||||||
|  |         value => { | ||||||
|  |             if (!isNil(value)) now.value = value; | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     let gradient: CanvasGradient | null = null; | ||||||
|  | 
 | ||||||
|  |     const getGradient = (ctx: CanvasRenderingContext2D) => { | ||||||
|  |         if (gradient) return gradient; | ||||||
|  |         gradient = ctx.createLinearGradient(0, 0, 0, 200); | ||||||
|  |         gradient.addColorStop(0, 'rgba(255,255,255,0)'); | ||||||
|  |         gradient.addColorStop(0.2, 'rgba(255,255,255,1)'); | ||||||
|  |         gradient.addColorStop(0.8, 'rgba(255,255,255,1)'); | ||||||
|  |         gradient.addColorStop(1, 'rgba(255,255,255,0)'); | ||||||
|  |         return gradient; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const renderMask = (canvas: MotaOffscreenCanvas2D) => { | ||||||
|  |         const { ctx } = canvas; | ||||||
|  |         const gradient = getGradient(ctx); | ||||||
|  |         ctx.fillStyle = gradient; | ||||||
|  |         ctx.fillRect(0, 0, 144, 200); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const changeTo = (index: number) => { | ||||||
|  |         const res = clamp(index, 0, props.floors.length - 1); | ||||||
|  |         now.value = res; | ||||||
|  |         selList.value = res; | ||||||
|  |         const y = res * 24; | ||||||
|  |         scrollRef.value?.scrollTo(y, 500); | ||||||
|  |         emit('update', now.value, floorId.value); | ||||||
|  |         emit('update:now', now.value); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const changeFloor = (delta: number) => { | ||||||
|  |         changeTo(now.value + delta); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const enterList = (index: number) => { | ||||||
|  |         selList.value = index; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     const close = () => { | ||||||
|  |         emit('close'); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return () => ( | ||||||
|  |         <container> | ||||||
|  |             <text text={floorName.value} loc={[90, 24]} anc={[0.5, 0.5]} /> | ||||||
|  |             <g-line line={[48, 40, 132, 40]} lineWidth={1} /> | ||||||
|  |             <g-line line={[48, 440, 132, 440]} lineWidth={1} /> | ||||||
|  |             <text | ||||||
|  |                 text="退出" | ||||||
|  |                 loc={[90, 456]} | ||||||
|  |                 anc={[0.5, 0.5]} | ||||||
|  |                 cursor="pointer" | ||||||
|  |                 onClick={close} | ||||||
|  |             /> | ||||||
|  |             <text | ||||||
|  |                 text="「 上移十层 」" | ||||||
|  |                 loc={[90, 70]} | ||||||
|  |                 anc={[0.5, 0.5]} | ||||||
|  |                 cursor="pointer" | ||||||
|  |                 onClick={() => changeFloor(-10)} | ||||||
|  |             /> | ||||||
|  |             <text | ||||||
|  |                 text="「 上移一层 」" | ||||||
|  |                 loc={[90, 110]} | ||||||
|  |                 anc={[0.5, 0.5]} | ||||||
|  |                 cursor="pointer" | ||||||
|  |                 onClick={() => changeFloor(-1)} | ||||||
|  |             /> | ||||||
|  |             <text | ||||||
|  |                 text="「 下移一层 」" | ||||||
|  |                 loc={[90, 370]} | ||||||
|  |                 anc={[0.5, 0.5]} | ||||||
|  |                 cursor="pointer" | ||||||
|  |                 onClick={() => changeFloor(1)} | ||||||
|  |             /> | ||||||
|  |             <text | ||||||
|  |                 text="「 下移十层 」" | ||||||
|  |                 loc={[90, 410]} | ||||||
|  |                 anc={[0.5, 0.5]} | ||||||
|  |                 cursor="pointer" | ||||||
|  |                 onClick={() => changeFloor(10)} | ||||||
|  |             /> | ||||||
|  |             <container loc={[0, 140, 144, 200]}> | ||||||
|  |                 <Scroll | ||||||
|  |                     ref={scrollRef} | ||||||
|  |                     loc={[0, 0, 144, 200]} | ||||||
|  |                     noscroll | ||||||
|  |                     zIndex={10} | ||||||
|  |                     padEnd={88} | ||||||
|  |                 > | ||||||
|  |                     {props.floors.map((v, i) => { | ||||||
|  |                         const floor = core.floors[v]; | ||||||
|  |                         const highlight = | ||||||
|  |                             now.value === i || selList.value === i; | ||||||
|  |                         const color = highlight ? '#fff' : '#aaa'; | ||||||
|  |                         const fill = highlight ? '#fff' : '#000'; | ||||||
|  |                         return ( | ||||||
|  |                             <container | ||||||
|  |                                 nocache | ||||||
|  |                                 loc={[0, i * 24 + 88, 144, 24]} | ||||||
|  |                                 key={v} | ||||||
|  |                             > | ||||||
|  |                                 <text | ||||||
|  |                                     cursor="pointer" | ||||||
|  |                                     text={floor.title} | ||||||
|  |                                     loc={[114, 12]} | ||||||
|  |                                     anc={[1, 0.5]} | ||||||
|  |                                     font={listFont} | ||||||
|  |                                     fillStyle={color} | ||||||
|  |                                     onEnter={() => enterList(i)} | ||||||
|  |                                     onLeave={() => enterList(now.value)} | ||||||
|  |                                     onClick={() => changeTo(i)} | ||||||
|  |                                 /> | ||||||
|  |                                 <g-circle | ||||||
|  |                                     stroke | ||||||
|  |                                     fill | ||||||
|  |                                     lineWidth={1} | ||||||
|  |                                     circle={[130, 12, 3]} | ||||||
|  |                                     strokeStyle={color} | ||||||
|  |                                     fillStyle={now.value === i ? fill : '#000'} | ||||||
|  |                                 /> | ||||||
|  |                             </container> | ||||||
|  |                         ); | ||||||
|  |                     })} | ||||||
|  |                 </Scroll> | ||||||
|  |                 <g-line | ||||||
|  |                     line={[130, 0, 130, 200]} | ||||||
|  |                     zIndex={5} | ||||||
|  |                     lineWidth={1} | ||||||
|  |                     strokeStyle="#aaa" | ||||||
|  |                 /> | ||||||
|  |                 <sprite | ||||||
|  |                     zIndex={20} | ||||||
|  |                     loc={[0, 0, 144, 200]} | ||||||
|  |                     nocache | ||||||
|  |                     noevent | ||||||
|  |                     render={renderMask} | ||||||
|  |                     composite="destination-in" | ||||||
|  |                 /> | ||||||
|  |             </container> | ||||||
|  |         </container> | ||||||
|  |     ); | ||||||
|  | }, floorSelectorProps); | ||||||
| @ -20,7 +20,12 @@ import { | |||||||
|     MotaOffscreenCanvas2D, |     MotaOffscreenCanvas2D, | ||||||
|     IActionEvent, |     IActionEvent, | ||||||
|     IWheelEvent, |     IWheelEvent, | ||||||
|     MouseType |     MouseType, | ||||||
|  |     EventProgress, | ||||||
|  |     ActionEventMap, | ||||||
|  |     ContainerCustom, | ||||||
|  |     ActionType, | ||||||
|  |     CustomContainerPropagateOrigin | ||||||
| } from '@motajs/render'; | } from '@motajs/render'; | ||||||
| import { hyper, linear, Transition } from 'mutate-animate'; | import { hyper, linear, Transition } from 'mutate-animate'; | ||||||
| import { clamp } from 'lodash-es'; | import { clamp } from 'lodash-es'; | ||||||
| @ -355,6 +360,23 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>( | |||||||
| 
 | 
 | ||||||
|         //#region 事件监听
 |         //#region 事件监听
 | ||||||
| 
 | 
 | ||||||
|  |         const customPropagate = <T extends ActionType>( | ||||||
|  |             type: T, | ||||||
|  |             progress: EventProgress, | ||||||
|  |             event: ActionEventMap[T], | ||||||
|  |             _: ContainerCustom, | ||||||
|  |             origin: CustomContainerPropagateOrigin | ||||||
|  |         ) => { | ||||||
|  |             if (progress === EventProgress.Capture) { | ||||||
|  |                 if (direction.value === ScrollDirection.Horizontal) { | ||||||
|  |                     event.offsetX += contentPos; | ||||||
|  |                 } else { | ||||||
|  |                     event.offsetY += contentPos; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             origin(type, progress, event); | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|         const wheelScroll = (delta: number, max: number) => { |         const wheelScroll = (delta: number, max: number) => { | ||||||
|             const sign = Math.sign(delta); |             const sign = Math.sign(delta); | ||||||
|             const dx = Math.abs(delta); |             const dx = Math.abs(delta); | ||||||
| @ -532,6 +554,7 @@ export const Scroll = defineComponent<ScrollProps, {}, string, ScrollSlots>( | |||||||
|                         ref={content} |                         ref={content} | ||||||
|                         onDown={down} |                         onDown={down} | ||||||
|                         render={renderContent} |                         render={renderContent} | ||||||
|  |                         propagate={customPropagate} | ||||||
|                         zIndex={0} |                         zIndex={0} | ||||||
|                     > |                     > | ||||||
|                         {slots.default?.()} |                         {slots.default?.()} | ||||||
|  | |||||||
| @ -9,8 +9,8 @@ import { SetupComponentOptions } from '@motajs/system-ui'; | |||||||
| 
 | 
 | ||||||
| export interface ThumbnailProps extends SpriteProps { | export interface ThumbnailProps extends SpriteProps { | ||||||
|     loc: ElementLocator; |     loc: ElementLocator; | ||||||
|     padStyle: CanvasStyle; |  | ||||||
|     floorId: FloorIds; |     floorId: FloorIds; | ||||||
|  |     padStyle?: CanvasStyle; | ||||||
|     map?: Block[]; |     map?: Block[]; | ||||||
|     hero?: HeroStatus; |     hero?: HeroStatus; | ||||||
|     // configs
 |     // configs
 | ||||||
| @ -65,7 +65,7 @@ export const Thumbnail = defineComponent<ThumbnailProps>(props => { | |||||||
|             options.centerY = hero.loc.y; |             options.centerY = hero.loc.y; | ||||||
|         } |         } | ||||||
|         ctx.save(); |         ctx.save(); | ||||||
|         ctx.fillStyle = props.padStyle; |         ctx.fillStyle = props.padStyle ?? 'black'; | ||||||
|         ctx.fillRect(0, 0, canvas.width, canvas.height); |         ctx.fillRect(0, 0, canvas.width, canvas.height); | ||||||
|         core.drawThumbnail(props.floorId, props.map, options); |         core.drawThumbnail(props.floorId, props.map, options); | ||||||
|         ctx.restore(); |         ctx.restore(); | ||||||
|  | |||||||
| @ -483,7 +483,6 @@ export class Damage extends RenderItem<EDamageEvent> { | |||||||
|         const { ctx } = canvas; |         const { ctx } = canvas; | ||||||
|         ctx.save(); |         ctx.save(); | ||||||
|         transformCanvas(canvas, transform); |         transformCanvas(canvas, transform); | ||||||
|         ctx.lineJoin = 'round'; |  | ||||||
| 
 | 
 | ||||||
|         const render = this.calNeedRender(transform); |         const render = this.calNeedRender(transform); | ||||||
|         const block = this.block; |         const block = this.block; | ||||||
| @ -521,6 +520,8 @@ export class Damage extends RenderItem<EDamageEvent> { | |||||||
|             const { ctx: ct } = temp; |             const { ctx: ct } = temp; | ||||||
| 
 | 
 | ||||||
|             ct.translate(-px, -py); |             ct.translate(-px, -py); | ||||||
|  |             ct.lineJoin = 'round'; | ||||||
|  |             ct.lineCap = 'round'; | ||||||
| 
 | 
 | ||||||
|             const render = this.renderable.get(v); |             const render = this.renderable.get(v); | ||||||
| 
 | 
 | ||||||
| @ -532,6 +533,7 @@ export class Damage extends RenderItem<EDamageEvent> { | |||||||
|                 ct.font = v.font ?? this.font; |                 ct.font = v.font ?? this.font; | ||||||
|                 ct.strokeStyle = v.stroke ?? this.strokeStyle; |                 ct.strokeStyle = v.stroke ?? this.strokeStyle; | ||||||
|                 ct.lineWidth = v.strokeWidth ?? this.strokeWidth; |                 ct.lineWidth = v.strokeWidth ?? this.strokeWidth; | ||||||
|  | 
 | ||||||
|                 ct.strokeText(v.text, v.x, v.y); |                 ct.strokeText(v.text, v.x, v.y); | ||||||
|                 ct.fillText(v.text, v.x, v.y); |                 ct.fillText(v.text, v.x, v.y); | ||||||
|             }); |             }); | ||||||
|  | |||||||
| @ -151,8 +151,23 @@ export type CustomContainerRenderFn = ( | |||||||
|     transform: Transform |     transform: Transform | ||||||
| ) => void; | ) => 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 { | export class ContainerCustom extends Container { | ||||||
|     private renderFn?: CustomContainerRenderFn; |     private renderFn?: CustomContainerRenderFn; | ||||||
|  |     private propagateFn?: CustomContainerPropagateFn; | ||||||
| 
 | 
 | ||||||
|     protected render( |     protected render( | ||||||
|         canvas: MotaOffscreenCanvas2D, |         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 渲染函数 |      * @param render 渲染函数 | ||||||
| @ -173,6 +202,14 @@ export class ContainerCustom extends Container { | |||||||
|         this.renderFn = render; |         this.renderFn = render; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * 设置这个自定义容器的事件传递函数 | ||||||
|  |      * @param propagate 事件传递函数 | ||||||
|  |      */ | ||||||
|  |     setPropagateFn(propagate: CustomContainerPropagateFn) { | ||||||
|  |         this.propagateFn = propagate; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     protected handleProps( |     protected handleProps( | ||||||
|         key: string, |         key: string, | ||||||
|         prevValue: any, |         prevValue: any, | ||||||
| @ -184,6 +221,11 @@ export class ContainerCustom extends Container { | |||||||
|                 this.setRenderFn(nextValue); |                 this.setRenderFn(nextValue); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|  |             case 'propagate': { | ||||||
|  |                 if (!this.assertType(nextValue, 'function', key)) return false; | ||||||
|  |                 this.setPropagateFn(nextValue); | ||||||
|  |                 return true; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         return super.handleProps(key, prevValue, nextValue); |         return super.handleProps(key, prevValue, nextValue); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -73,11 +73,11 @@ export interface IActionEventBase { | |||||||
|     ctrlKey: boolean; |     ctrlKey: boolean; | ||||||
|     /** 触发时是否按下了 Windows(Windows) / Command(Mac) 键 */ |     /** 触发时是否按下了 Windows(Windows) / Command(Mac) 键 */ | ||||||
|     metaKey: boolean; |     metaKey: boolean; | ||||||
|  |     /** 这次操作的标识符,在按下、移动、抬起阶段中保持不变 */ | ||||||
|  |     identifier: number; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface IActionEvent extends IActionEventBase { | export interface IActionEvent extends IActionEventBase { | ||||||
|     /** 这次操作的标识符,在按下、移动、抬起阶段中保持不变 */ |  | ||||||
|     identifier: number; |  | ||||||
|     /** 相对于触发元素左上角的横坐标 */ |     /** 相对于触发元素左上角的横坐标 */ | ||||||
|     offsetX: number; |     offsetX: number; | ||||||
|     /** 相对于触发元素左上角的纵坐标 */ |     /** 相对于触发元素左上角的纵坐标 */ | ||||||
|  | |||||||
| @ -165,14 +165,19 @@ export class MotaRenderer extends Container implements IRenderTreeRoot { | |||||||
|             } |             } | ||||||
|             this.checkMouseEnterLeave( |             this.checkMouseEnterLeave( | ||||||
|                 ev, |                 ev, | ||||||
|  |                 event, | ||||||
|                 this.beforeHovered, |                 this.beforeHovered, | ||||||
|                 this.hoveredElement |                 this.hoveredElement | ||||||
|             ); |             ); | ||||||
|         }); |         }); | ||||||
|         canvas.addEventListener('mouseleave', ev => { |         canvas.addEventListener('mouseleave', ev => { | ||||||
|             ev.preventDefault(); |             ev.preventDefault(); | ||||||
|  |             const id = this.getMouseIdentifier( | ||||||
|  |                 ActionType.Leave, | ||||||
|  |                 this.getMouseType(ev) | ||||||
|  |             ); | ||||||
|             this.hoveredElement.forEach(v => { |             this.hoveredElement.forEach(v => { | ||||||
|                 v.emit('leave', this.createMouseActionBase(ev, v)); |                 v.emit('leave', this.createMouseActionBase(ev, id, v)); | ||||||
|             }); |             }); | ||||||
|             this.hoveredElement.clear(); |             this.hoveredElement.clear(); | ||||||
|             this.beforeHovered.clear(); |             this.beforeHovered.clear(); | ||||||
| @ -210,6 +215,7 @@ export class MotaRenderer extends Container implements IRenderTreeRoot { | |||||||
|                 this.captureEvent(ActionType.Move, v); |                 this.captureEvent(ActionType.Move, v); | ||||||
|                 this.checkTouchEnterLeave( |                 this.checkTouchEnterLeave( | ||||||
|                     ev, |                     ev, | ||||||
|  |                     v, | ||||||
|                     this.beforeHovered, |                     this.beforeHovered, | ||||||
|                     this.hoveredElement |                     this.hoveredElement | ||||||
|                 ); |                 ); | ||||||
| @ -308,10 +314,12 @@ export class MotaRenderer extends Container implements IRenderTreeRoot { | |||||||
| 
 | 
 | ||||||
|     private createMouseActionBase( |     private createMouseActionBase( | ||||||
|         event: MouseEvent, |         event: MouseEvent, | ||||||
|  |         id: number, | ||||||
|         target: RenderItem = this, |         target: RenderItem = this, | ||||||
|         mouse: MouseType = this.getMouseType(event) |         mouse: MouseType = this.getMouseType(event) | ||||||
|     ): IActionEventBase { |     ): IActionEventBase { | ||||||
|         return { |         return { | ||||||
|  |             identifier: id, | ||||||
|             target: target, |             target: target, | ||||||
|             touch: false, |             touch: false, | ||||||
|             type: mouse, |             type: mouse, | ||||||
| @ -325,9 +333,11 @@ export class MotaRenderer extends Container implements IRenderTreeRoot { | |||||||
| 
 | 
 | ||||||
|     private createTouchActionBase( |     private createTouchActionBase( | ||||||
|         event: TouchEvent, |         event: TouchEvent, | ||||||
|  |         id: number, | ||||||
|         target: RenderItem |         target: RenderItem | ||||||
|     ): IActionEventBase { |     ): IActionEventBase { | ||||||
|         return { |         return { | ||||||
|  |             identifier: id, | ||||||
|             target: target, |             target: target, | ||||||
|             touch: false, |             touch: false, | ||||||
|             type: MouseType.Left, |             type: MouseType.Left, | ||||||
| @ -480,36 +490,50 @@ export class MotaRenderer extends Container implements IRenderTreeRoot { | |||||||
| 
 | 
 | ||||||
|     private checkMouseEnterLeave( |     private checkMouseEnterLeave( | ||||||
|         event: MouseEvent, |         event: MouseEvent, | ||||||
|  |         ev: IActionEvent, | ||||||
|         before: Set<RenderItem>, |         before: Set<RenderItem>, | ||||||
|         now: Set<RenderItem> |         now: Set<RenderItem> | ||||||
|     ) { |     ) { | ||||||
|         // 先 leave,再 enter
 |         // 先 leave,再 enter
 | ||||||
|         before.forEach(v => { |         before.forEach(v => { | ||||||
|             if (!now.has(v)) { |             if (!now.has(v)) { | ||||||
|                 v.emit('leave', this.createMouseActionBase(event, v)); |                 v.emit( | ||||||
|  |                     'leave', | ||||||
|  |                     this.createMouseActionBase(event, ev.identifier, v) | ||||||
|  |                 ); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         now.forEach(v => { |         now.forEach(v => { | ||||||
|             if (!before.has(v)) { |             if (!before.has(v)) { | ||||||
|                 v.emit('enter', this.createMouseActionBase(event, v)); |                 v.emit( | ||||||
|  |                     'enter', | ||||||
|  |                     this.createMouseActionBase(event, ev.identifier, v) | ||||||
|  |                 ); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private checkTouchEnterLeave( |     private checkTouchEnterLeave( | ||||||
|         event: TouchEvent, |         event: TouchEvent, | ||||||
|  |         ev: IActionEvent, | ||||||
|         before: Set<RenderItem>, |         before: Set<RenderItem>, | ||||||
|         now: Set<RenderItem> |         now: Set<RenderItem> | ||||||
|     ) { |     ) { | ||||||
|         // 先 leave,再 enter
 |         // 先 leave,再 enter
 | ||||||
|         before.forEach(v => { |         before.forEach(v => { | ||||||
|             if (!now.has(v)) { |             if (!now.has(v)) { | ||||||
|                 v.emit('leave', this.createTouchActionBase(event, v)); |                 v.emit( | ||||||
|  |                     'leave', | ||||||
|  |                     this.createTouchActionBase(event, ev.identifier, v) | ||||||
|  |                 ); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         now.forEach(v => { |         now.forEach(v => { | ||||||
|             if (!before.has(v)) { |             if (!before.has(v)) { | ||||||
|                 v.emit('enter', this.createTouchActionBase(event, v)); |                 v.emit( | ||||||
|  |                     'enter', | ||||||
|  |                     this.createTouchActionBase(event, ev.identifier, v) | ||||||
|  |                 ); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -6,7 +6,8 @@ import { | |||||||
|     ElementAnchor, |     ElementAnchor, | ||||||
|     ElementLocator, |     ElementLocator, | ||||||
|     ElementScale, |     ElementScale, | ||||||
|     CustomContainerRenderFn |     CustomContainerRenderFn, | ||||||
|  |     CustomContainerPropagateFn | ||||||
| } from '@motajs/render-core'; | } from '@motajs/render-core'; | ||||||
| import { | import { | ||||||
|     BezierParams, |     BezierParams, | ||||||
| @ -94,6 +95,8 @@ export interface ContainerProps extends BaseProps {} | |||||||
| export interface ConatinerCustomProps extends ContainerProps { | export interface ConatinerCustomProps extends ContainerProps { | ||||||
|     /** 自定义容器渲染函数 */ |     /** 自定义容器渲染函数 */ | ||||||
|     render?: CustomContainerRenderFn; |     render?: CustomContainerRenderFn; | ||||||
|  |     /** 自定义容器事件传递函数 */ | ||||||
|  |     propagate?: CustomContainerPropagateFn; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export interface GL2Props extends BaseProps {} | export interface GL2Props extends BaseProps {} | ||||||
|  | |||||||
							
								
								
									
										1685
									
								
								pnpm-lock.yaml
									
									
									
									
									
								
							
							
						
						
									
										1685
									
								
								pnpm-lock.yaml
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user