UNPKG

@turbox3d/renderer-core

Version:

Large-scale declarative graphic ui core renderer

148 lines (130 loc) 5 kB
import { ViewEntity, SceneEvent } from '@turbox3d/event-manager'; import { shallowEqual } from '@turbox3d/shared'; import { SceneTool } from '@turbox3d/command-manager'; import { Element, VirtualNode } from './render'; import { getSceneParent } from './utils'; import { SceneContext } from './scene'; export interface PreserveProps { key?: string | number; children?: Element<any>[]; onClick?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onDBClick?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onRightClick?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onDragStart?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onDragMove?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onDragEnd?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onPinchStart?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onPinch?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onPinchEnd?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onRotateStart?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onRotate?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onRotateEnd?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onPress?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onPressUp?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onHoverIn?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; onHoverOut?: (viewEntity: Partial<ViewEntity>, event: SceneEvent, tools: SceneTool) => void; clickable?: boolean; hoverable?: boolean; draggable?: boolean; pinchable?: boolean; rotatable?: boolean; pressable?: boolean; } export type ComponentProps<P> = PreserveProps & Partial<ViewEntity> & P; const dummyPreserveProps: PreserveProps & Partial<ViewEntity> = { key: void 0, // children: void 0, // onClick: void 0, // onDBClick: void 0, // onRightClick: void 0, // onDragStart: void 0, // onDragMove: void 0, // onDragEnd: void 0, // onPinchStart: void 0, // onPinch: void 0, // onPinchEnd: void 0, // onRotateStart: void 0, // onRotate: void 0, // onRotateEnd: void 0, // onPress: void 0, // onPressUp: void 0, // onHoverIn: void 0, // onHoverOut: void 0, clickable: void 0, hoverable: void 0, draggable: void 0, pinchable: void 0, rotatable: void 0, pressable: void 0, id: void 0, type: void 0, }; /** * graphic render component */ export class Component<P extends object = {}> { props: ComponentProps<P>; _vNode: VirtualNode; get context(): SceneContext { const scene = getSceneParent(this); if (scene) { return ((scene as any).sceneContext || {}) as SceneContext; } return {} as SceneContext; } constructor(props = {} as ComponentProps<P>) { this.props = props; } forceUpdate() { this._vNode.update(true); } shouldComponentUpdate(nextProps = {} as Readonly<ComponentProps<P>>) { return true; } shouldComponentInteractiveUpdate(nextProps = {} as Readonly<ComponentProps<P>>) { return !shallowEqual({ clickable: this.props.clickable, hoverable: this.props.hoverable, draggable: this.props.draggable, pinchable: this.props.pinchable, rotatable: this.props.rotatable, pressable: this.props.pressable, }, { clickable: nextProps.clickable, hoverable: nextProps.hoverable, draggable: nextProps.draggable, pinchable: nextProps.pinchable, rotatable: nextProps.rotatable, pressable: nextProps.pressable, }); } shouldComponentCustomPropsUpdate(nextProps = {} as Readonly<ComponentProps<P>>) { const preserveKeys = Object.keys(dummyPreserveProps); return !shallowEqual(this.props, nextProps, preserveKeys); } componentWillMount(): void | Promise<void> { // } componentWillUpdate(nextProps = {} as Readonly<ComponentProps<P>>): void | Promise<void> { // } render() { return this.props.children || null; } componentDidMount(): void | Promise<void> { // } componentDidUpdate(prevProps: Readonly<ComponentProps<P>>): void | Promise<void> { // } componentWillUnmount(): void | Promise<void> { // } } export class PureComponent<P extends object = {}> extends Component<P> { shouldComponentUpdate(nextProps: Readonly<ComponentProps<P>>) { const interactiveKeys = new Set(['clickable', 'hoverable', 'draggable', 'pinchable', 'rotatable', 'pressable']); const preserveKeys = Object.keys(dummyPreserveProps).filter(key => !interactiveKeys.has(key)); return !shallowEqual(this.props, nextProps, preserveKeys); } }