import * as React from 'react'; import { SelectAllControlKeys, SelectControlKey, SelectDisplayType, } from '../../able'; import { Layer } from '../layer'; import { TransformData, Entity } from '../../../common'; import { PlaygroundConfigEntity } from '../config'; import clx from 'clsx'; import { SelectorBounds, SelectorBoundsProps } from './selector-bounds'; export interface SelectorEntityRendererProps { playgroundConfig: PlaygroundConfigEntity; dispatch: Layer['dispatch']; // 事件分发器 hovered: boolean; // 是否出在hover状态 selected: boolean; // 是否为选中状态 multipleSelected: boolean; // 多个节点被选中 isMoving: boolean; // 是否在移动中 isInOperation: boolean; // 操作中 focused: boolean; boundsProps: SelectorBoundsProps; scale: number; // 缩放 displayType: SelectDisplayType; // 展示类型 selectableEntities: Entity[]; // 所有可被选中的实体 selectControlKeys: SelectControlKey[]; originBtnDisabled?: boolean; // 中心点是否可点 children?: React.JSX.Element[] | React.JSX.Element; style?: React.CSSProperties; className?: string; entity: Entity; // 当前实体 deco?: any; extendRenderer?: (props: SelectorEntityRendererProps) => React.JSX.Element; // 扩展 onControlClick: (key: string, e: React.MouseEvent) => void; // 点击节点控制器触发逻辑, TODO 需要再优化, 并支持吸附能力 onDoubleClick?: (event: React.MouseEvent) => void; // onExtendClick?: (v: SelectorExtendType | 'updateData', node: any, value?: any) => void; elemState?: 'all' | 'point' | 'line'; // all: 全部显示, point: 显示点和线,隐藏 extendRenderer, line: 只显示线 } /** * 实体渲染器 */ export type SelectorEntityRenderer = ( props: SelectorEntityRendererProps ) => React.JSX.Element; export function DefaultSelectorEntityRenderer( props: SelectorEntityRendererProps ): React.JSX.Element { const { elemState = 'all' } = props; // 没有子节点或没有样式情况下且没有选中,则不做任何渲染,提升性能 const needRenderer = props.style || props.className || props.children; if (!props.selected && !props.hovered && !needRenderer) return <>; if (props.selected && props.multipleSelected && !needRenderer) return <>; const hideExtendRenderer = elemState !== 'all'; const hidePoint = elemState === 'line'; const selected = props.selected && !props.multipleSelected; const className = clx( 'gedit-selector-node', { hovered: props.hovered, selected: selected, focused: props.focused, [props.boundsProps.className ? props.boundsProps.className : '']: true, }, props.className ); const transform = props.entity.getData(TransformData)!; const { origin, worldDegree: rotate } = transform; // 先择器不带旋转,旋转样式里按制; const bounds = transform.boundsWithoutRotation; const boundsWorld = transform.bounds; const style: React.CSSProperties = { ...props.boundsProps.style, ...props.style, transformOrigin: `${origin.x * 100}% ${origin.y * 100}%`, }; const onControlMouseDown = (key: string) => (e: React.MouseEvent) => { props.onControlClick(key, e); }; let childNodes: React.JSX.Element[] = !selected || props.isMoving || hidePoint ? [] : SelectAllControlKeys.filter(k => props.selectControlKeys.includes(k) ).map(key => { const style: React.CSSProperties = key === 'origin' ? { left: origin.x * 100 + '%', top: origin.y * 100 + '%', zIndex: 61, pointerEvents: props.originBtnDisabled ? 'none' : undefined, } : {}; return (
); }); if (props.children) { childNodes = childNodes.concat(props.children); } // const ang = transform.rotation / Math.PI * 180; // const leftRotate90 = ang > 30 && ang < 150 ? 30 : 0; // 30 为避免与旋转按钮重叠 return ( <> {childNodes} {/* */} {!hideExtendRenderer && props.extendRenderer && !props.isInOperation && selected && (
{props.extendRenderer(props)}
)} ); }