From de359199b8d22743a87fffd0700d69d0ebd658d5 Mon Sep 17 00:00:00 2001 From: qinhaoyan <30946345+qinhaoyan@users.noreply.github.com> Date: Thu, 10 Oct 2024 16:53:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E5=B0=BA=E5=AF=B8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/amis-editor-core/scss/editor.scss | 7 +- .../amis-editor-core/src/component/Editor.tsx | 8 - .../src/component/Preview.tsx | 27 +-- .../scss/components/_mobile-dev-tool.scss | 98 +++++++++ .../amis-ui/src/components/MobileDevTool.tsx | 205 +++++++++++++++--- 5 files changed, 280 insertions(+), 65 deletions(-) diff --git a/packages/amis-editor-core/scss/editor.scss b/packages/amis-editor-core/scss/editor.scss index c6186e57c..60317b6b1 100644 --- a/packages/amis-editor-core/scss/editor.scss +++ b/packages/amis-editor-core/scss/editor.scss @@ -286,9 +286,8 @@ border-color: #222; border-style: solid; border-radius: 30px; - width: 375px; - height: 96%; - max-height: 812px; + width: 100%; + height: 100%; flex-grow: unset; min-height: unset; min-width: unset; @@ -1971,6 +1970,8 @@ div[class*='Form-group']:empty { transform: translate(-50%, -50%); top: 53%; left: 50%; + width: 395px; + height: 687px; } } } diff --git a/packages/amis-editor-core/src/component/Editor.tsx b/packages/amis-editor-core/src/component/Editor.tsx index 535693bdf..d37cc252c 100644 --- a/packages/amis-editor-core/src/component/Editor.tsx +++ b/packages/amis-editor-core/src/component/Editor.tsx @@ -641,12 +641,6 @@ export default class Editor extends Component< )} {isMobile && ( { - this.setState({mobileDimensions: value}); - }} - onScaleChange={scale => { - this.setState({mobileScale: scale}); - }} container={this.mainPreviewRef.current} previewBody={this.mainPreviewBodyRef.current?.currentDom} /> @@ -664,8 +658,6 @@ export default class Editor extends Component< autoFocus={autoFocus} toolbarContainer={this.getToolbarContainer} readonly={readonly} - mobileDimensions={mobileDimensions} - mobileScale={mobileScale} ref={this.mainPreviewBodyRef} > diff --git a/packages/amis-editor-core/src/component/Preview.tsx b/packages/amis-editor-core/src/component/Preview.tsx index ecc034bed..ecd215b97 100644 --- a/packages/amis-editor-core/src/component/Preview.tsx +++ b/packages/amis-editor-core/src/component/Preview.tsx @@ -49,11 +49,6 @@ export interface PreviewProps { toolbarContainer?: () => any; readonly?: boolean; - mobileDimensions?: { - width: number; - height: number; - }; - mobileScale?: number; ref?: any; } @@ -166,11 +161,7 @@ export default class Preview extends Component { requestAnimationFrame(() => { this.layer!.style.cssText += `transform: translate(0, -${ this.scrollLayer!.scrollTop - }px) ${ - this.props.isMobile - ? `scale(${(this.props.mobileScale || 100) / 100})` - : '' - };`; + }px);`; }); } @@ -571,15 +562,6 @@ export default class Preview extends Component { isMobile ? 'is-mobile' : 'is-pc hoverShowScrollBar' )} ref={this.contentsRef} - style={ - isMobile - ? { - width: this.props.mobileDimensions?.width, - height: this.props.mobileDimensions?.height, - transform: `scale(${(this.props.mobileScale || 100) / 100})` - } - : undefined - } >
{!store.ready ? ( @@ -628,13 +610,6 @@ export default class Preview extends Component { onDragEnter={this.handleWidgetsDragEnter} className="ae-Preview-widgets" id="aePreviewHighlightBox" - style={ - isMobile - ? { - transform: `scale(${(this.props.mobileScale || 100) / 100})` - } - : undefined - } > {store.highlightNodes.map(node => ( void; - onScaleChange: (scale: number) => void; container: HTMLElement | null; previewBody: HTMLElement | null; }) { - const [dimension, setDimension] = React.useState(dimensions[0]); + const [dimension, setDimension] = React.useState(dimensions[1]); const [scale, setScale] = React.useState(100); const [autoScale, setAutoScale] = React.useState(100); // 记录初始时100%的尺寸 @@ -108,16 +112,16 @@ export default function MobileDevTool(props: { height: 0 }); - const {onChange, onScaleChange, container, previewBody} = props; + const {container, previewBody} = props; const resizeObserver = new ResizeObserver(debounce(updateAutoScale, 300)); useEffect(() => { - onChange?.({ + updatePreviewSize({ width: dimension.width, height: dimension.height }); - onScaleChange?.(100); + updatePreviewScale(100); // 初始化时获取预览区域的尺寸 getPreviewInitialSize(); @@ -128,6 +132,11 @@ export default function MobileDevTool(props: { if (container) { resizeObserver.unobserve(container); } + if (previewBody) { + previewBody.style.width = ''; + previewBody.style.height = ''; + previewBody.style.transform = ''; + } }; }, [container, previewBody]); @@ -161,22 +170,66 @@ export default function MobileDevTool(props: { }, 500); } - function rotateScreen() { + function handleRotateScreen() { setDimension({ name: dimension.name, width: dimension.height, height: dimension.width }); - onChange?.({ + updatePreviewSize({ width: dimension.height, height: dimension.width }); - getPreviewInitialSize(); + initialSize.current = { + width: initialSize.current.height, + height: initialSize.current.width + }; + updateAutoScale(); } function handleAutoScale() { setScale(autoScale); - onScaleChange?.(autoScale); + updatePreviewScale(autoScale); + } + + function handleDimensionChange(item: any) { + if (item) { + const value = dimensions.find(n => n.name === item.value)!; + setDimension(value); + updatePreviewSize(value); + setScale(100); + updatePreviewScale(100); + getPreviewInitialSize(); + } + } + + function handleCustomInputDimensionChange( + value: string, + type: 'width' | 'height' + ) { + const number = parseInt(value || '0', 10); + const newDimension = { + name: 'custom', + width: type === 'width' ? number : dimension.width, + height: type === 'height' ? number : dimension.height + }; + setDimension(newDimension); + updatePreviewSize(newDimension); + } + + function updatePreviewSize(dimension: {width: number; height: number}) { + if (previewBody) { + // 预览区域宽高加上20px的padding + previewBody.style.width = dimension.width + 20 + 'px'; + previewBody.style.height = dimension.height + 20 + 'px'; + } + } + + function updatePreviewScale(scale: number) { + if (previewBody) { + previewBody.style.transform = + 'translate(-50%, -50%) scale(' + scale / 100 + ')'; + } } return ( @@ -186,30 +239,42 @@ export default function MobileDevTool(props: { { + const value = event.currentTarget.value; + + handleCustomInputDimensionChange(value, 'width'); + }} + /> + ) : ( + {dimension.width} + )} × - {dimension.height} + {dimension.name === 'custom' ? ( + { + const value = event.currentTarget.value; + + handleCustomInputDimensionChange(value, 'height'); + }} + /> + ) : ( + {dimension.height} + )}
@@ -225,7 +290,7 @@ export default function MobileDevTool(props: { ]} onChange={(item: any) => { setScale(item.value); - onScaleChange?.(item.value); + updatePreviewScale(item.value); }} /> {!scaleList.includes(scale) && ( @@ -240,13 +305,97 @@ export default function MobileDevTool(props: { 自适应
-
+
+ {dimension.name === 'custom' && ( + { + setDimension({ + name: 'custom', + width: w - 20, + height: h - 20 + }); + }} + /> + )} ); } + +function CustomSizeHandle(props: { + previewBody: HTMLElement | null; + onChange?: (w: number, h: number) => void; +}) { + const {previewBody, onChange} = props; + + function handleRightDown(e: any) { + e.stopPropagation(); + e.preventDefault(); + document.body.classList.add('width-move'); + document.addEventListener('mousemove', handleRightDragMove); + document.addEventListener('mouseup', handleRightDragEnd); + } + + function handleRightDragMove(e: any) { + e.stopPropagation(); + if (previewBody) { + let w = previewBody.clientWidth; + w += e.movementX; + w = Math.max(20, w); + previewBody.style.width = w + 'px'; + onChange?.(w, previewBody.clientHeight); + } + } + + function handleRightDragEnd() { + document.body.classList.remove('width-move'); + document.removeEventListener('mousemove', handleRightDragMove); + document.removeEventListener('mouseup', handleRightDragEnd); + } + + function handleBottomDown(e: any) { + e.stopPropagation(); + e.preventDefault(); + document.body.classList.add('height-move'); + document.addEventListener('mousemove', handleBottomDragMove); + document.addEventListener('mouseup', handleBottomDragEnd); + } + + function handleBottomDragMove(e: any) { + e.stopPropagation(); + if (previewBody) { + let h = previewBody.clientHeight; + h += e.movementY; + h = Math.max(20, h); + previewBody.style.height = h + 'px'; + onChange?.(previewBody.clientWidth, h); + } + } + + function handleBottomDragEnd() { + document.body.classList.remove('height-move'); + document.removeEventListener('mousemove', handleBottomDragMove); + document.removeEventListener('mouseup', handleBottomDragEnd); + } + + return ( + previewBody}> + <> +
+
+ +
+ ); +}