feat(zhst/biz): 添加大图组件v2
This commit is contained in:
parent
a501656907
commit
ce6a719bc2
12
.fatherrc.ts
12
.fatherrc.ts
@ -1,5 +1,15 @@
|
|||||||
import { defineConfig } from 'father';
|
import { defineConfig } from 'father-plugin-less';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
|
esm: {
|
||||||
|
output: 'es',
|
||||||
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
|
},
|
||||||
|
cjs: {
|
||||||
|
output: 'lib',
|
||||||
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
"dumi": "^2.2.13",
|
"dumi": "^2.2.13",
|
||||||
"eslint": "^8.23.0",
|
"eslint": "^8.23.0",
|
||||||
"father": "^4.1.0",
|
"father": "^4.1.0",
|
||||||
|
"father-plugin-less": "^0.0.2",
|
||||||
"husky": "^8.0.1",
|
"husky": "^8.0.1",
|
||||||
"lerna": "^8.0.0",
|
"lerna": "^8.0.0",
|
||||||
"lint-staged": "^13.0.3",
|
"lint-staged": "^13.0.3",
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { defineConfig } from 'father';
|
import { defineConfig } from 'father-plugin-less';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: {
|
esm: {
|
||||||
output: 'es',
|
output: 'es',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
cjs: {
|
cjs: {
|
||||||
output: 'lib',
|
output: 'lib',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
|
plugins: ['father-plugin-less'],
|
||||||
});
|
});
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
"registry": "http://10.0.0.77:4874"
|
"registry": "http://10.0.0.77:4874"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@swc/core": "^1.3.9",
|
||||||
"@zhst/types": "workspace:^"
|
"@zhst/types": "workspace:^"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
304
packages/biz/src/BigImage/BigImage.tsx
Normal file
304
packages/biz/src/BigImage/BigImage.tsx
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
import React, { forwardRef, useImperativeHandle, useRef } from 'react'
|
||||||
|
import {
|
||||||
|
ConfigProvider,
|
||||||
|
Descriptions,
|
||||||
|
CropperImage,
|
||||||
|
AttachImage,
|
||||||
|
VideoPlayer,
|
||||||
|
RelatedImage,
|
||||||
|
Radio,
|
||||||
|
Tooltip,
|
||||||
|
Button,
|
||||||
|
Tabs
|
||||||
|
} from '@zhst/meta';
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import { IconFont } from '@zhst/icon'
|
||||||
|
import { BigImageProps, BigImageRef } from './interface'
|
||||||
|
import CombineImage from './components/CombineImage'
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
|
const DescriptionsItem = Descriptions.Item
|
||||||
|
|
||||||
|
export const componentPrefix = 'zhst-big-image'
|
||||||
|
|
||||||
|
const initialStyle ={
|
||||||
|
fontSize: '12px'
|
||||||
|
}
|
||||||
|
|
||||||
|
const BigImage = forwardRef<BigImageRef, BigImageProps>((props, ref) => {
|
||||||
|
const {
|
||||||
|
// ------------ 通用配置 -------------------
|
||||||
|
type,
|
||||||
|
viewHeight,
|
||||||
|
width = '100%',
|
||||||
|
children,
|
||||||
|
// ------------ 顶部按钮 -----------------
|
||||||
|
topButtonRender,
|
||||||
|
// ------------ 描述 -----------------
|
||||||
|
descriptionList = [],
|
||||||
|
showDescription,
|
||||||
|
// ------------- tab 导航 ----------------
|
||||||
|
customTabBarExtraContent,
|
||||||
|
tabProps,
|
||||||
|
onTabChange,
|
||||||
|
// ------------- 场景图 -------------
|
||||||
|
cropperImageProps = {
|
||||||
|
cropButtonList: []
|
||||||
|
},
|
||||||
|
// ----------------- 对比图 ---------------------
|
||||||
|
combineImageProps,
|
||||||
|
// ------------ 视频模式 -----------------
|
||||||
|
videoProps,
|
||||||
|
// ------------ view 操作按钮 -----------------
|
||||||
|
showModeChange,
|
||||||
|
modeButtonGroupProps,
|
||||||
|
viewTopModeButtonList = [
|
||||||
|
{
|
||||||
|
key: 'image',
|
||||||
|
label: '图片'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'video',
|
||||||
|
label: '视频'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// ------------------ 翻页 ----------------------
|
||||||
|
showNavigation,
|
||||||
|
prevButtonProps,
|
||||||
|
onPrevButtonClick,
|
||||||
|
onNextButtonClick,
|
||||||
|
nextButtonProps,
|
||||||
|
// ------------------ 人脸碰撞模型 -----------------
|
||||||
|
relatedImageProps,
|
||||||
|
isRelated = false,
|
||||||
|
theme,
|
||||||
|
} = props
|
||||||
|
const combineImageRef = useRef<any>(null)
|
||||||
|
const videoPlayerRef = useRef<any>(null)
|
||||||
|
const cropperImageRef = useRef<any>(null)
|
||||||
|
|
||||||
|
cropperImageProps.cropButtonList = cropperImageProps?.cropButtonList || [
|
||||||
|
{
|
||||||
|
key: 'auto',
|
||||||
|
icon: <IconFont icon='icon-zidong' />,
|
||||||
|
label: '智能框选',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'custom',
|
||||||
|
icon: <IconFont icon='icon-shoudong' />,
|
||||||
|
label: '手动框选',
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// ------------------- 初始化模式 ----------------------
|
||||||
|
const initMode = (type: BigImageProps['type'] = 'normal') => {
|
||||||
|
switch (type) {
|
||||||
|
case 'compater':
|
||||||
|
return (
|
||||||
|
<CombineImage
|
||||||
|
// @ts-ignore
|
||||||
|
ref={combineImageRef}
|
||||||
|
height={viewHeight}
|
||||||
|
{...combineImageProps}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
case 'normal':
|
||||||
|
return (
|
||||||
|
<div style={{ height: viewHeight, width: '100%' }}>
|
||||||
|
<CropperImage
|
||||||
|
ref={cropperImageRef}
|
||||||
|
type='rect'
|
||||||
|
// @ts-ignore
|
||||||
|
height={viewHeight}
|
||||||
|
{...cropperImageProps}
|
||||||
|
>
|
||||||
|
{/* // ------------ 显示条件:当不为编辑状态,并且有图片值 ----------------- */}
|
||||||
|
{!cropperImageProps?.editAble && cropperImageProps?.attachImageData && (
|
||||||
|
<>
|
||||||
|
<AttachImage
|
||||||
|
data={cropperImageProps?.attachImageData}
|
||||||
|
{...cropperImageProps?.attachImageProps}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
right: '4px',
|
||||||
|
bottom: '4px',
|
||||||
|
fontSize: '18px',
|
||||||
|
color: 'red',
|
||||||
|
cursor: 'default'
|
||||||
|
}}
|
||||||
|
>{`人脸质量分:${(Number(cropperImageProps?.score) as number).toFixed(2)}`}</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{/* // ------------ 场景图绘制工具栏 ----------------- */}
|
||||||
|
{cropperImageProps?.showEditTools && (
|
||||||
|
<div className={`${componentPrefix}-view-cropper-btn`}>
|
||||||
|
<Radio.Group
|
||||||
|
className={`${componentPrefix}-view-cropper-btn-group`}
|
||||||
|
size="small"
|
||||||
|
buttonStyle='solid'
|
||||||
|
// @ts-ignore
|
||||||
|
onChange={cropperImageProps?.onCropperTypeChange}
|
||||||
|
{...cropperImageProps.btnGroupProps}
|
||||||
|
>
|
||||||
|
{cropperImageProps?.cropButtonList?.map(btn => (
|
||||||
|
<Tooltip key={btn.key} title={btn.label}>
|
||||||
|
{/* @ts-ignore */}
|
||||||
|
<Radio.Button value={btn.key}{...btn.props}><div className={`${componentPrefix}-view-cropper-btn-group-radio`}>{btn.icon} {btn.label}</div></Radio.Button>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
<Button onClick={cropperImageProps?.onExitEdit} className={`${componentPrefix}-view-cropper-btn_close`} type="primary" size="small" icon={<IconFont icon="icon-danchuangguanbi" />} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</CropperImage>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
case 'video':
|
||||||
|
return (
|
||||||
|
// @ts-ignore
|
||||||
|
<VideoPlayer ref={videoPlayerRef} height={viewHeight} {...videoProps} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露 ref 实例
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
// @ts-ignore
|
||||||
|
cropperImageRef: cropperImageRef?.current,
|
||||||
|
videoPlayerRef: videoPlayerRef?.current,
|
||||||
|
combineImageRef: combineImageRef?.current,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(`${componentPrefix}-view`)}
|
||||||
|
style={{ width: `${parseInt(width as string)}px` }}
|
||||||
|
>
|
||||||
|
<div className={classNames(`${componentPrefix}-view-btns`)}>
|
||||||
|
{topButtonRender}
|
||||||
|
</div>
|
||||||
|
{showDescription && (
|
||||||
|
<div
|
||||||
|
className={classNames(`${componentPrefix}-view-desc`)}
|
||||||
|
>
|
||||||
|
<ConfigProvider
|
||||||
|
theme={{
|
||||||
|
components: {
|
||||||
|
Descriptions: {
|
||||||
|
viewBg: '#f6f6f6',
|
||||||
|
colorBgLayout:'#ccc',
|
||||||
|
titleColor: 'rgba(0,0,0,0.45)',
|
||||||
|
colorTextLabel: 'rgba(0,0,0,0.45)',
|
||||||
|
contentColor: 'rgba(0,0,0,0.88)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...theme
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{descriptionList.map(descriptions => (
|
||||||
|
<Descriptions
|
||||||
|
key={descriptions.title}
|
||||||
|
title={descriptions.showTitle && descriptions.title}
|
||||||
|
column={8}
|
||||||
|
{...descriptions.props}
|
||||||
|
>
|
||||||
|
{descriptions?.children?.map(item => (
|
||||||
|
<DescriptionsItem
|
||||||
|
key={item.key}
|
||||||
|
label={item.label}
|
||||||
|
span={1}
|
||||||
|
contentStyle={{ fontSize: initialStyle.fontSize }}
|
||||||
|
labelStyle={{ fontSize: initialStyle.fontSize }}
|
||||||
|
>{item.children}</DescriptionsItem>
|
||||||
|
))}
|
||||||
|
</Descriptions>
|
||||||
|
))}
|
||||||
|
</ConfigProvider>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<Tabs
|
||||||
|
tabBarExtraContent={customTabBarExtraContent}
|
||||||
|
onChange={onTabChange}
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
label: `场景图`,
|
||||||
|
key: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: `对比图`,
|
||||||
|
key: '2',
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
{...tabProps}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className={classNames(`${componentPrefix}-view-container`)}
|
||||||
|
>
|
||||||
|
{/* ---------------- view 视图左上角导航按钮 ------------------ */}
|
||||||
|
{showModeChange && (
|
||||||
|
<div
|
||||||
|
className={classNames(`${componentPrefix}-view-container-modeNav`)}
|
||||||
|
>
|
||||||
|
<Radio.Group
|
||||||
|
buttonStyle='solid'
|
||||||
|
size='small'
|
||||||
|
{...modeButtonGroupProps}
|
||||||
|
>
|
||||||
|
{viewTopModeButtonList?.map(btn => (
|
||||||
|
<Tooltip key={btn.key} title={btn.tooltipTxt}>
|
||||||
|
{/* @ts-ignore */}
|
||||||
|
<Radio.Button value={btn.key} {...btn.props}>{btn.icon} {btn.label}</Radio.Button>
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</Radio.Group>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{/* --------------------------------- 视频播放模式 --------------------------------- */}
|
||||||
|
{initMode(type)}
|
||||||
|
{/* 切换按钮组件 */}
|
||||||
|
{/* ----------------------------------- 上一张按钮 ---------------------------------- */}
|
||||||
|
{showNavigation && (
|
||||||
|
<Button
|
||||||
|
className={classNames(
|
||||||
|
`${componentPrefix}-view-container-nav`,
|
||||||
|
`${componentPrefix}-view-container-nav_left`
|
||||||
|
)}
|
||||||
|
icon={<IconFont icon="icon-qiehuanzuo" />}
|
||||||
|
type="primary"
|
||||||
|
// style={{ backgroundColor: 'rgba(255,255,255,0.8)' }}
|
||||||
|
shape='circle'
|
||||||
|
onClick={onPrevButtonClick}
|
||||||
|
{...prevButtonProps}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{/* ----------------------------------- 下一张按钮 ---------------------------------- */}
|
||||||
|
{showNavigation && (
|
||||||
|
<Button
|
||||||
|
className={classNames(
|
||||||
|
`${componentPrefix}-view-container-nav`,
|
||||||
|
`${componentPrefix}-view-container-nav_right`
|
||||||
|
)}
|
||||||
|
icon={<IconFont icon="icon-qiehuanyou" />}
|
||||||
|
type="primary"
|
||||||
|
// style={{ backgroundColor: 'rgba(255,255,255,0.8)' }}
|
||||||
|
shape='circle'
|
||||||
|
onClick={onNextButtonClick}
|
||||||
|
{...nextButtonProps}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/* ----------------------------------- 人脸碰撞组件 ---------------------------------- */}
|
||||||
|
{isRelated && (
|
||||||
|
// @ts-ignore
|
||||||
|
<RelatedImage
|
||||||
|
{...relatedImageProps}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default BigImage
|
@ -0,0 +1,3 @@
|
|||||||
|
.zhst-big-image-combime-image {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
}
|
82
packages/biz/src/BigImage/components/CombineImage/index.tsx
Normal file
82
packages/biz/src/BigImage/components/CombineImage/index.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
import React, { FC, useRef, forwardRef, useImperativeHandle } from 'react';
|
||||||
|
import { CompareImage, Flex, Progress, ProgressProps, CompareImageProps } from '@zhst/meta'
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
|
export interface ComBineImageProps {
|
||||||
|
height?: string | number
|
||||||
|
data: {
|
||||||
|
imgSummary: string;
|
||||||
|
compaterImage: string;
|
||||||
|
imageKey: string;
|
||||||
|
score: number;
|
||||||
|
}
|
||||||
|
prevDisable?: boolean;
|
||||||
|
nextDisable?: boolean;
|
||||||
|
onPre?: () => void;
|
||||||
|
onNext?: () => void;
|
||||||
|
openRoll?: boolean
|
||||||
|
targetImageProps?: CompareImageProps
|
||||||
|
sourceImageProps?: CompareImageProps
|
||||||
|
}
|
||||||
|
|
||||||
|
const conicColors: ProgressProps['strokeColor'] = {
|
||||||
|
'0%': '#42E2AC',
|
||||||
|
'50%': '#DFAF2E',
|
||||||
|
'100%': '#F95C55',
|
||||||
|
};
|
||||||
|
|
||||||
|
const componentName = 'zhst-big-image-combime-image'
|
||||||
|
|
||||||
|
const ComBineImage: FC<ComBineImageProps> = forwardRef((props, ref) => {
|
||||||
|
const {
|
||||||
|
height,
|
||||||
|
data,
|
||||||
|
prevDisable,
|
||||||
|
nextDisable,
|
||||||
|
onNext,
|
||||||
|
onPre,
|
||||||
|
openRoll
|
||||||
|
} = props
|
||||||
|
const { imgSummary, compaterImage, score } = data
|
||||||
|
const targetImageRef = useRef(null)
|
||||||
|
const compareImageRef = useRef(null)
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => ({
|
||||||
|
compareImageRef,
|
||||||
|
targetImageRef
|
||||||
|
}));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex className={componentName} justify='space-between' align='center' >
|
||||||
|
<CompareImage
|
||||||
|
ref={targetImageRef}
|
||||||
|
height={height}
|
||||||
|
width="400px"
|
||||||
|
preDisable={prevDisable}
|
||||||
|
nextDisable={nextDisable}
|
||||||
|
onNext={onNext}
|
||||||
|
onPre={onPre}
|
||||||
|
showScore={false}
|
||||||
|
openRoll={openRoll}
|
||||||
|
url={imgSummary}
|
||||||
|
label="目标图"
|
||||||
|
{...props.targetImageProps}
|
||||||
|
/>
|
||||||
|
<Progress type="circle" size={72} strokeWidth={6} percent={Number(score || 0)} strokeColor={conicColors} />
|
||||||
|
<CompareImage
|
||||||
|
ref={compareImageRef}
|
||||||
|
width="400px"
|
||||||
|
height={height}
|
||||||
|
url={compaterImage}
|
||||||
|
openRoll={false}
|
||||||
|
score={score}
|
||||||
|
label="预警图"
|
||||||
|
labelColor='#FA5852'
|
||||||
|
{...props.sourceImageProps}
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
export default ComBineImage
|
44
packages/biz/src/BigImage/components/navigation/index.less
Normal file
44
packages/biz/src/BigImage/components/navigation/index.less
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
.zhst-image__nav {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
width: 48px;
|
||||||
|
height: 100%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0;
|
||||||
|
|
||||||
|
&>button {
|
||||||
|
& span {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:global {
|
||||||
|
i:hover {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disable {
|
||||||
|
:global {
|
||||||
|
i {
|
||||||
|
color: #f0f0f0;
|
||||||
|
cursor: not-allowed !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-prev {
|
||||||
|
left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-next {
|
||||||
|
right: 12px;
|
||||||
|
}
|
||||||
|
}
|
40
packages/biz/src/BigImage/components/navigation/index.tsx
Normal file
40
packages/biz/src/BigImage/components/navigation/index.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// !! 已废弃
|
||||||
|
import * as React from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { Button } from '@zhst/meta';
|
||||||
|
import { IconFont } from '@zhst/icon'
|
||||||
|
import './index.less';
|
||||||
|
|
||||||
|
const componentName = `zhst-image__nav`;
|
||||||
|
|
||||||
|
const Navigation: React.FC<{
|
||||||
|
show?: boolean;
|
||||||
|
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||||
|
prev?: boolean;
|
||||||
|
next?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
|
className?: string;
|
||||||
|
color?: string;
|
||||||
|
hoverColor?: string;
|
||||||
|
}> = (props) => {
|
||||||
|
const { show, prev, next, disabled, onClick, className, color } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classnames(
|
||||||
|
`${componentName}`,
|
||||||
|
prev && `${componentName}-prev`,
|
||||||
|
next && `${componentName}-next`,
|
||||||
|
disabled && `${componentName}--disable`,
|
||||||
|
!show && `${componentName}--hide`,
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Button type="text" disabled={disabled} shape='circle' onClick={onClick}>
|
||||||
|
<IconFont size={28} color={color} icon={prev ? 'icon-qiehuanzuo' : 'icon-qiehuanyou'} />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Navigation;
|
Binary file not shown.
After Width: | Height: | Size: 143 KiB |
71
packages/biz/src/BigImage/demo/index.tsx
Normal file
71
packages/biz/src/BigImage/demo/index.tsx
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import { BigImage } from '@zhst/biz'
|
||||||
|
import { Space, Switch } from '@zhst/meta'
|
||||||
|
import { pick, get } from '@zhst/func'
|
||||||
|
import { BIG_IMAGE_DATA, attributeList } from '../mock'
|
||||||
|
import Img from './imgs/photo-1503185912284-5271ff81b9a8.webp'
|
||||||
|
|
||||||
|
const BigModal = (props: any) => {
|
||||||
|
const {
|
||||||
|
} = props
|
||||||
|
const [dataSource, setDataSource] = useState(BIG_IMAGE_DATA)
|
||||||
|
const [showDesc, setShowDesc] = useState(true)
|
||||||
|
const [type, setType] = useState('normal')
|
||||||
|
const modalRef = useRef(null)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '32px', border: '1px solid #09f' }}>
|
||||||
|
<Space>
|
||||||
|
<span>显示属性:<Switch value={showDesc} onChange={e => setShowDesc(pre => !pre)} /></span>
|
||||||
|
</Space>
|
||||||
|
<BigImage
|
||||||
|
type={type}
|
||||||
|
ref={modalRef}
|
||||||
|
width={896}
|
||||||
|
viewHeight={'440px'}
|
||||||
|
showModeChange
|
||||||
|
onTabChange={(newVal) => setType(newVal === '1'? 'normal': 'compater')}
|
||||||
|
// ------------ 属性列表 -----------------
|
||||||
|
showDescription={showDesc}
|
||||||
|
descriptionList={attributeList}
|
||||||
|
// ------------ 图片/视频切换 -----------------
|
||||||
|
viewTopModeButtonList={[
|
||||||
|
{
|
||||||
|
key: 'image',
|
||||||
|
label: '图片'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'video',
|
||||||
|
label: '视频'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
modeButtonGroupProps={{
|
||||||
|
defaultValue: 'image',
|
||||||
|
onChange: e => console.log('模式切换', e)
|
||||||
|
}}
|
||||||
|
// ------------ 导航功能 -----------------
|
||||||
|
showNavigation
|
||||||
|
onPrevButtonClick={val => console.log('pre', val)}
|
||||||
|
onNextButtonClick={val => console.log('next', val)}
|
||||||
|
// ------------ 场景图功能 -----------------
|
||||||
|
cropperImageProps={{
|
||||||
|
url: Img,
|
||||||
|
score: 50,
|
||||||
|
odList: get(dataSource, 'odRect', []),
|
||||||
|
attachImageData: get(dataSource, 'attachImg', []),
|
||||||
|
}}
|
||||||
|
// ------------ 对比图模式 -----------------
|
||||||
|
combineImageProps={{
|
||||||
|
data: pick(dataSource, 'compaterImage', 'imgSummary', 'imageKey', 'score'),
|
||||||
|
}}
|
||||||
|
// ------------ 视频模块 -----------------
|
||||||
|
videoProps={{
|
||||||
|
url: get(dataSource, 'flvUrl', '')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
</BigImage>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BigModal
|
128
packages/biz/src/BigImage/demo/oldData.tsx
Normal file
128
packages/biz/src/BigImage/demo/oldData.tsx
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { BigImageModal } from '@zhst/biz'
|
||||||
|
import { Button, DescriptionsProps } from '@zhst/meta'
|
||||||
|
import { IMAGE_DATA, BIG_IMAGE_DATA } from '../mock'
|
||||||
|
import bigImageModalAdapter from '../util/bigImageModalAdapter'
|
||||||
|
import { get } from '@zhst/func';
|
||||||
|
|
||||||
|
const descriptionList: DescriptionsProps['items'] = [
|
||||||
|
{
|
||||||
|
title: '人员属性',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
label: '性别',
|
||||||
|
children: '男',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
label: '年龄',
|
||||||
|
children: '成年',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
label: '帽子',
|
||||||
|
children: '无',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '4',
|
||||||
|
label: '上身颜色',
|
||||||
|
children: '灰',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '5',
|
||||||
|
label: '下身颜色',
|
||||||
|
children: '蓝色',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '6',
|
||||||
|
label: '附着物',
|
||||||
|
children: '无',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '7',
|
||||||
|
label: '骑行',
|
||||||
|
children: '否',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// 适配器,适配老接口
|
||||||
|
const NewImageModal = bigImageModalAdapter(BigImageModal, {
|
||||||
|
oldMode: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const BigModal = (props) => {
|
||||||
|
const {
|
||||||
|
onClose,
|
||||||
|
isArchiveDetail = false,
|
||||||
|
specialTitle = '对比图2',
|
||||||
|
transformPropFunc,
|
||||||
|
screenshotButtonRender,
|
||||||
|
showLowFaceTip = false
|
||||||
|
} = props
|
||||||
|
const [visible, setVisible] = useState(false)
|
||||||
|
const [selectIndex, setSelectIndex] = useState(0)
|
||||||
|
const [dataSource, setDataSource] = useState(IMAGE_DATA.dataSource)
|
||||||
|
const [dataSources, setDataSources] = useState(IMAGE_DATA.dataSource)
|
||||||
|
const [selectItem, setSelectItem] = useState({})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button onClick={() => setVisible(true)} >查看大图</Button>
|
||||||
|
<NewImageModal
|
||||||
|
title="查看大图"
|
||||||
|
dataSource={dataSource}
|
||||||
|
imageData={dataSource}
|
||||||
|
width={1098}
|
||||||
|
onClose={() => onClose}
|
||||||
|
descriptionConfig={{ data: descriptionList }}
|
||||||
|
visible={visible}
|
||||||
|
isArchiveDetail={isArchiveDetail}
|
||||||
|
ToolProps={{
|
||||||
|
// renderLeft: leftOperateBar({ disableBtn, onActionClick: onBigImageActionClick }),
|
||||||
|
// renderRight: rightOperateBar({
|
||||||
|
// disableBtn,
|
||||||
|
// onActionClick: onBigImageActionClick,
|
||||||
|
// isArchiveDetail,
|
||||||
|
// }),
|
||||||
|
// renderVideoBtn: !disableBtn.includes(OPT['PLAY_VIDEO']),
|
||||||
|
// disableVideo: disableVideo,
|
||||||
|
}}
|
||||||
|
selectIndex={selectIndex}
|
||||||
|
onSelectIndexChange={(index: number) => {
|
||||||
|
index > 0 && index < dataSources.length && setSelectIndex(index);
|
||||||
|
}}
|
||||||
|
// tabsFilter={tabsFilter}
|
||||||
|
specialTitle={specialTitle}
|
||||||
|
transformPropFunc={async (item: any) => {
|
||||||
|
let bigImageInfo = !!transformPropFunc && (await transformPropFunc(item));
|
||||||
|
setSelectItem({ ...bigImageInfo });
|
||||||
|
return { ...bigImageInfo };
|
||||||
|
}}
|
||||||
|
screenshotButtonRender={screenshotButtonRender}
|
||||||
|
//@ts-ignore
|
||||||
|
transformVideoPropFunc={async (item) => {
|
||||||
|
const { maxDuration: duration = 20 } = item || {};
|
||||||
|
const time = get(item, 'timestamp');
|
||||||
|
const cameraId = get(item, 'cameraId');
|
||||||
|
const { url: flvUrl } = {
|
||||||
|
url: 'url',
|
||||||
|
downloadUrl: 'url',
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
flvUrl,
|
||||||
|
maxDuration: duration,
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
nullDialogProp={{
|
||||||
|
emptyText: showLowFaceTip ? '目标图人脸质量较低,暂无聚类数据' : '暂无数据',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BigModal
|
89
packages/biz/src/BigImage/demo/withEdit.tsx
Normal file
89
packages/biz/src/BigImage/demo/withEdit.tsx
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import { BigImage } from '@zhst/biz'
|
||||||
|
import { Space, Switch, Button } from '@zhst/meta'
|
||||||
|
import { pick, get } from '@zhst/func'
|
||||||
|
import { BIG_IMAGE_DATA, attributeList } from '../mock'
|
||||||
|
import Img from './imgs/photo-1503185912284-5271ff81b9a8.webp'
|
||||||
|
|
||||||
|
const testOd = [
|
||||||
|
{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.58543766,
|
||||||
|
"y": 0.3203356,
|
||||||
|
"w": 0.052037954,
|
||||||
|
"h": 0.2664015
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const BigModal = (props: any) => {
|
||||||
|
const {
|
||||||
|
} = props
|
||||||
|
const [dataSource, setDataSource] = useState(BIG_IMAGE_DATA)
|
||||||
|
const [showDesc, setShowDesc] = useState(true)
|
||||||
|
const [editAble, setEditAble] = useState(false)
|
||||||
|
const [odList, setOdList] = useState(get(dataSource, 'odRect', []))
|
||||||
|
const [type, setType] = useState('normal')
|
||||||
|
const bigImageRef = useRef(null)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '32px', border: '1px solid #09f' }}>
|
||||||
|
<Space>
|
||||||
|
<span>显示属性:<Switch value={showDesc} onChange={e => setShowDesc(pre => !pre)} /></span>
|
||||||
|
<span>打开编辑模式:<Switch value={editAble} onChange={e => setEditAble(pre => !pre)} /></span>
|
||||||
|
<Button onClick={() => setOdList(testOd)}>修改Od</Button>
|
||||||
|
</Space>
|
||||||
|
<BigImage
|
||||||
|
type={type}
|
||||||
|
ref={bigImageRef}
|
||||||
|
width={896}
|
||||||
|
viewHeight={'440px'}
|
||||||
|
showModeChange
|
||||||
|
onTabChange={(newVal) => setType(newVal === '1'? 'normal': 'compater')}
|
||||||
|
// ------------ 属性列表 -----------------
|
||||||
|
showDescription={showDesc}
|
||||||
|
descriptionList={attributeList}
|
||||||
|
// ------------ 图片/视频切换 -----------------
|
||||||
|
viewTopModeButtonList={[
|
||||||
|
{
|
||||||
|
key: 'image',
|
||||||
|
label: '图片'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'video',
|
||||||
|
label: '视频'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
modeButtonGroupProps={{
|
||||||
|
defaultValue: 'image',
|
||||||
|
onChange: e => console.log('模式切换', e)
|
||||||
|
}}
|
||||||
|
// ------------ 导航功能 -----------------
|
||||||
|
showNavigation
|
||||||
|
onPrevButtonClick={val => console.log('pre', val)}
|
||||||
|
onNextButtonClick={val => console.log('next', val)}
|
||||||
|
// ------------ 场景图功能 -----------------
|
||||||
|
cropperImageProps={{
|
||||||
|
editAble,
|
||||||
|
url: Img,
|
||||||
|
score: 50,
|
||||||
|
odList: odList,
|
||||||
|
showEditTools: editAble,
|
||||||
|
attachImageData: get(dataSource, 'attachImg', []),
|
||||||
|
onCropperTypeChange: v => console.log('框选模式', v),
|
||||||
|
onExitEdit: () => setEditAble(pre => !pre)
|
||||||
|
}}
|
||||||
|
// ------------ 对比图模式 -----------------
|
||||||
|
combineImageProps={{
|
||||||
|
data: pick(dataSource, 'compaterImage', 'imgSummary', 'imageKey', 'score'),
|
||||||
|
}}
|
||||||
|
// ------------ 视频模块 -----------------
|
||||||
|
videoProps={{
|
||||||
|
url: get(dataSource, 'flvUrl', '')
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
</BigImage>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BigModal
|
78
packages/biz/src/BigImage/demo/withRelatedImage.tsx
Normal file
78
packages/biz/src/BigImage/demo/withRelatedImage.tsx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import { BigImage } from '@zhst/biz'
|
||||||
|
import { Button, Space, Switch } from '@zhst/meta'
|
||||||
|
import { pick, get } from '@zhst/func'
|
||||||
|
import { BIG_IMAGE_DATA, attributeList, RELATED_IMAGES } from '../mock'
|
||||||
|
|
||||||
|
const BigModal = (props: any) => {
|
||||||
|
const {
|
||||||
|
} = props
|
||||||
|
const [visible, setVisible] = useState(true)
|
||||||
|
const [dataSource, setDataSource] = useState(BIG_IMAGE_DATA)
|
||||||
|
const [selectedItemKey, setSelectedItemKey] = useState()
|
||||||
|
const [showFaceModel, setShowFaceModel] = useState(true)
|
||||||
|
const [type, setType] = useState('normal')
|
||||||
|
const modalRef = useRef(null)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '32px', border: '1px solid #09f' }}>
|
||||||
|
<Space>
|
||||||
|
<span>显示人脸碰撞模型:<Switch value={showFaceModel} onChange={e => setShowFaceModel(pre => !pre)} /></span>
|
||||||
|
</Space>
|
||||||
|
<BigImage
|
||||||
|
type={type}
|
||||||
|
open={visible}
|
||||||
|
ref={modalRef}
|
||||||
|
viewHeight={'440px'}
|
||||||
|
width={896}
|
||||||
|
onCancel={() => setVisible(false)}
|
||||||
|
showModeChange
|
||||||
|
onTabChange={(newVal, oldVal) => setType(newVal === '1'? 'normal': 'compater')}
|
||||||
|
// ------------ 图片/视频切换 -----------------
|
||||||
|
viewTopModeButtonList={[
|
||||||
|
{
|
||||||
|
key: 'image',
|
||||||
|
label: '图片'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'video',
|
||||||
|
label: '视频'
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
modeButtonGroupProps={{
|
||||||
|
defaultValue: 'image',
|
||||||
|
onChange: e => console.log('模式切换', e)
|
||||||
|
}}
|
||||||
|
// ------------ 场景图功能 -----------------
|
||||||
|
cropperImageProps={{
|
||||||
|
url: "https://gw.alipayobjects.com/zos/antfincdn/LlvErxo8H9/photo-1503185912284-5271ff81b9a8.webp",
|
||||||
|
score: 50,
|
||||||
|
odList: get(dataSource, 'odRect', []),
|
||||||
|
attachImageData: get(dataSource, 'attachImg', []),
|
||||||
|
}}
|
||||||
|
// ------------ 对比图模式 -----------------
|
||||||
|
combineImageProps={{
|
||||||
|
data: pick(dataSource, 'compaterImage', 'imgSummary', 'imageKey', 'score'),
|
||||||
|
}}
|
||||||
|
// ------------ 视频模块 -----------------
|
||||||
|
videoProps={{
|
||||||
|
url: get(dataSource, 'flvUrl', '')
|
||||||
|
}}
|
||||||
|
// ------------ 人脸碰撞模型 -----------------
|
||||||
|
isRelated={showFaceModel}
|
||||||
|
relatedImageProps={{
|
||||||
|
activeTab: 'related',
|
||||||
|
selectedItemKey,
|
||||||
|
data: RELATED_IMAGES,
|
||||||
|
onCancel: () => console.log('取消关联'),
|
||||||
|
onConnect: () => console.log('关联'),
|
||||||
|
onTabChange: (newVal, oldVal) => console.log('tab切换', newVal, oldVal),
|
||||||
|
onItemSelected: (item) => setSelectedItemKey(item.key)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
</BigImage>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BigModal
|
BIN
packages/biz/src/BigImage/images/emptyImage.png
Normal file
BIN
packages/biz/src/BigImage/images/emptyImage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
BIN
packages/biz/src/BigImage/images/percent_background.png
Normal file
BIN
packages/biz/src/BigImage/images/percent_background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 514 B |
132
packages/biz/src/BigImage/index.less
Normal file
132
packages/biz/src/BigImage/index.less
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
.zhst-big-image {
|
||||||
|
.zhst-dialog-content {
|
||||||
|
box-shadow: 0 4px 12px rgb(0 0 0 / 20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.zhst-tabs .zhst-tabs-nav-wrap {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-view {
|
||||||
|
&-btns {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
&-desc {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding: 16px 16px 0 16px;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
.zhst-descriptions-header {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.zhst-descriptions-title {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ------------ tab -----------------
|
||||||
|
.zhst-tabs-nav {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
.zhst-tabs-tab {
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
padding: 0;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
&::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-container {
|
||||||
|
position: relative;
|
||||||
|
min-height: 440px;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-size: 0;
|
||||||
|
&-modeNav {
|
||||||
|
padding: 2px;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
left: 4px;
|
||||||
|
z-index: 10;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
&__nav {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 99;
|
||||||
|
top: 50%;
|
||||||
|
width: 40px !important;
|
||||||
|
height: 40px !important;
|
||||||
|
background: #d9d9d9;
|
||||||
|
border-radius: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
|
||||||
|
&>button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
opacity: 0.3;
|
||||||
|
|
||||||
|
&>button {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__nav:hover {
|
||||||
|
background: #09f;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
// ------------ 导航 -----------------
|
||||||
|
&-nav {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8)!important;
|
||||||
|
}
|
||||||
|
&_left {
|
||||||
|
left: 8px;
|
||||||
|
}
|
||||||
|
&_right {
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ------------ 场景图 -----------------
|
||||||
|
&-cropper-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 4px;
|
||||||
|
&_close {
|
||||||
|
margin-left: 4px;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
&-group {
|
||||||
|
.zhst-radio-button-wrapper {
|
||||||
|
display: inline-flex;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #191919;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8)
|
||||||
|
}
|
||||||
|
&-radio {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
.anticon {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
96
packages/biz/src/BigImage/index.md
Normal file
96
packages/biz/src/BigImage/index.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
group: 进阶组件
|
||||||
|
category: Components
|
||||||
|
subtitle: 大图组件
|
||||||
|
toc: content
|
||||||
|
title: BigImage 大图组件
|
||||||
|
---
|
||||||
|
|
||||||
|
## 大图弹框
|
||||||
|
|
||||||
|
<code src="./demo/index.tsx">基本</code>
|
||||||
|
<code src="./demo/withRelatedImage.tsx">人脸碰撞模型</code>
|
||||||
|
<code src="./demo/withEdit.tsx">编辑模式</code>
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| type | 当前模式 | 'compater'、'normal'、'video' | - | |
|
||||||
|
| viewHeight | 视图高度 | string、number | - | |
|
||||||
|
| width | 宽度 | string、number | - | |
|
||||||
|
| showDescription | 描述列表显示\隐藏 | boolean | false | |
|
||||||
|
| descriptionsProps | 描述列表透传 | | antd - DescriptionsProps | |
|
||||||
|
| descriptionList | 描述列表数据(见下文) | | IDescriptionList | |
|
||||||
|
| topButtonRender | 顶部按钮 | | ReactNode、string | |
|
||||||
|
| customTabBarExtraContent | 自定义tab尾部导航插槽 | | ReactNode、 string | |
|
||||||
|
| onTabChange | tab事件监听 | | antd - TabsProps['onChange'] | |
|
||||||
|
| tabProps | tab透传 | | antd - TabsProps | |
|
||||||
|
| showModeChange | 是否显示模式切换按钮 | | boolean | |
|
||||||
|
| viewTopModeButtonList | 模式切换按钮列表 | | TypeRadio[] | |
|
||||||
|
| modeButtonGroupProps | 模式切换按钮组透传 | RadioGroupProps | - | |
|
||||||
|
| isRelated | 人脸碰撞模型显示\隐藏 | boolean | | |
|
||||||
|
| relatedImageProps | 人脸碰撞模型透传 | zhst/meta - RelatedImageProps | | |
|
||||||
|
| cropperImageProps | 场景图模式透传 | ICropperImageProps | | |
|
||||||
|
| combineImageProps | 对比图模式透传 | ComBineImageProps | | |
|
||||||
|
| videoProps | 视频模式透传 | videoProps | | |
|
||||||
|
| showNavigation | 是否展示导航 | boolean | | |
|
||||||
|
| prevButtonProps | 前翻箭头透传 | prevButtonProps | | |
|
||||||
|
| onPrevButtonClick | 前翻箭头点击事件 | () => void; | | |
|
||||||
|
| nextButtonProps | 下翻箭头透传 | () => void; | | |
|
||||||
|
| onNextButtonClick | 下翻箭头点击事件 | () => void; | | |
|
||||||
|
| children | | ReactNode | | |
|
||||||
|
|
||||||
|
### IDescriptionList
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface IDescriptionList {
|
||||||
|
title: string;
|
||||||
|
showTitle?: boolean;
|
||||||
|
props?: DescriptionsProps
|
||||||
|
children: DescriptionsProps['items']
|
||||||
|
}[]
|
||||||
|
```
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface ICropperImageProps extends CropperImageProps {
|
||||||
|
showEditTools?: boolean // 是否展示编辑按钮
|
||||||
|
editAble?: boolean // 是否开启编辑模式
|
||||||
|
score?: string | number // 分数
|
||||||
|
btnGroupProps?: BtnGroupProps; // crop 场景图模式下的按钮拓展
|
||||||
|
cropButtonList?: TypeRadio[] // 编辑按钮列表
|
||||||
|
onCropperTypeChange?: (type: RadioProps['onChange']) => void
|
||||||
|
onExitEdit?: ButtonProps['onClick'] // 退出编辑模式
|
||||||
|
attachImageData?: AttachImageProps['data'] // 左下角预览图
|
||||||
|
attachImageProps?: AttachImageProps // 左下角预览图透传
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 设计方案
|
||||||
|
|
||||||
|
结合当下的业务场景,目前大图组件有三种模式
|
||||||
|
|
||||||
|
1. 场景图模式
|
||||||
|
-
|
||||||
|
2. 对比图模式
|
||||||
|
3. 视频模式
|
||||||
|
|
||||||
|
场景图和视频模式,支持用户编辑圈选
|
||||||
|
|
||||||
|
三种模式状态下,都会有外层模块的嵌套,目前有以下几种:
|
||||||
|
|
||||||
|
1. 描述模块
|
||||||
|
2. 顶部拓展
|
||||||
|
- 目前仅支持自定义
|
||||||
|
- 默认下边间距 16px
|
||||||
|
3. tabs 切换
|
||||||
|
- 默认下间距:16px
|
||||||
|
- 支持自定义文案
|
||||||
|
- 支持自定义数量
|
||||||
|
- 支持后方插槽
|
||||||
|
4. 人脸碰撞模型
|
||||||
|
- 支持用户自定义传入数据
|
||||||
|
|
||||||
|
本来想通过插件的形式按需加载
|
5
packages/biz/src/BigImage/index.tsx
Normal file
5
packages/biz/src/BigImage/index.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import BigImage from "./BigImage";
|
||||||
|
|
||||||
|
export type { BigImageProps, BigImageRef } from './BigImage'
|
||||||
|
|
||||||
|
export default BigImage
|
84
packages/biz/src/BigImage/interface.ts
Normal file
84
packages/biz/src/BigImage/interface.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
import { ReactNode } from 'react'
|
||||||
|
import {
|
||||||
|
ButtonProps,
|
||||||
|
RadioProps,
|
||||||
|
RadioGroupProps,
|
||||||
|
VideoViewProps,
|
||||||
|
DescriptionsProps,
|
||||||
|
TabsProps,
|
||||||
|
RelatedImageProps,
|
||||||
|
BtnGroupProps,
|
||||||
|
CropperImageProps,
|
||||||
|
VideoViewRef,
|
||||||
|
AttachImageProps
|
||||||
|
} from '@zhst/meta'
|
||||||
|
import { ComBineImageProps } from './components/CombineImage'
|
||||||
|
|
||||||
|
export type TypeRadio = {
|
||||||
|
label?: string;
|
||||||
|
key: string;
|
||||||
|
tooltipTxt?: string;
|
||||||
|
onClick?: ButtonProps['onClick']
|
||||||
|
icon?: ReactNode | string;
|
||||||
|
props?: ButtonProps
|
||||||
|
}
|
||||||
|
|
||||||
|
type TypePlugin = 'compater' | 'normal' | 'video' | 'faceMode'
|
||||||
|
|
||||||
|
export interface BigImageProps {
|
||||||
|
type?: TypePlugin // 当前 tab
|
||||||
|
viewHeight?: string | number;
|
||||||
|
width?: string | number
|
||||||
|
typePlugins?: TypePlugin[] // TODO: 开启插件类型
|
||||||
|
// ------------ 描述列表 -----------------
|
||||||
|
showDescription?: boolean;
|
||||||
|
descriptionsProps?: DescriptionsProps
|
||||||
|
descriptionList?: {
|
||||||
|
title: string;
|
||||||
|
showTitle?: boolean;
|
||||||
|
props?: DescriptionsProps
|
||||||
|
children: DescriptionsProps['items']
|
||||||
|
}[]
|
||||||
|
// ------------------ 顶部按钮列表
|
||||||
|
topButtonRender?: ReactNode | string
|
||||||
|
// ---------------- Tabs 导航 ------------------
|
||||||
|
customTabBarExtraContent?: string | ReactNode
|
||||||
|
onTabChange?: TabsProps['onChange']
|
||||||
|
tabProps?: TabsProps
|
||||||
|
// ------------ 图片 | 视频切换导航 -----------------
|
||||||
|
showModeChange?: boolean
|
||||||
|
viewTopModeButtonList?: TypeRadio[]
|
||||||
|
modeButtonGroupProps?: RadioGroupProps
|
||||||
|
// ----------------- 人脸碰转 -----------------
|
||||||
|
isRelated?: boolean // 人脸碰撞功能打开
|
||||||
|
relatedImageProps?: RelatedImageProps
|
||||||
|
// -------------------------- crop 场景图模式 -----------------------
|
||||||
|
cropperImageProps?: CropperImageProps & {
|
||||||
|
showEditTools?: boolean
|
||||||
|
editAble?: boolean
|
||||||
|
score?: string | number
|
||||||
|
btnGroupProps?: BtnGroupProps; // crop 场景图模式下的按钮拓展
|
||||||
|
cropButtonList?: TypeRadio[]
|
||||||
|
onCropperTypeChange?: (type: RadioProps['onChange']) => void
|
||||||
|
onExitEdit?: ButtonProps['onClick']
|
||||||
|
attachImageData?: AttachImageProps['data']
|
||||||
|
attachImageProps?: AttachImageProps
|
||||||
|
}
|
||||||
|
// -------------------- 对比图模式 -------------------------
|
||||||
|
combineImageProps?: ComBineImageProps
|
||||||
|
// ------------ 导航 -----------------
|
||||||
|
showNavigation?: boolean // 是否展示导航箭头
|
||||||
|
prevButtonProps?: any;
|
||||||
|
onPrevButtonClick?: () => void;
|
||||||
|
nextButtonProps?: any
|
||||||
|
onNextButtonClick?: () => void;
|
||||||
|
theme?: any
|
||||||
|
children?: React.ReactNode
|
||||||
|
// ------------ 视频模式 -----------------
|
||||||
|
videoProps?: VideoViewProps
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BigImageRef {
|
||||||
|
videoPlayerRef: VideoViewRef
|
||||||
|
combineImageRef: any
|
||||||
|
}
|
292
packages/biz/src/BigImage/mock.ts
Normal file
292
packages/biz/src/BigImage/mock.ts
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
import imageUrl from './demo/imgs/photo-1503185912284-5271ff81b9a8.webp'
|
||||||
|
|
||||||
|
export const IMAGE_DATA = {
|
||||||
|
"enAbleDeleteFeature": true,
|
||||||
|
"tabsFilter": [
|
||||||
|
"COMPATER",
|
||||||
|
"NORMAL"
|
||||||
|
],
|
||||||
|
"selectIndex": 4,
|
||||||
|
"disableBtn": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
4,
|
||||||
|
20
|
||||||
|
],
|
||||||
|
"dataSource": {
|
||||||
|
"objectId": "1742110565582518272",
|
||||||
|
"condition": {
|
||||||
|
"featureInfo": null,
|
||||||
|
"featureData": "AAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"imageData": "",
|
||||||
|
"alg": "VERSION_REID_HEAD_ATTR",
|
||||||
|
"rect": {
|
||||||
|
"x": 0.271875,
|
||||||
|
"y": 0.32222223,
|
||||||
|
"w": 0.2859375,
|
||||||
|
"h": 0.67777777
|
||||||
|
},
|
||||||
|
"objectImageUrl": "singer-20240102/1/129529/1742047651878156288.jpg",
|
||||||
|
"srcImageUrl": "singer-20240102/1/129529/1742047652511496192.jpg"
|
||||||
|
},
|
||||||
|
"score": 0.7163062,
|
||||||
|
"timestamp": 1704186491979,
|
||||||
|
"deviceId": "129533",
|
||||||
|
"id": "129533",
|
||||||
|
"name": "4楼门口过道人脸",
|
||||||
|
"dirid": "0",
|
||||||
|
"status": "1",
|
||||||
|
"longitude": 120.125,
|
||||||
|
"latitude": 30.280500411987305,
|
||||||
|
"caseId": "0",
|
||||||
|
"caseGroup": "",
|
||||||
|
"isDeleted": "DEVICEMANAGER_BOOL_DEFAULT",
|
||||||
|
"objectIndex": {
|
||||||
|
"objectId": "1742110565582518272",
|
||||||
|
"solutionId": "1",
|
||||||
|
"deviceId": "129533",
|
||||||
|
"fragmentId": "0"
|
||||||
|
},
|
||||||
|
"objectType": "OBJECT_TYPE_PEDESTRAIN",
|
||||||
|
"isObjectTrack": true,
|
||||||
|
"pathId": "1742110532019697664",
|
||||||
|
"frameInfo": {
|
||||||
|
"frameId": "0",
|
||||||
|
"frameTimestamp": "1704186491979",
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"originWidth": 1920,
|
||||||
|
"originHeight": 1080,
|
||||||
|
"offsetTime": "24714687",
|
||||||
|
"skipNumber": "0"
|
||||||
|
},
|
||||||
|
"level": 1,
|
||||||
|
"bboxInFrame": {
|
||||||
|
"x": 0.603125,
|
||||||
|
"y": 0.3314815,
|
||||||
|
"w": 0.0578125,
|
||||||
|
"h": 0.2712963
|
||||||
|
},
|
||||||
|
"bboxExtInFrame": {
|
||||||
|
"x": 0.546875,
|
||||||
|
"y": 0.2638889,
|
||||||
|
"w": 0.17135416,
|
||||||
|
"h": 0.40648147
|
||||||
|
},
|
||||||
|
"objectImageKey": "",
|
||||||
|
"objectExtImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565582518272.jpg",
|
||||||
|
"frameImageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565603489792.jpg",
|
||||||
|
"confidence": 0.817271,
|
||||||
|
"sourceObjectId": "1742110565603489792",
|
||||||
|
"storeTimestamp": "0",
|
||||||
|
"gbNumber": "",
|
||||||
|
"qualityScore": 0,
|
||||||
|
"subObjectCount": 1,
|
||||||
|
"subObjectType": [
|
||||||
|
"OBJECT_TYPE_FACE"
|
||||||
|
],
|
||||||
|
"subObjectIds": [
|
||||||
|
"1742110532015503360"
|
||||||
|
],
|
||||||
|
"solutionId": "1",
|
||||||
|
"fragmentId": "0",
|
||||||
|
"contrastKey": "singer-20240102/1/129533/1742110565582518272.jpg",
|
||||||
|
"compaterImages": [
|
||||||
|
"http://10.0.0.7:30003/file/singer-20240102/1/129529/1742047651878156288.jpg"
|
||||||
|
],
|
||||||
|
"imgSummary": "singer-20240102/1/129533/1742110565582518272.jpg",
|
||||||
|
"imageKey": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565582518272.jpg",
|
||||||
|
"srcImageUrl": "http://10.0.0.7:30003/file/singer-20240102/1/129533/1742110565603489792.jpg",
|
||||||
|
"algorithmVersion": "VERSION_REID_HEAD_ATTR",
|
||||||
|
"cameraId": "129533",
|
||||||
|
"cameraName": "4楼门口过道人脸"
|
||||||
|
},
|
||||||
|
"isArchiveDetail": false,
|
||||||
|
"ToolProps": {
|
||||||
|
"renderVideoBtn": true,
|
||||||
|
"disableVideo": false
|
||||||
|
},
|
||||||
|
"specialTitle": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RELATED_IMAGES = [
|
||||||
|
{ key: '123', url: imageUrl },
|
||||||
|
{ key: '22', url: imageUrl },
|
||||||
|
{ key: '22122333', url: imageUrl },
|
||||||
|
{ key: '2212243', url: imageUrl },
|
||||||
|
{ key: '224523433', url: imageUrl },
|
||||||
|
{ key: '224235453', url: imageUrl },
|
||||||
|
{ key: '245423', url: imageUrl },
|
||||||
|
{ key: '224233543', url: imageUrl },
|
||||||
|
{ key: '22452343', url: imageUrl },
|
||||||
|
{ key: '22323243', url: imageUrl },
|
||||||
|
{ key: '2236456', url: imageUrl },
|
||||||
|
{ key: '224563', url: imageUrl },
|
||||||
|
{ key: '24565423', url: imageUrl },
|
||||||
|
{ key: '245645623', url: imageUrl },
|
||||||
|
{ key: '2456435623', url: imageUrl },
|
||||||
|
{ key: '2323', url: imageUrl }
|
||||||
|
]
|
||||||
|
|
||||||
|
export const BIG_IMAGE_DATA = {
|
||||||
|
imageKey: imageUrl,
|
||||||
|
imgSummary: imageUrl,
|
||||||
|
flvUrl: 'ws://10.0.0.120:9033/flv/HaikangNvr/45.flv?ip=10.0.2.103&stime=1712539148&etime=1712539168',
|
||||||
|
compaterImage: imageUrl,
|
||||||
|
odRect: [
|
||||||
|
{
|
||||||
|
id: '123',
|
||||||
|
"x":0.5445312,
|
||||||
|
"y":0.19166666,
|
||||||
|
"w":0.08671875,
|
||||||
|
"h":0.40138888
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "123",
|
||||||
|
"x": 0.5519352,
|
||||||
|
"y": 0.2965385,
|
||||||
|
"w": 0.05185461,
|
||||||
|
"h": 0.24698898,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "456",
|
||||||
|
"x": 0.58543766,
|
||||||
|
"y": 0.3203356,
|
||||||
|
"w": 0.052037954,
|
||||||
|
"h": 0.2664015
|
||||||
|
}
|
||||||
|
],
|
||||||
|
attachImg: [
|
||||||
|
{
|
||||||
|
"url": imageUrl,
|
||||||
|
"label": "形体"
|
||||||
|
},{
|
||||||
|
"url": imageUrl,
|
||||||
|
"label": "人脸"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
score: 60, // 人脸质量分
|
||||||
|
showScore: true, // 人脸质量分
|
||||||
|
cameraPosition: 'string', // 摄像头位置
|
||||||
|
time: '2022-01-01', // 摄像头拍摄时间
|
||||||
|
objects: [
|
||||||
|
{
|
||||||
|
"objectIndex": {
|
||||||
|
"objectId": "1746832189053474816",
|
||||||
|
"solutionId": "0",
|
||||||
|
"deviceId": "0",
|
||||||
|
"fragmentId": "0"
|
||||||
|
},
|
||||||
|
"objectType": "OBJECT_TYPE_PEDESTRAIN",
|
||||||
|
"sourceObjectId": "0",
|
||||||
|
"level": 0,
|
||||||
|
"confidence": 0.881164,
|
||||||
|
"frameInfo": {
|
||||||
|
"frameId": "0",
|
||||||
|
"frameTimestamp": "1705312223057",
|
||||||
|
"width": 0,
|
||||||
|
"height": 0,
|
||||||
|
"originWidth": 0,
|
||||||
|
"originHeight": 0,
|
||||||
|
"offsetTime": "0",
|
||||||
|
"skipNumber": "0"
|
||||||
|
},
|
||||||
|
"infoOnSource": {
|
||||||
|
"bboxInFrame": {
|
||||||
|
"bboxRatio": {
|
||||||
|
"x": 0.61418945,
|
||||||
|
"y": 0.34309354,
|
||||||
|
"w": 0.067661405,
|
||||||
|
"h": 0.34659258
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"countInSource": 0,
|
||||||
|
"indexInSource": 0
|
||||||
|
},
|
||||||
|
"qualityScore": 0,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const attributeList = [
|
||||||
|
{
|
||||||
|
title: '人员属性',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
label: '性别',
|
||||||
|
children: '男',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
label: '年龄',
|
||||||
|
children: '成年',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
label: '帽子',
|
||||||
|
children: '无',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '4',
|
||||||
|
label: '上身颜色',
|
||||||
|
children: '灰',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '5',
|
||||||
|
label: '下身颜色',
|
||||||
|
children: '蓝色',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '6',
|
||||||
|
label: '附着物',
|
||||||
|
children: '无',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '7',
|
||||||
|
label: '骑行',
|
||||||
|
children: '否',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '社区规范',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: '1',
|
||||||
|
label: '性别',
|
||||||
|
children: '男',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
label: '年龄',
|
||||||
|
children: '成年',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
label: '帽子',
|
||||||
|
children: '无',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '4',
|
||||||
|
label: '上身颜色',
|
||||||
|
children: '灰',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '5',
|
||||||
|
label: '下身颜色',
|
||||||
|
children: '蓝色',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '6',
|
||||||
|
label: '附着物',
|
||||||
|
children: '无',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '7',
|
||||||
|
label: '骑行',
|
||||||
|
children: '否',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
195
packages/biz/src/BigImage/util/bigImageModalAdapter.tsx
Normal file
195
packages/biz/src/BigImage/util/bigImageModalAdapter.tsx
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/**
|
||||||
|
* 适配老的大屏组件数据格式传入
|
||||||
|
*/
|
||||||
|
import React, { } from 'react';
|
||||||
|
import { AlgorithmVersionStr, HumanProperty, ObjectType, Rect, IScreenshotButtonProp } from '@zhst/types'
|
||||||
|
import { VideoViewProps, ImgViewProps, VideoViewRef, ImgViewRef } from '@zhst/meta'
|
||||||
|
|
||||||
|
export type TAB_TYPE = 'COMPATER' | 'NORMAL' | 'TRACK';
|
||||||
|
export type MODEL_TYPE = 'VIDEO' | 'IMAGE';
|
||||||
|
|
||||||
|
export interface CarouselProps {
|
||||||
|
hasPre?: boolean;
|
||||||
|
hasNext?: boolean;
|
||||||
|
selectIndex: number;
|
||||||
|
setSelectIndex: React.Dispatch<React.SetStateAction<number>>;
|
||||||
|
dataSource: Array<{
|
||||||
|
key: string;
|
||||||
|
url: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ISelectItem = Partial<Omit<ImgViewProps, 'screenshotButtonRender'>> &
|
||||||
|
Partial<Omit<VideoViewProps, 'screenshotButtonRender'>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述列表 description
|
||||||
|
*/
|
||||||
|
export interface HeaderProps {
|
||||||
|
value: TAB_TYPE;
|
||||||
|
onChange: (type: TAB_TYPE) => void;
|
||||||
|
tabsFilter: TAB_TYPE[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ParamProps {
|
||||||
|
tab: string;
|
||||||
|
selectItem: ISelectItem;
|
||||||
|
imgViewRef: React.MutableRefObject<ImgViewRef>;
|
||||||
|
VideoViewRef: React.MutableRefObject<VideoViewRef>;
|
||||||
|
model: MODEL_TYPE;
|
||||||
|
setModel: React.Dispatch<React.SetStateAction<MODEL_TYPE>>;
|
||||||
|
/* 可观测值 */
|
||||||
|
scale$: number;
|
||||||
|
showCrop$: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具栏
|
||||||
|
*/
|
||||||
|
export interface ToolProps {
|
||||||
|
renderRight?: (props: ParamProps) => React.ReactNode;
|
||||||
|
renderLeft?: (props: ParamProps) => React.ReactNode;
|
||||||
|
renderVideoBtn?: boolean;
|
||||||
|
param: ParamProps;
|
||||||
|
disableVideo: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface BigImageData {
|
||||||
|
//imageKey 小图
|
||||||
|
extendRectList: (Rect & { algorithmVersion: AlgorithmVersionStr; imageKey: string })[];
|
||||||
|
rectList: (Rect & { algorithmVersion: AlgorithmVersionStr; imageKey: string })[];
|
||||||
|
attachImg: { url: string; label: '形体' | '人脸' }[];
|
||||||
|
odRect: Rect;
|
||||||
|
compaterImages: string[] // 目标图列表
|
||||||
|
constractKey: string; // 当前比较中的目标图
|
||||||
|
frameImageKey: string; // 场景图
|
||||||
|
imageKey?: string; // 大图
|
||||||
|
imgSummary: string; // 摘要图
|
||||||
|
objectExtImageKey: string; //比对到的目标图扩展图 === imgSummary
|
||||||
|
|
||||||
|
attributeList: { label: string; list: any[] }[];
|
||||||
|
archiveImages?: any;
|
||||||
|
spaceName: string;
|
||||||
|
|
||||||
|
objectIndex?: {
|
||||||
|
deviceId: string;
|
||||||
|
fragmentId: string;
|
||||||
|
objectId: string;
|
||||||
|
solutionId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
objectType: ObjectType;
|
||||||
|
objectId: string; //这张摘要本身的Id
|
||||||
|
bodyObjectId?: string;
|
||||||
|
faceObjectId?: string; //这张摘要下的人脸Id(如果有)
|
||||||
|
sourceObjectId?: string; //这张摘要上游的形体Id(如果有)
|
||||||
|
cameraId: string;
|
||||||
|
cameraName: string;
|
||||||
|
selectIndex: number;
|
||||||
|
humanProperty: HumanProperty;
|
||||||
|
qualityScore?: number; //人脸质量分
|
||||||
|
score: number; // 相似度
|
||||||
|
timestamp: string;
|
||||||
|
bodyImageUrl: string;
|
||||||
|
faceImageUrl: string;
|
||||||
|
algorithmVersion: AlgorithmVersionStr;
|
||||||
|
|
||||||
|
bodySpaceName: string;
|
||||||
|
faceSpaceName: string;
|
||||||
|
position: {
|
||||||
|
lat: number
|
||||||
|
lng: number
|
||||||
|
}
|
||||||
|
|
||||||
|
solutionId?: string;
|
||||||
|
[index: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface IOldImageData {
|
||||||
|
visible?: boolean; // 显示隐藏弹框
|
||||||
|
defaultModel?: MODEL_TYPE; // 视频模式 | 图片模式
|
||||||
|
onClose?: () => void; // 关闭弹框
|
||||||
|
isLoading?: boolean; // 是否加载中
|
||||||
|
hasPre?: boolean; // 向前翻页
|
||||||
|
hasNext?: boolean; // 向后翻页
|
||||||
|
selectIndex?: number; // 选中的数据(dataSource为数组情况下)
|
||||||
|
onSelectIndexChange?: (i: number) => void; // 修改当前下标
|
||||||
|
dataSource: BigImageData[]; // 数据1
|
||||||
|
dataSources: BigImageData[]; // 数据2
|
||||||
|
relatedData?: BigImageData[]; // 数据3
|
||||||
|
transformPropFunc: (item: any) => ISelectItem; // 格式化数据方法
|
||||||
|
transformVideoPropFunc: (
|
||||||
|
item: ISelectItem
|
||||||
|
) => Promise<Omit<VideoViewProps, 'screenshotButtonRender'>>; // 视频模式格式化数据方法
|
||||||
|
screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement;
|
||||||
|
showTool?: boolean; // 是否显示底部菜单
|
||||||
|
showCarousel?: boolean; //
|
||||||
|
imgViewProp?: Partial<ImgViewProps>; // 图片模式的配置
|
||||||
|
videoViewProp?: Partial<VideoViewProps>; // 视频模式的配置
|
||||||
|
ToolProps?: Partial<ToolProps>; // 底部菜单的配置
|
||||||
|
nullDialogProp?: {
|
||||||
|
emptyText?: string;
|
||||||
|
}; // 暂无数据的配置
|
||||||
|
showHeader?: boolean; // 是否显示 description
|
||||||
|
tabsFilter?: TAB_TYPE[]; // tabs 过滤
|
||||||
|
useVirtual?: boolean; // 是否显示虚拟
|
||||||
|
loadNext?: (i: number) => Promise<void>; // 下一个
|
||||||
|
loadPre?: (i: number) => Promise<void>; // 前一个
|
||||||
|
children: React.ReactNode; // 子元素
|
||||||
|
title?: string; // 标题
|
||||||
|
specialTitle?: string; // 对比图模式下标题
|
||||||
|
isRelated?: boolean;
|
||||||
|
carouselProp?: Partial<CarouselProps>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface ImageModalDataProps {
|
||||||
|
targetData: BigImageData[]
|
||||||
|
compactData: BigImageData[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ModalAdapterConfigProps {
|
||||||
|
oldMode?: boolean; // 是否是老模式
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容老数据格式
|
||||||
|
* @param _data 老数据格式
|
||||||
|
* @returns newData
|
||||||
|
*/
|
||||||
|
const translateOldImageData = (_data: IOldImageData) => {
|
||||||
|
return {
|
||||||
|
..._data,
|
||||||
|
open: _data.visible,
|
||||||
|
onCancel: _data.onClose
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 大图组件适配器,兼容老接口
|
||||||
|
* @param Cmp 大图组件
|
||||||
|
* @param config 额外配置
|
||||||
|
* @returns 大图组件
|
||||||
|
*/
|
||||||
|
const adapter = (Cmp: any, config: ModalAdapterConfigProps): any => {
|
||||||
|
const { oldMode = false } = config
|
||||||
|
|
||||||
|
return (props: IOldImageData) => {
|
||||||
|
const newProps = oldMode ? translateOldImageData(props) : props
|
||||||
|
console.log('adapter----适配数据', props, newProps)
|
||||||
|
|
||||||
|
// 该属性已经废弃
|
||||||
|
delete newProps.visible
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Cmp
|
||||||
|
{...newProps}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default adapter
|
36
packages/biz/src/BigImage/util/interface.ts
Normal file
36
packages/biz/src/BigImage/util/interface.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
export interface IBigImageModalData {
|
||||||
|
imageKey?: string // 目标图
|
||||||
|
imgSummary?: string // 大图
|
||||||
|
flvUrl?: string // 视频链接
|
||||||
|
compaterImages?: string[] // 对比图
|
||||||
|
odRect?: { // od 框数据
|
||||||
|
"x": number
|
||||||
|
"y": number
|
||||||
|
"w": number
|
||||||
|
"h": number
|
||||||
|
[key: string]: string | number; // 拓展参数
|
||||||
|
}[],
|
||||||
|
attachImg?: { // 小图,只有在场景图模式生效(人脸、形体)
|
||||||
|
"url": string
|
||||||
|
"label": string
|
||||||
|
[key: string]: string
|
||||||
|
}[],
|
||||||
|
score?: number | string // 人脸质量分
|
||||||
|
showScore?: boolean // 人脸质量分
|
||||||
|
cameraPosition?: string // 摄像头位置
|
||||||
|
time?: string // 摄像头拍摄时间
|
||||||
|
objects: { // 拓展参数、可以自由支配
|
||||||
|
objectIndex: {
|
||||||
|
[key: string]: any
|
||||||
|
},
|
||||||
|
objectType: string
|
||||||
|
sourceObjectId: string
|
||||||
|
level: number
|
||||||
|
confidence: number
|
||||||
|
infoOnSource: {
|
||||||
|
[key: string]: any
|
||||||
|
},
|
||||||
|
qualityScore: number
|
||||||
|
[key: string]: any
|
||||||
|
}[]
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
export { default as BigImageModal } from './BigImageModal'
|
export { default as BigImageModal } from './BigImageModal'
|
||||||
export type { BigImageModalProps } from './BigImageModal'
|
export type { BigImageModalProps } from './BigImageModal'
|
||||||
|
export { default as BigImage } from './BigImage'
|
||||||
|
export type { BigImageProps, BigImageRef } from './BigImage'
|
||||||
export { default as BoxSelectTree } from './boxSelectTree'
|
export { default as BoxSelectTree } from './boxSelectTree'
|
||||||
export type { BoxSelectTreeProps } from './boxSelectTree'
|
export type { BoxSelectTreeProps } from './boxSelectTree'
|
||||||
export { default as Tree } from './tree'
|
export { default as Tree } from './tree'
|
||||||
|
1
packages/hooks/es/useSocket/index.d.ts
vendored
1
packages/hooks/es/useSocket/index.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
export {};
|
|
1
packages/hooks/lib/useSocket/index.d.ts
vendored
1
packages/hooks/lib/useSocket/index.d.ts
vendored
@ -1 +0,0 @@
|
|||||||
export {};
|
|
@ -1,13 +1,16 @@
|
|||||||
import { defineConfig } from 'father';
|
import { defineConfig } from 'father-plugin-less';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: {
|
esm: {
|
||||||
output: 'es',
|
output: 'es',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
cjs: {
|
cjs: {
|
||||||
output: 'lib',
|
output: 'lib',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
|
plugins: ['father-plugin-less'],
|
||||||
});
|
});
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
.icon:hover {
|
|
||||||
color: #6accca !important;
|
|
||||||
}
|
|
@ -1,13 +1,16 @@
|
|||||||
import { defineConfig } from 'father';
|
import { defineConfig } from 'father-plugin-less';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: {
|
esm: {
|
||||||
output: 'es',
|
output: 'es',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
cjs: {
|
cjs: {
|
||||||
output: 'lib',
|
output: 'lib',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
|
plugins: ['father-plugin-less'],
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Created by jiangzhixiong on 2024/05/21
|
* Created by jiangzhixiong on 2024/05/21
|
||||||
*/
|
*/
|
||||||
import { forwardRef, useImperativeHandle, useRef, } from 'react'
|
import { forwardRef, useImperativeHandle, useRef, } from 'react'
|
||||||
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
||||||
import {
|
import {
|
||||||
DragCircleMode,
|
DragCircleMode,
|
||||||
@ -14,12 +14,11 @@ import drawRectMode from 'mapbox-gl-draw-rectangle-mode'
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import drawStaticMode from '@mapbox/mapbox-gl-draw-static-mode'
|
import drawStaticMode from '@mapbox/mapbox-gl-draw-static-mode'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import drawCircleMode from './Draw/drawCircleMode.draw.js'
|
import drawCircleMode from './mode/drawCircleMode.draw.js'
|
||||||
import { useControl } from 'react-map-gl';
|
import { useControl } from 'react-map-gl';
|
||||||
import type { ControlPosition } from 'react-map-gl';
|
import type { ControlPosition } from 'react-map-gl';
|
||||||
import { MapContextValue } from 'react-map-gl/dist/esm/components/map';
|
|
||||||
|
|
||||||
export type DrawControlProps = ConstructorParameters<typeof MapboxDraw>[0] & {
|
export interface DrawControlProps extends MapboxDraw {
|
||||||
position?: ControlPosition;
|
position?: ControlPosition;
|
||||||
onCreate?: (evt: {features: object[]}) => void;
|
onCreate?: (evt: {features: object[]}) => void;
|
||||||
onUpdate?: (evt: {features: object[]; action: string}) => void;
|
onUpdate?: (evt: {features: object[]; action: string}) => void;
|
||||||
@ -38,6 +37,7 @@ export interface DrawControlRefProps {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
const DrawControl = forwardRef<DrawControlRefProps, DrawControlProps>((props, ref) => {
|
const DrawControl = forwardRef<DrawControlRefProps, DrawControlProps>((props, ref) => {
|
||||||
const drawRef = useRef<DrawControlRefProps['drawer']>(null)
|
const drawRef = useRef<DrawControlRefProps['drawer']>(null)
|
||||||
|
|
||||||
@ -45,12 +45,13 @@ const DrawControl = forwardRef<DrawControlRefProps, DrawControlProps>((props, re
|
|||||||
() => {
|
() => {
|
||||||
let draw = new MapboxDraw(
|
let draw = new MapboxDraw(
|
||||||
{
|
{
|
||||||
|
// @ts-ignore
|
||||||
modes: {
|
modes: {
|
||||||
...MapboxDraw.modes,
|
...MapboxDraw.modes,
|
||||||
// draw_line_select: drawLineSelectMode,
|
// draw_line_select: drawLineSelectMode,
|
||||||
draw_rect: drawRectMode,
|
draw_rect: drawRectMode,
|
||||||
drag_circle: DragCircleMode,
|
drag_circle: DragCircleMode,
|
||||||
draw_circle : drawCircleMode,
|
draw_circle: drawCircleMode,
|
||||||
direct_select: DirectMode,
|
direct_select: DirectMode,
|
||||||
simple_select: SimpleSelectMode,
|
simple_select: SimpleSelectMode,
|
||||||
static: drawStaticMode,
|
static: drawStaticMode,
|
||||||
@ -62,7 +63,7 @@ const DrawControl = forwardRef<DrawControlRefProps, DrawControlProps>((props, re
|
|||||||
drawRef.current = draw
|
drawRef.current = draw
|
||||||
return draw
|
return draw
|
||||||
},
|
},
|
||||||
(context: MapContextValue) => {
|
(context: any) => {
|
||||||
const { map } = context
|
const { map } = context
|
||||||
map.on('draw.create', e => props.onCreate?.(e));
|
map.on('draw.create', e => props.onCreate?.(e));
|
||||||
map.on('draw.update', e => props.onUpdate?.(e));
|
map.on('draw.update', e => props.onUpdate?.(e));
|
||||||
@ -98,11 +99,4 @@ const DrawControl = forwardRef<DrawControlRefProps, DrawControlProps>((props, re
|
|||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
|
|
||||||
DrawControl.defaultProps = {
|
|
||||||
onCreate: () => {},
|
|
||||||
onUpdate: () => {},
|
|
||||||
onDelete: () => {},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DrawControl
|
export default DrawControl
|
||||||
|
24
packages/map/src/drawControl/mode/doubleClickZoom.js
Normal file
24
packages/map/src/drawControl/mode/doubleClickZoom.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
const doubleClickZoom = {
|
||||||
|
enable(ctx) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (
|
||||||
|
!ctx.map ||
|
||||||
|
!ctx.map.doubleClickZoom ||
|
||||||
|
!ctx._ctx ||
|
||||||
|
!ctx._ctx.store ||
|
||||||
|
!ctx._ctx.store.getInitialConfigValue
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
if (!ctx._ctx.store.getInitialConfigValue('doubleClickZoom')) return;
|
||||||
|
ctx.map.doubleClickZoom.enable();
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
disable(ctx) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!ctx.map || !ctx.map.doubleClickZoom) return;
|
||||||
|
ctx.map.doubleClickZoom.disable();
|
||||||
|
}, 0);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default doubleClickZoom;
|
69
packages/map/src/drawControl/mode/drawCircleMode.draw.js
Normal file
69
packages/map/src/drawControl/mode/drawCircleMode.draw.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
||||||
|
import doubleClickZoom from './doubleClickZoom';
|
||||||
|
import * as turf from '@turf/turf';
|
||||||
|
const { circle, distance, helpers: turfHelpers } = turf;
|
||||||
|
const drawCircleMode = { ...MapboxDraw.modes.draw_polygon };
|
||||||
|
drawCircleMode.onSetup = function () {
|
||||||
|
const polygon = this.newFeature({
|
||||||
|
type: 'Feature',
|
||||||
|
properties: {
|
||||||
|
isCircle: true,
|
||||||
|
center: [],
|
||||||
|
},
|
||||||
|
geometry: {
|
||||||
|
type: 'Polygon',
|
||||||
|
coordinates: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addFeature(polygon);
|
||||||
|
|
||||||
|
this.clearSelectedFeatures();
|
||||||
|
doubleClickZoom.disable(this);
|
||||||
|
// dragPan.disable(this);
|
||||||
|
this.updateUIClasses({ mouse: 'add' });
|
||||||
|
this.activateUIButton('Polygon');
|
||||||
|
this.setActionableState({
|
||||||
|
trash: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
polygon,
|
||||||
|
currentVertexPosition: 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
drawCircleMode.onClick = drawCircleMode.onTap = function (state, e) {
|
||||||
|
const currentCenter = state.polygon.properties.center;
|
||||||
|
if (currentCenter.length === 0) {
|
||||||
|
// dragPan.disable(this)
|
||||||
|
state.polygon.properties.center = [e.lngLat.lng, e.lngLat.lat];
|
||||||
|
} else {
|
||||||
|
// dragPan.enable(this);
|
||||||
|
return this.changeMode('simple_select', { featureIds: [state.polygon.id] });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
drawCircleMode.onDrag = drawCircleMode.onMouseMove = function (state, e) {
|
||||||
|
const center = state.polygon.properties.center;
|
||||||
|
if (center.length > 0) {
|
||||||
|
const distanceInKm = distance(
|
||||||
|
turfHelpers.point(center),
|
||||||
|
turfHelpers.point([e.lngLat.lng, e.lngLat.lat]),
|
||||||
|
{
|
||||||
|
units: 'kilometers',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const circleFeature = circle(center, distanceInKm);
|
||||||
|
state.polygon.incomingCoords(circleFeature.geometry.coordinates);
|
||||||
|
state.polygon.properties.radiusInKm = distanceInKm;
|
||||||
|
state.polygon.properties.lastClickCoord = [e.lngLat.lng, e.lngLat.lat];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//它决定当前 Drew 数据存储中的哪些特性将在地图上呈现。
|
||||||
|
//所有传递给“显示”的特性都将被渲染,因此可以为每个内部特性传递多个显示特性。
|
||||||
|
//有关如何制作显示特性的建议,请参阅‘ styling-pull’in‘ API.md’
|
||||||
|
drawCircleMode.toDisplayFeatures = function (state, geojson, display) {
|
||||||
|
const isActivePolygon = geojson.properties.id === state.polygon.id;
|
||||||
|
geojson.properties.active = isActivePolygon ? 'true' : 'false';
|
||||||
|
display(geojson);
|
||||||
|
};
|
||||||
|
export default drawCircleMode;
|
@ -1,13 +1,16 @@
|
|||||||
import { defineConfig } from 'father';
|
import { defineConfig } from 'father-plugin-less';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: {
|
esm: {
|
||||||
output: 'es',
|
output: 'es',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
cjs: {
|
cjs: {
|
||||||
output: 'lib',
|
output: 'lib',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
|
plugins: ['father-plugin-less'],
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { defineConfig } from 'father';
|
import { defineConfig } from 'father-plugin-less';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
// more father config: https://github.com/umijs/father/blob/master/docs/config.md
|
||||||
esm: {
|
esm: {
|
||||||
output: 'es',
|
output: 'es',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
cjs: {
|
cjs: {
|
||||||
output: 'lib',
|
output: 'lib',
|
||||||
ignores: ['**/demo/*', 'src/**/demo/*']
|
ignores: ['**/demo/*', 'src/**/demo/*'],
|
||||||
|
transformer: 'babel',
|
||||||
},
|
},
|
||||||
|
plugins: ['father-plugin-less'],
|
||||||
});
|
});
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
.zhst-image__btn-group {
|
|
||||||
// display: flex;
|
|
||||||
width: 30px;
|
|
||||||
box-shadow: 0 2px 6px 0 rgb(0 0 0 / 40%);
|
|
||||||
|
|
||||||
&__item {
|
|
||||||
display: flex;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: #000;
|
|
||||||
|
|
||||||
&>button {
|
|
||||||
padding: 0;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #09f;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
color: #09f;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>span {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--active {
|
|
||||||
&>button {
|
|
||||||
color: #09f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--circle {
|
|
||||||
background-color: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--circle &__item {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
.zhst-image__img-view {
|
|
||||||
position: relative;
|
|
||||||
width: calc(100%);
|
|
||||||
height: 100%;
|
|
||||||
font-size: 0;
|
|
||||||
|
|
||||||
&__face-score {
|
|
||||||
position: absolute;
|
|
||||||
right: 20px;
|
|
||||||
bottom: 80px;
|
|
||||||
color: red;
|
|
||||||
font-family: 'Microsoft YaHei';
|
|
||||||
font-size: 19px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-opt {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 99;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-crop-opt {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 99;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-align {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-main {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
font-size: 0;
|
|
||||||
|
|
||||||
&--cursor {
|
|
||||||
& canvas {
|
|
||||||
min-height: 320px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-screenshot {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,8 +16,12 @@ var CompareImage = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
var customizePrefixCls = props.prefixCls,
|
var customizePrefixCls = props.prefixCls,
|
||||||
_props$label = props.label,
|
_props$label = props.label,
|
||||||
label = _props$label === void 0 ? '标题' : _props$label,
|
label = _props$label === void 0 ? '标题' : _props$label,
|
||||||
|
_props$width = props.width,
|
||||||
|
width = _props$width === void 0 ? '400' : _props$width,
|
||||||
|
height = props.height,
|
||||||
_props$openRoll = props.openRoll,
|
_props$openRoll = props.openRoll,
|
||||||
openRoll = _props$openRoll === void 0 ? true : _props$openRoll,
|
openRoll = _props$openRoll === void 0 ? true : _props$openRoll,
|
||||||
|
labelColor = props.labelColor,
|
||||||
_props$url = props.url,
|
_props$url = props.url,
|
||||||
url = _props$url === void 0 ? '' : _props$url,
|
url = _props$url === void 0 ? '' : _props$url,
|
||||||
_props$score = props.score,
|
_props$score = props.score,
|
||||||
@ -33,6 +37,7 @@ var CompareImage = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
getPrefixCls = _useContext.getPrefixCls;
|
getPrefixCls = _useContext.getPrefixCls;
|
||||||
var componentName = getPrefixCls('image__compater-view', customizePrefixCls);
|
var componentName = getPrefixCls('image__compater-view', customizePrefixCls);
|
||||||
var imgContainerRef = useRef(null);
|
var imgContainerRef = useRef(null);
|
||||||
|
var containerRef = useRef(null);
|
||||||
var imgInsRef = useRef(null);
|
var imgInsRef = useRef(null);
|
||||||
var _useState = useState(0),
|
var _useState = useState(0),
|
||||||
_useState2 = _slicedToArray(_useState, 2),
|
_useState2 = _slicedToArray(_useState, 2),
|
||||||
@ -47,8 +52,10 @@ var CompareImage = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
setScale(get(data, 'scale', 0));
|
setScale(get(data, 'scale', 0));
|
||||||
});
|
});
|
||||||
if (generateImg(url)) {
|
if (generateImg(url)) {
|
||||||
|
console.log('containerRef', containerRef);
|
||||||
imgInsRef.current = new Viewer(imgContainerRef.current, {
|
imgInsRef.current = new Viewer(imgContainerRef.current, {
|
||||||
image: generateImg(url)
|
image: generateImg(url),
|
||||||
|
height: parseInt(height)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return function () {
|
return function () {
|
||||||
@ -74,9 +81,15 @@ var CompareImage = /*#__PURE__*/forwardRef(function (props, ref) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
return /*#__PURE__*/React.createElement("div", {
|
return /*#__PURE__*/React.createElement("div", {
|
||||||
className: classNames("".concat(componentName, "__container"))
|
className: classNames("".concat(componentName, "__container")),
|
||||||
|
style: {
|
||||||
|
width: "".concat(parseInt(width), "px")
|
||||||
|
}
|
||||||
}, label && /*#__PURE__*/React.createElement("div", {
|
}, label && /*#__PURE__*/React.createElement("div", {
|
||||||
className: classNames("".concat(componentName, "__label"))
|
className: classNames("".concat(componentName, "__label")),
|
||||||
|
style: {
|
||||||
|
backgroundColor: labelColor
|
||||||
|
}
|
||||||
}, label), !url ? /*#__PURE__*/React.createElement("div", {
|
}, label), !url ? /*#__PURE__*/React.createElement("div", {
|
||||||
className: classNames("".concat(componentName, "__empty"))
|
className: classNames("".concat(componentName, "__empty"))
|
||||||
}, /*#__PURE__*/React.createElement("img", {
|
}, /*#__PURE__*/React.createElement("img", {
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
.zhst-image__CornerScore {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 56px;
|
|
||||||
height: 22px;
|
|
||||||
line-height: 22px;
|
|
||||||
text-align: right;
|
|
||||||
padding-right: 1px;
|
|
||||||
background-size: 100%;
|
|
||||||
background-image: url('data: image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAAAsCAYAAAC9rDzHAAAByUlEQVR4Xu2cO08DMRCEJy0tlNBCSwmU0EIJLbS0UEILLTX/Fo3kk1AUHrrsjB3dWIoUnZTdvfnOZ6+1mxXGGHsADgEcA9hvnyMAvJ7xiwKrjuoQ0HmDxu8ZMxToAZDQrgAE2gxg6z9xAjwFcAvgoCDumGgKuADeA7iI6vUKqAFyE/KU12U9uMmiGuBr4Ong0bIS4A2Aa234sa4CyFzuPfLqFVABfGg5nv4OFu5BAZAbl4+F62q7fQVAJul3tjtYuCMFwEcATNozDAooAL7ltMVATngS8+kLP54UMzAAjc9VABrFVrgKQIWqRpsBaBRb4SoAFaoabQagUWyFqwBUqGq0GYBGsRWuAlChqtFmABrFVrgKQIWqRpsBaBRb4SoAFaoabVYDZLU1K9EyTApUA2RzyrMp9rgRlBWylIIlFRkmBapnIIuZ0hJmgkc3lQBTzGQEN7mqApjNSwd4VTOQr8yXFDL1IbjtDOTMY/dR1r0+/LZaA1n7yb6/wOsEb+4rlMDYdZR0oSO4uZuYtEkPAO17CP9dA3nCwll3Mlj8iw/nL4ABN/gj8hPAgBsc3KY1kJuTs7Y5yV+B7BBA5nKXrSUsKcGOgJvC/ALSJBp5mBHCFAAAAABJRU5ErkJggg==');
|
|
||||||
z-index: 99;
|
|
||||||
|
|
||||||
&>span {
|
|
||||||
padding-right: 6px;
|
|
||||||
line-height: 22px;
|
|
||||||
font-size: 12px;
|
|
||||||
vertical-align: middle;
|
|
||||||
color: rgba(255, 255, 255, 100%);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
.zhst-image__compater-view {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
&>div:first-child {
|
|
||||||
margin-right: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>div:last-child {
|
|
||||||
margin-left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__container {
|
|
||||||
font-size: 0;
|
|
||||||
position: relative;
|
|
||||||
box-sizing: content-box;
|
|
||||||
border: 1px solid #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__view {
|
|
||||||
min-width: 345px;
|
|
||||||
min-height: 450px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__label {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 99;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
font-size: 16px;
|
|
||||||
height: 34px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
// width: 48px;
|
|
||||||
padding: 0 6px;
|
|
||||||
background: #09f;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__tool {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 40px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: #f9f9f9;
|
|
||||||
|
|
||||||
i,
|
|
||||||
span {
|
|
||||||
color: #333 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>*:not(:last-child) {
|
|
||||||
margin-right: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__scale {
|
|
||||||
display: inline-block;
|
|
||||||
width: 38px;
|
|
||||||
height: 16px;
|
|
||||||
|
|
||||||
// margin-left: 15px;
|
|
||||||
box-sizing: content-box;
|
|
||||||
border: 1px solid rgb(77 77 77 / 100%);
|
|
||||||
background: rgb(255 255 255 / 100%);
|
|
||||||
border-radius: 2px;
|
|
||||||
color: #4d4d4d;
|
|
||||||
cursor: default;
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 16px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__line {
|
|
||||||
width: 1px;
|
|
||||||
height: 14px;
|
|
||||||
background: #e6e6e6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__empty {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 9;
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background: #f9f9f9;
|
|
||||||
transform: translateY(-100%);
|
|
||||||
|
|
||||||
&>img {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
width: 140px;
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--text {
|
|
||||||
color: #999;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__scoll-module {
|
|
||||||
position: absolute;
|
|
||||||
padding: 12px;
|
|
||||||
bottom: 48px;
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
align-items: flex-end;
|
|
||||||
justify-content: space-between;
|
|
||||||
pointer-events: none;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&__btn {
|
|
||||||
width: 56px;
|
|
||||||
height: 56px;
|
|
||||||
opacity: 0.4;
|
|
||||||
pointer-events: all;
|
|
||||||
|
|
||||||
&>span {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&__btn:hover {
|
|
||||||
opacity: 0.6;
|
|
||||||
background-color: #09f !important;
|
|
||||||
color: #fff !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
.zhst-image__video-view__player-mask {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 99;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: rgb(4 4 4 / 70%);
|
|
||||||
|
|
||||||
&--bg {
|
|
||||||
z-index: 999;
|
|
||||||
background-color: rgb(4 4 4 / 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-title {
|
|
||||||
margin-top: 12px;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
& a {
|
|
||||||
color: #09f;
|
|
||||||
cursor: pointer;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.zhst-image__video-view__icon-wraper {
|
|
||||||
display: flex;
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
background-color: rgb(255 255 255 / 10%);
|
|
||||||
border-radius: 50%;
|
|
||||||
cursor: pointer;
|
|
||||||
line-height: 80px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
// &:hover {
|
|
||||||
// background: #0099ff;
|
|
||||||
// }
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
.zhst-image__range {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&--no-slider {
|
|
||||||
.next-range-slider {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& .next-range .next-range-track {
|
|
||||||
height: 8px;
|
|
||||||
margin-top: -4px;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .next-range .next-range-selected {
|
|
||||||
height: 8px;
|
|
||||||
margin-top: -4px;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .next-range .next-range-slider-inner {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
border-color: #fff;
|
|
||||||
margin-top: -7px;
|
|
||||||
margin-left: -7px;
|
|
||||||
background-color: #0098ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .next-range .next-range-slider {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
margin-top: -7px;
|
|
||||||
margin-left: -7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .next-range.simulation-click>.next-range-slider-inner {
|
|
||||||
border: 2px solid #fff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .next-range .next-range-frag.next-range-active .next-range-slider .next-range-slider-inner {
|
|
||||||
border: 2px solid #fff !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
& .next-range .next-range-slider.next-range-slider-moving .next-range-slider-inner {
|
|
||||||
border: 2px solid #fff !important;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
.zhst-image__video-view {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #333;
|
|
||||||
|
|
||||||
// &-flv {
|
|
||||||
// width: 85%;
|
|
||||||
// }
|
|
||||||
&-screenshot {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-crop-container {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-align {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-opt {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 99;
|
|
||||||
bottom: 0;
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 32px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 12px 0 24px;
|
|
||||||
background-color: rgb(0 0 0 / 80%);
|
|
||||||
line-height: 32px;
|
|
||||||
|
|
||||||
&>div:first-child {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>div:last-child {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-left: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-range {
|
|
||||||
display: flex;
|
|
||||||
height: 32px;
|
|
||||||
flex: 1;
|
|
||||||
align-items: center;
|
|
||||||
line-height: 32px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
&>div:first-child {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>div:last-child {
|
|
||||||
width: 100px;
|
|
||||||
margin-left: 8px;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,6 +9,7 @@ export { default as VideoPlayer } from "./VideoPlayer";
|
|||||||
// antd
|
// antd
|
||||||
export { default as Tabs } from "./tabs";
|
export { default as Tabs } from "./tabs";
|
||||||
export { default as Tree } from "./tree";
|
export { default as Tree } from "./tree";
|
||||||
|
export { default as Spin } from "./spin";
|
||||||
export { default as message } from "./message";
|
export { default as message } from "./message";
|
||||||
export { default as Button } from "./button";
|
export { default as Button } from "./button";
|
||||||
export { default as Image } from "./image";
|
export { default as Image } from "./image";
|
||||||
|
@ -17,6 +17,9 @@ export interface CompareImageProps {
|
|||||||
* @default "默认值"
|
* @default "默认值"
|
||||||
*/
|
*/
|
||||||
label?: string;
|
label?: string;
|
||||||
|
labelColor?: string;
|
||||||
|
width?: string;
|
||||||
|
height?: string
|
||||||
showTools?: boolean;
|
showTools?: boolean;
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
openRoll?: boolean; //开启翻页
|
openRoll?: boolean; //开启翻页
|
||||||
@ -39,7 +42,10 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
|
|||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
label = '标题',
|
label = '标题',
|
||||||
|
width = '400',
|
||||||
|
height,
|
||||||
openRoll = true,
|
openRoll = true,
|
||||||
|
labelColor,
|
||||||
url = '',
|
url = '',
|
||||||
score = 0,
|
score = 0,
|
||||||
preDisable,
|
preDisable,
|
||||||
@ -69,11 +75,10 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (generateImg(url)) {
|
imgInsRef.current = new Viewer(imgContainerRef.current, {
|
||||||
imgInsRef.current = new Viewer(imgContainerRef.current, {
|
image: url,
|
||||||
image: generateImg(url),
|
height: parseInt(height!),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
handleTransformChange?.remove();
|
handleTransformChange?.remove();
|
||||||
@ -96,8 +101,8 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(`${componentName}__container`)}>
|
<div className={classNames(`${componentName}__container`)} style={{ width: `${parseInt(width)}px` }}>
|
||||||
{label && <div className={classNames(`${componentName}__label`)}>{label}</div>}
|
{label && <div className={classNames(`${componentName}__label`)} style={{ backgroundColor: labelColor }}>{label}</div>}
|
||||||
{!url ? (
|
{!url ? (
|
||||||
<div className={classNames(`${componentName}__empty`)}>
|
<div className={classNames(`${componentName}__empty`)}>
|
||||||
<img
|
<img
|
||||||
@ -121,7 +126,6 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
|
|||||||
style={{ width: '56px' }}
|
style={{ width: '56px' }}
|
||||||
icon={<IconFont icon="icon-qiehuanzuo" size={32} color='#fff' />}
|
icon={<IconFont icon="icon-qiehuanzuo" size={32} color='#fff' />}
|
||||||
>
|
>
|
||||||
|
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className={classNames(`${componentName}__scoll-module__btn`)}
|
className={classNames(`${componentName}__scoll-module__btn`)}
|
||||||
@ -159,7 +163,6 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
|
|||||||
<span className={classNames(`${componentName}__tool__scale`)}>
|
<span className={classNames(`${componentName}__tool__scale`)}>
|
||||||
{Math.round(scale * 100) + '%'}
|
{Math.round(scale * 100) + '%'}
|
||||||
</span>
|
</span>
|
||||||
<div className={classNames(`${componentName}__tool__line`)}></div>
|
|
||||||
{/* </Button> */}
|
{/* </Button> */}
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
.zhst-image__CornerScore {
|
.zhst-image__CornerScore {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 36px;
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
|
@ -13,7 +13,7 @@ export const CornerScore: React.FC<ScoreProps> = (props) => {
|
|||||||
return useMemo(
|
return useMemo(
|
||||||
() => (
|
() => (
|
||||||
<div className={classNames(`${componentName}`)}>
|
<div className={classNames(`${componentName}`)}>
|
||||||
<span>{~~(scoreTxt * 100)}%</span>
|
<span>{~~(scoreTxt)}%</span>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
[scoreTxt]
|
[scoreTxt]
|
||||||
|
@ -19,39 +19,36 @@
|
|||||||
border: 1px solid #f0f0f0;
|
border: 1px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__view {
|
|
||||||
min-width: 345px;
|
|
||||||
min-height: 450px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__label {
|
&__label {
|
||||||
|
padding: 4px 8px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
right: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
font-size: 16px;
|
font-size: 14px;
|
||||||
height: 34px;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
// width: 48px;
|
background: #52ACFA;
|
||||||
padding: 0 6px;
|
|
||||||
background: #09f;
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
border-bottom-left-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__tool {
|
&__tool {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40px;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: #f9f9f9;
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
|
||||||
i,
|
i,
|
||||||
span {
|
span {
|
||||||
color: #333 !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
@ -63,14 +60,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__scale {
|
&__scale {
|
||||||
|
padding: 2px 14px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 38px;
|
|
||||||
height: 16px;
|
|
||||||
|
|
||||||
// margin-left: 15px;
|
// margin-left: 15px;
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
border: 1px solid rgb(77 77 77 / 100%);
|
border: 1px solid #fff;
|
||||||
background: rgb(255 255 255 / 100%);
|
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
color: #4d4d4d;
|
color: #4d4d4d;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
@ -72,6 +72,7 @@ const CropperImage = forwardRef<CropperImageRefProps, CropperImageProps>((props,
|
|||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
url,
|
url,
|
||||||
|
height = 0,
|
||||||
odList,
|
odList,
|
||||||
selectedItem,
|
selectedItem,
|
||||||
onMouseDown,
|
onMouseDown,
|
||||||
@ -115,7 +116,8 @@ const CropperImage = forwardRef<CropperImageRefProps, CropperImageProps>((props,
|
|||||||
image: url,
|
image: url,
|
||||||
scaleAble,
|
scaleAble,
|
||||||
selectAble,
|
selectAble,
|
||||||
height: 600,
|
// @ts-ignore
|
||||||
|
height: parseInt(height),
|
||||||
fitScaleAsMinScale: true,
|
fitScaleAsMinScale: true,
|
||||||
dragAble: false,
|
dragAble: false,
|
||||||
});
|
});
|
||||||
|
@ -80,5 +80,3 @@ demo:
|
|||||||
| strokeWidth | 仪表盘进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | - |
|
| strokeWidth | 仪表盘进度条线的宽度,单位是进度条画布宽度的百分比 | number | 6 | - |
|
||||||
|
|
||||||
## 主题变量(Design Token)
|
## 主题变量(Design Token)
|
||||||
|
|
||||||
<ComponentTokenTable component="Progress"></ComponentTokenTable>
|
|
||||||
|
@ -27,7 +27,7 @@ const RelatedCarousel: FC<RelatedCarouselProps> = (_props: any) => {
|
|||||||
onItemSelected,
|
onItemSelected,
|
||||||
label,
|
label,
|
||||||
onClick,
|
onClick,
|
||||||
width = '742px',
|
width = '100%',
|
||||||
height = '100px',
|
height = '100px',
|
||||||
selectedKey: defaultSelectedKey
|
selectedKey: defaultSelectedKey
|
||||||
} = _props
|
} = _props
|
||||||
|
@ -25,6 +25,8 @@ module.exports = __toCommonJS(src_exports);
|
|||||||
var import_antd = require("antd");
|
var import_antd = require("antd");
|
||||||
var import_func = require("@zhst/func");
|
var import_func = require("@zhst/func");
|
||||||
var Slave = class {
|
var Slave = class {
|
||||||
|
config;
|
||||||
|
authTokenDefine;
|
||||||
// 设置参数
|
// 设置参数
|
||||||
constructor() {
|
constructor() {
|
||||||
this.authTokenDefine = "ZHST_AUTH_TOKEN";
|
this.authTokenDefine = "ZHST_AUTH_TOKEN";
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"declaration": true,
|
"declaration": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
"declarationMap": true,
|
||||||
"composite": true,
|
"composite": true,
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
@ -12,9 +13,9 @@
|
|||||||
"@zhst/*": ["packages/*/src/"]
|
"@zhst/*": ["packages/*/src/"]
|
||||||
},
|
},
|
||||||
"importHelpers": false,
|
"importHelpers": false,
|
||||||
"sourceMap": true,
|
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
|
"allowJs": true,
|
||||||
"jsxFactory": "React.createElement",
|
"jsxFactory": "React.createElement",
|
||||||
"jsxFragmentFactory": "React.Fragment",
|
"jsxFragmentFactory": "React.Fragment",
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
|
Loading…
Reference in New Issue
Block a user