|
@@ -0,0 +1,179 @@
|
|
|
+import React from 'react';
|
|
|
+import { Layout, Button, Typography, Flex } from 'antd';
|
|
|
+import { ArrowLeftOutlined } from '@ant-design/icons';
|
|
|
+import { useDispatch, useSelector } from 'react-redux';
|
|
|
+import { switchToOperationPanel } from '../../../states/panelSwitchSliceForView';
|
|
|
+import {
|
|
|
+ setCropAction,
|
|
|
+ setRatio,
|
|
|
+ type CropAction,
|
|
|
+ type CropRatio,
|
|
|
+} from '../../../states/view/rectCropPanelSlice';
|
|
|
+import { RootState } from '../../../states/store';
|
|
|
+import Icon from '@/components/Icon';
|
|
|
+import '@/themes/truncateText.css';
|
|
|
+
|
|
|
+const { Header, Content } = Layout;
|
|
|
+const { Title, Text } = Typography;
|
|
|
+
|
|
|
+// 功能按钮组件
|
|
|
+const FunctionButton = ({
|
|
|
+ title,
|
|
|
+ action,
|
|
|
+ iconName,
|
|
|
+}: {
|
|
|
+ title: string;
|
|
|
+ action: string;
|
|
|
+ iconName?: string;
|
|
|
+}) => {
|
|
|
+ const dispatch = useDispatch();
|
|
|
+
|
|
|
+ const handleCropAction = (action: string) => {
|
|
|
+ console.log(`执行裁剪操作: ${action}`);
|
|
|
+ dispatch(setCropAction(action as CropAction));
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Button
|
|
|
+ onClick={() => handleCropAction(action)}
|
|
|
+ icon={
|
|
|
+ iconName ? (
|
|
|
+ <Icon
|
|
|
+ module="module-process"
|
|
|
+ name={iconName}
|
|
|
+ userId="base"
|
|
|
+ theme="default"
|
|
|
+ size="2x"
|
|
|
+ state="normal"
|
|
|
+ />
|
|
|
+ ) : undefined
|
|
|
+ }
|
|
|
+ style={{
|
|
|
+ width: '1.5rem',
|
|
|
+ height: '1.5rem',
|
|
|
+ padding: 0,
|
|
|
+ }}
|
|
|
+ title={title}
|
|
|
+ className="truncate-text"
|
|
|
+ >
|
|
|
+ {!iconName && <span style={{ fontSize: '10px' }}>{title}</span>}
|
|
|
+ </Button>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+// 比例按钮组件
|
|
|
+const RatioButton = ({
|
|
|
+ ratio,
|
|
|
+ isSelected,
|
|
|
+}: {
|
|
|
+ ratio: CropRatio;
|
|
|
+ isSelected: boolean;
|
|
|
+}) => {
|
|
|
+ const dispatch = useDispatch();
|
|
|
+
|
|
|
+ const handleClick = () => {
|
|
|
+ dispatch(setRatio(ratio));
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Button
|
|
|
+ onClick={handleClick}
|
|
|
+ style={{
|
|
|
+ width: '100%',
|
|
|
+ height: '40px',
|
|
|
+ fontSize: '14px',
|
|
|
+ backgroundColor: isSelected ? '#3a3a3a' : '#2a2a2a',
|
|
|
+ color: '#fff',
|
|
|
+ borderColor: isSelected ? '#555' : '#444',
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {ratio}
|
|
|
+ </Button>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+const RectCropPanel = () => {
|
|
|
+ const dispatch = useDispatch();
|
|
|
+ const selectedRatio = useSelector(
|
|
|
+ (state: RootState) => state.rectCropPanel.selectedRatio
|
|
|
+ );
|
|
|
+
|
|
|
+ const handleReturn = () => {
|
|
|
+ dispatch(switchToOperationPanel());
|
|
|
+ };
|
|
|
+
|
|
|
+ // 比例数据,按两列排列
|
|
|
+ const ratios: CropRatio[] = [
|
|
|
+ '8x10',
|
|
|
+ '10x8',
|
|
|
+ '10x12',
|
|
|
+ '12x10',
|
|
|
+ '10x14',
|
|
|
+ '14x10',
|
|
|
+ '11x14',
|
|
|
+ '14x11',
|
|
|
+ '14x17',
|
|
|
+ '17x14',
|
|
|
+ '14x14',
|
|
|
+ '17x17',
|
|
|
+ ];
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Layout className="h-full">
|
|
|
+ {/* 顶部导航栏 */}
|
|
|
+ <Header
|
|
|
+ style={{
|
|
|
+ display: 'flex',
|
|
|
+ alignItems: 'center',
|
|
|
+ padding: '0 16px',
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Button
|
|
|
+ type="text"
|
|
|
+ icon={<ArrowLeftOutlined />}
|
|
|
+ onClick={handleReturn}
|
|
|
+ />
|
|
|
+ <Title level={5} style={{ margin: 0, lineHeight: '48px' }}>
|
|
|
+ 矩形裁剪
|
|
|
+ </Title>
|
|
|
+ </Header>
|
|
|
+
|
|
|
+ {/* 主体内容 */}
|
|
|
+ <Content
|
|
|
+ style={{ padding: '16px', maxHeight: '100%', overflowY: 'auto' }}
|
|
|
+ >
|
|
|
+ {/* 功能按钮区域 */}
|
|
|
+ <div style={{ marginBottom: '24px' }}>
|
|
|
+ <Flex wrap gap="small" align="center" justify="start" className="p-1">
|
|
|
+ <FunctionButton title="裁剪图像" action="裁剪图像" />
|
|
|
+ <FunctionButton title="撤销遮线框" action="撤销遮线框" />
|
|
|
+ <FunctionButton title="添加Mask" action="添加Mask" />
|
|
|
+ <FunctionButton title="删除Mask" action="删除Mask" />
|
|
|
+ <FunctionButton title="重新计算EXI" action="重新计算EXI" />
|
|
|
+ </Flex>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 尺寸比例选择区域 */}
|
|
|
+ <div style={{ marginBottom: '24px' }}>
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ display: 'grid',
|
|
|
+ gridTemplateColumns: '1fr 1fr',
|
|
|
+ gap: '8px',
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {ratios.map((ratio) => (
|
|
|
+ <RatioButton
|
|
|
+ key={ratio}
|
|
|
+ ratio={ratio}
|
|
|
+ isSelected={selectedRatio === ratio}
|
|
|
+ />
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </Content>
|
|
|
+ </Layout>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default RectCropPanel;
|