start iframe
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-02-21 22:17:29
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-17 11:24:59
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\components\IframeWrapperMove\event.ts
|
||||
*/
|
||||
import { RefObject } from 'react';
|
||||
import { containerResizer } from '../../core/resizeHandler/containerResizer';
|
||||
import { contextMenuState } from '../../core/contextMenu';
|
||||
import UserConfig from '../../config';
|
||||
|
||||
export interface WrapperMoveStateProps {
|
||||
isDrag: boolean;
|
||||
startX: number;
|
||||
startY: number;
|
||||
needX: number;
|
||||
needY: number;
|
||||
}
|
||||
|
||||
export interface WrapperMoveRef {
|
||||
ref: null | RefObject<HTMLDivElement>;
|
||||
}
|
||||
|
||||
export const wrapperMoveState: WrapperMoveStateProps = {
|
||||
isDrag: false,
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
needX: 0,
|
||||
needY: 0,
|
||||
};
|
||||
|
||||
export const wrapperRefState: WrapperMoveRef = {
|
||||
ref: null,
|
||||
};
|
||||
|
||||
export const wrapperEvent = (ref: RefObject<HTMLDivElement>, config: UserConfig) => {
|
||||
const scale = config.getScaleState().value;
|
||||
const store = config.getStore();
|
||||
return {
|
||||
onMouseDown: (e: React.MouseEvent) => {
|
||||
// e.preventDefault();// 不能使用preventDefault 否则弹窗输入框焦点无法触发
|
||||
contextMenuState.unmountContextMenu();
|
||||
if (e.target !== ref.current) {
|
||||
} else {
|
||||
wrapperMoveState.isDrag = true;
|
||||
wrapperMoveState.startX = e.clientX;
|
||||
wrapperMoveState.startY = e.clientY;
|
||||
if (ref.current) {
|
||||
ref.current.style.cursor = 'grab';
|
||||
wrapperRefState.ref = ref;
|
||||
}
|
||||
}
|
||||
},
|
||||
onMouseMove: (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
if (wrapperMoveState.isDrag) {
|
||||
const diffX = e.clientX - wrapperMoveState.startX;
|
||||
const diffY = e.clientY - wrapperMoveState.startY;
|
||||
wrapperMoveState.needX = wrapperMoveState.needX + diffX / scale;
|
||||
wrapperMoveState.needY = wrapperMoveState.needY + diffY / scale;
|
||||
wrapperMoveState.startX = e.clientX;
|
||||
wrapperMoveState.startY = e.clientY;
|
||||
|
||||
store.forceUpdate();
|
||||
}
|
||||
containerResizer.onMouseMove(e, config);
|
||||
},
|
||||
};
|
||||
};
|
||||
export const wrapperMoveMouseUp = (config: UserConfig) => {
|
||||
if (wrapperRefState.ref && wrapperRefState.ref.current) {
|
||||
wrapperRefState.ref.current.style.cursor = 'default';
|
||||
}
|
||||
containerResizer.onMouseUp(config);
|
||||
wrapperMoveState.isDrag = false;
|
||||
};
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-03-14 04:29:09
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-17 22:13:37
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\components\IframeWrapperMove\index.tsx
|
||||
*/
|
||||
import { AllHTMLAttributes, CSSProperties, PropsWithChildren, ReactNode, useRef } from 'react';
|
||||
import { wrapperEvent } from './event';
|
||||
import { onWheelEvent } from '../../core/scale';
|
||||
import React from 'react';
|
||||
import Ticker from './ticker';
|
||||
import UserConfig from '../../config';
|
||||
import { containerResizer } from '../../core/resizeHandler/containerResizer';
|
||||
|
||||
export interface ContainerWrapperProps extends AllHTMLAttributes<HTMLDivElement> {
|
||||
config: UserConfig;
|
||||
classNames?: string;
|
||||
style?: CSSProperties;
|
||||
extra?: ReactNode;
|
||||
}
|
||||
|
||||
function ContainerWrapper(props: PropsWithChildren<ContainerWrapperProps>) {
|
||||
const { children, style, classNames, config, extra, ...rest } = props;
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const ticker = props.config.ticker;
|
||||
const wrapperMoveState = config.getWrapperMove().iframe;
|
||||
const scaleState = config.getScaleState();
|
||||
const state = props.config.getStore().getData();
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`ant-menu ${classNames ? classNames : ''}`}
|
||||
ref={ref}
|
||||
style={{
|
||||
backgroundColor: '#f0f0f0',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
...style,
|
||||
}}
|
||||
{...wrapperEvent(ref, props.config)}
|
||||
{...onWheelEvent(props.config)}
|
||||
{...rest}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
transform: `scale(${scaleState.value}) translate(${wrapperMoveState.needX}px, ${wrapperMoveState.needY}px)`,
|
||||
width: state.container.width * scaleState.value,
|
||||
height: state.container.height * scaleState.value,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
<div
|
||||
style={{
|
||||
height: '50px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: state.container.width * scaleState.value,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '20px',
|
||||
cursor: 's-resize',
|
||||
}}
|
||||
onMouseDown={(e) => containerResizer.onMousedown(e, props.config)}
|
||||
>
|
||||
{props.config.getConfig().containerIcon}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{extra && extra}
|
||||
{ticker && <Ticker config={props.config}></Ticker>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default ContainerWrapper;
|
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-07-12 15:54:35
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-13 21:07:22
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\components\wrapperMove\ticker.tsx
|
||||
*/
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import UserConfig from '../../config';
|
||||
|
||||
const width = '20px';
|
||||
const indent = 50;
|
||||
|
||||
function Ticker(props: { config: UserConfig }) {
|
||||
const topRef = useRef<HTMLDivElement>(null);
|
||||
const leftRef = useRef<HTMLDivElement>(null);
|
||||
const [topRender, setTopRender] = useState(0);
|
||||
const [leftRender, setLeftRender] = useState(0);
|
||||
|
||||
const scale = props.config.getScaleState().value;
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
if (topRef.current) {
|
||||
const width = topRef.current.getBoundingClientRect().width;
|
||||
const renderWidth = Math.ceil(width / 10 / scale);
|
||||
setTopRender(renderWidth);
|
||||
}
|
||||
// left可以不用放,但为了更新统一
|
||||
if (leftRef.current) {
|
||||
const height = leftRef.current.getBoundingClientRect().height;
|
||||
const renderHeight = Math.ceil(height / 10 / scale);
|
||||
setLeftRender(renderHeight);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, [props.config, props.config.collapsed, scale]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={topRef}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: indent,
|
||||
width: '100%',
|
||||
height: width,
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
{Array(topRender)
|
||||
.fill(1)
|
||||
.map((_, i) => {
|
||||
if (i % 10 === 0) {
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
style={{
|
||||
background: 'rgb(204, 204, 204)',
|
||||
width: '1px',
|
||||
height: '12px',
|
||||
position: 'relative',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: '20px',
|
||||
fontSize: '10px',
|
||||
left: '-2px',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
{i}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
style={{ background: 'rgb(204, 204, 204)', width: '1px', height: '6px' }}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
<div
|
||||
ref={leftRef}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: indent,
|
||||
left: 0,
|
||||
width: width,
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
flexDirection: 'column',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
{Array(leftRender)
|
||||
.fill(1)
|
||||
.map((_, i) => {
|
||||
if (i % 10 === 0) {
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
style={{
|
||||
background: 'rgb(204, 204, 204)',
|
||||
width: '12px',
|
||||
height: '1px',
|
||||
position: 'relative',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
left: '20px',
|
||||
fontSize: '10px',
|
||||
top: '-2px',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
>
|
||||
{i}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
style={{
|
||||
background: 'rgb(204, 204, 204)',
|
||||
width: '6px',
|
||||
height: '1px',
|
||||
userSelect: 'none',
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Ticker;
|
@@ -37,6 +37,7 @@ function Container(props: PropsWithChildren<ContainerProps>) {
|
||||
return props.state.globalState.containerColor;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{props.context === 'edit' && (
|
||||
|
184
packages/dooringx-lib/src/components/iframeContainer.tsx
Normal file
184
packages/dooringx-lib/src/components/iframeContainer.tsx
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* @Author: yehuozhili
|
||||
* @Date: 2021-07-17 10:08:08
|
||||
* @LastEditors: yehuozhili
|
||||
* @LastEditTime: 2021-07-17 22:13:51
|
||||
* @FilePath: \dooringx\packages\dooringx-lib\src\components\iframeContainer.tsx
|
||||
*/
|
||||
import { containerDragResolve } from '../core/crossDrag';
|
||||
import { containerFocusRemove } from '../core/focusHandler';
|
||||
import { innerContainerDrag } from '../core/innerDrag';
|
||||
import { NormalMarkLineRender } from '../core/markline';
|
||||
import { IStoreData } from '../core/store/storetype';
|
||||
import { wrapperMoveState } from './IframeWrapperMove/event';
|
||||
import { CSSProperties, PropsWithChildren, useEffect, useMemo, useState } from 'react';
|
||||
import Blocks from './blocks';
|
||||
import React from 'react';
|
||||
import UserConfig, { defaultStore } from '../config';
|
||||
import styles from '../index.less';
|
||||
import { getRealHeight } from '../core/transfer';
|
||||
import { WrapperMoveStateProps } from './IframeWrapperMove/event';
|
||||
import { onWheelEventIframe } from '../core/scale';
|
||||
import { selectRangeMouseUp } from '../core/selectRange';
|
||||
interface ContainerProps {
|
||||
context: 'edit' | 'preview';
|
||||
config: UserConfig;
|
||||
editContainerStyle?: CSSProperties;
|
||||
previewContainerStyle?: CSSProperties;
|
||||
}
|
||||
interface IframeInnerState {
|
||||
store: IStoreData;
|
||||
scaleState: {
|
||||
value: number;
|
||||
maxValue: number;
|
||||
minValue: number;
|
||||
};
|
||||
isEdit: boolean;
|
||||
origin: null | IStoreData[];
|
||||
wrapperState: {
|
||||
data: any;
|
||||
iframe: WrapperMoveStateProps;
|
||||
};
|
||||
}
|
||||
|
||||
function Container(props: PropsWithChildren<ContainerProps>) {
|
||||
const { editContainerStyle, previewContainerStyle } = props;
|
||||
|
||||
const [message, setMessage] = useState<IframeInnerState>({
|
||||
store: defaultStore,
|
||||
scaleState: {
|
||||
value: 0,
|
||||
maxValue: 0,
|
||||
minValue: 0,
|
||||
},
|
||||
isEdit: false,
|
||||
wrapperState: props.config.getWrapperMove(),
|
||||
origin: null,
|
||||
});
|
||||
|
||||
const state = message.store;
|
||||
const scaleState = message.scaleState;
|
||||
const isEdit = message.isEdit;
|
||||
|
||||
const bgColor = () => {
|
||||
if (isEdit) {
|
||||
return 'rgba(255,255,255,1)';
|
||||
} else {
|
||||
return state.globalState.containerColor;
|
||||
}
|
||||
};
|
||||
|
||||
const transform = useMemo(() => {
|
||||
if (props.context === 'edit') {
|
||||
return `scale(${scaleState.value}) translate(${wrapperMoveState.needX}px, ${wrapperMoveState.needY}px)`;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}, [props.context, scaleState.value]);
|
||||
|
||||
useEffect(() => {
|
||||
const fn = (e: any) => {
|
||||
console.log(e, 'ccccccccccccccc');
|
||||
if (typeof e.data !== 'object') {
|
||||
return;
|
||||
}
|
||||
if (!e.data.store) {
|
||||
if (e.data.type === 'event') {
|
||||
if (e.data.column === 'select') {
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const data: IframeInnerState = e.data;
|
||||
console.log(data, 'kkkkkkkkkk', !e.data.store, e.data.store);
|
||||
|
||||
setMessage(data);
|
||||
props.config.resetData([data.store]);
|
||||
props.config.scaleState = data.scaleState;
|
||||
};
|
||||
window.addEventListener('message', fn);
|
||||
window.parent.postMessage('ready', '*');
|
||||
return () => {
|
||||
window.removeEventListener('message', fn);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{props.context === 'edit' && (
|
||||
<>
|
||||
<div
|
||||
style={{ display: 'flex' }}
|
||||
onMouseUp={(e) => {
|
||||
selectRangeMouseUp(e, props.config);
|
||||
// props.config.sendParent({
|
||||
// type: 'event',
|
||||
// column: 'select',
|
||||
// data: null,
|
||||
// });
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
selectRangeMouseUp(e, props.config);
|
||||
}}
|
||||
{...onWheelEventIframe(props.config, scaleState)}
|
||||
>
|
||||
<div
|
||||
id="yh-container"
|
||||
className={styles.yh_container}
|
||||
style={{
|
||||
height: `${state.container.height * scaleState.value}px`,
|
||||
width: `${state.container.width * scaleState.value}px`,
|
||||
backgroundColor: bgColor(),
|
||||
position: 'relative',
|
||||
overflow: 'hidden',
|
||||
...editContainerStyle,
|
||||
}}
|
||||
{...(props.context === 'edit' ? containerDragResolve(props.config) : null)}
|
||||
{...(props.context === 'edit' ? innerContainerDrag(props.config) : null)}
|
||||
{...(props.context === 'edit' ? containerFocusRemove(props.config) : null)}
|
||||
>
|
||||
{props.context === 'edit' && (
|
||||
<NormalMarkLineRender config={props.config}></NormalMarkLineRender>
|
||||
)}
|
||||
{state.block.map((v) => {
|
||||
return (
|
||||
<Blocks
|
||||
config={props.config}
|
||||
key={v.id}
|
||||
data={v}
|
||||
context={props.context}
|
||||
></Blocks>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{props.context === 'preview' && (
|
||||
<div
|
||||
id="yh-container-preview"
|
||||
className={styles.yh_container_preview}
|
||||
style={{
|
||||
height: `${getRealHeight(state.container.height)}px`,
|
||||
width: `100%`,
|
||||
position: 'relative' as 'absolute' | 'relative',
|
||||
overflow: 'hidden',
|
||||
backgroundColor: bgColor(),
|
||||
transform: transform,
|
||||
...previewContainerStyle,
|
||||
}}
|
||||
>
|
||||
{state.block.map((v) => {
|
||||
return (
|
||||
<Blocks key={v.id} config={props.config} data={v} context={props.context}></Blocks>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
export default Container;
|
Reference in New Issue
Block a user