feat: 大图初稿

This commit is contained in:
NICE CODE BY DEV 2024-01-17 19:25:13 +08:00
parent b42ae38eb2
commit 1fdceb89b1
23 changed files with 546 additions and 466 deletions

View File

@ -1,11 +1,14 @@
// @ts-nocheck
import React, { useRef, useState } from 'react'
import { Descriptions, Modal, Tabs } from 'antd';
import { ConfigProvider, Descriptions, Modal, Tabs, Button, BigImagePreview } from '@zhst/meta';
import classNames from 'classnames'
import type { ModalProps, DescriptionsProps, TabsProps } from 'antd'
import type { ModalProps, DescriptionsProps, TabsProps } from '@zhst/meta'
import { get } from '@zhst/func';
import { MODEL_TYPE, TAB_TYPE } from '@zhst/types';
import './index.less'
import Navigation from './components/navigation';
import CombineImage from './components/CombineImage'
import { BIG_IMAGE_DATA } from './mock'
const DescriptionsItem = Descriptions.Item
@ -21,12 +24,14 @@ export interface BigImageModalProps extends ModalProps {
}
tabsConfig: { // 导航栏配置
data: Pick<TabsProps, 'items'> & {
key: 'NORMAL' | 'COMPATER' | 'TRACK'
key: TAB_TYPE
} // 导航栏列表
}
dataSource: any
imageData: any
relatedData: any
mode?: MODEL_TYPE
changeMode?: (mode: MODEL_TYPE) => void
}
const initialStyle ={
@ -42,35 +47,52 @@ const BigImageModal: React.FC<BigImageModalProps> = (props) => {
descriptionConfig = {
data: []
},
tabsConfig = {
dataSource = [],
imageData = [],
relatedData = [],
mode = 'IMAGE',
changeMode
} = props
const tabsConfig = {
data: [
{
label: '对比图模式',
key: '1',
children: '对比图组件',
children: (
<CombineImage
targetData={dataSource}
compareData={dataSource}
/>
)
},
{
label: '场景图模式',
key: '2',
children: '场景图组件',
children: (
<BigImagePreview
height={'500px'}
dataSource={BIG_IMAGE_DATA}
/>
)
}
]
}
],
},
dataSource = [],
imageData = [],
relatedData = [],
} = props
const showCropRef = useRef(false);
const scaleRef = useRef(0);
// ========================== 头切换 =========================
const [activeKey, setActiveKey] = useState<string>(get(tabsConfig, 'data[0].key'));
const [tab, setTab] = useState<TAB_TYPE>(get(tabsConfig, 'data[0].key'));
const [activeKey, setActiveKey] = useState<string>('related');
// ========================= 预览切换下标 =========================
const [previewIndex, setPreviewIndex] = useState<number>(0)
const [isRelated, setIsRelated] = useState<number>(false)
// ========================= 模式切换 ============================
const [currentMode, setCurrentMode] = useState(mode)
return (
<Modal
destroyOnClose
@ -79,6 +101,22 @@ const BigImageModal: React.FC<BigImageModalProps> = (props) => {
className={componentPrefix}
title={title}
{...props}
>
<ConfigProvider
theme={{
token: {
colorTextSecondary: 'rgba(0,0,0,0.45)'
},
components: {
Descriptions: {
titleMarginBottom: '20px',
viewBg: '#f6f6f6',
titleColor: 'rgba(0,0,0,0.45)',
colorTextLabel: 'rgba(0,0,0,0.45)',
contentColor: 'rgba(0,0,0,0.88)',
},
},
}}
>
{descriptionConfig.data.map(descriptions => (
<Descriptions
@ -102,17 +140,11 @@ const BigImageModal: React.FC<BigImageModalProps> = (props) => {
))}
</Descriptions>
))}
<Tabs
defaultActiveKey={activeKey}
centered
tabBarStyle={{ fontSize: '18px' }}
items={tabsConfig.data}
{...tabsConfig}
/>
</ConfigProvider>
<div
className={classNames(`${componentPrefix}-view-container`)}
style={
activeKey === 'TRACK'
tab === 'TRACK'
? {
height: '718px',
marginBottom: '0px',
@ -120,8 +152,17 @@ const BigImageModal: React.FC<BigImageModalProps> = (props) => {
: {}
}
>
<Tabs
activeKey={tab}
centered
onChange={v => setTab(v)}
tabBarStyle={{ fontSize: '18px', fontWeight:'bold' }}
items={tabsConfig.data}
{...tabsConfig}
/>
{/* 切换按钮组件 */}
{
activeKey !== 'TRACK' && (
tab !== 'TRACK' && (
<>
{/* ----------------------------------- 上一张按钮 ---------------------------------- */}
<Navigation
@ -154,6 +195,26 @@ const BigImageModal: React.FC<BigImageModalProps> = (props) => {
</>
)
}
{/* --------------------------------- 模型碰撞组件 --------------------------------- */}
{isRelated && tab !== 'TRACK' && (
<div className="relatedWrapper">
<Tabs
className="relatedTabs"
tabPosition={'left'}
activeKey={activeKey}
onChange={(key: string) => {
setActiveKey(key);
}}
items={tabList.map((item) => {
return {
label: item.label,
key: item.key,
children: item.children,
};
})}
/>
</div>
)}
</div>
</Modal>
)

View File

@ -0,0 +1,28 @@
import React, { FC } from 'react';
import { CompareImage, Flex, Score } from '@zhst/meta'
interface ComBineImageProps {
targetData: {
url: string;
score: number;
}[]
compareData: {
url: string;
score: number
}[]
}
const ComBineImage: FC<ComBineImageProps> = (props) => {
const { targetData = [], compareData = [] } = props
return (
<Flex justify='space-evenly' align='center' style={{ padding:'0 32px' }}>
<CompareImage dataSource={targetData} label="目标图" />
<Score score={0.2} />
<CompareImage dataSource={compareData} openRoll={false} label="对比图" />
</Flex>
)
}
export default ComBineImage

View File

@ -0,0 +1,66 @@
import React from 'react';
import { BigImageModal } from '@zhst/biz'
import { DescriptionsProps } from '@zhst/meta'
import { IMAGE_DATA, BIG_IMAGE_DATA } from '../mock'
import { bigImageModalAdapter } from '@zhst/biz'
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: '否',
},
]
}
];
export default () => {
const imageDataAdapter = bigImageModalAdapter(IMAGE_DATA)
console.log(imageDataAdapter)
return (
<BigImageModal
title="查看大图"
open
dataSource={IMAGE_DATA.dataSource}
imageData={IMAGE_DATA.dataSource}
width={1098}
descriptionConfig={{ data: descriptionList }}
/>
)
}

View File

@ -1,5 +1,4 @@
.zhst-image {
.zhst-dialog-content {
box-shadow: 0 4px 12px rgb(0 0 0 / 20%);
}
@ -8,7 +7,6 @@
&-view-container {
position: relative;
width: 100%;
height: 532px;
margin-bottom: 16px;
&__nav {
@ -227,232 +225,6 @@
}
}
.zhst-image__header {
width: 100%;
// margin-top: 3px;
margin-bottom: 10px;
&__pad0 {
padding: 0;
}
&__pad66 {
padding: 0 66px;
}
&__bar {
display: flex;
width: 100%;
background: #f6f6f6;
// box-shadow: 0px 0px 8px 0px rgba(172, 172, 172, 0.5);
justify-content: center;
// border-color: #f0f0f0;
// border-bottom-width: 1px;
// border-bottom-style: solid;
}
&__barNoColor {
display: flex;
width: 100%;
justify-content: center;
border-color: #f0f0f0;
border-bottom-width: 1px;
border-bottom-style: solid;
}
&__item {
position: relative;
display: flex;
height: 40px;
align-items: center;
justify-content: center;
margin: 0 15px;
color: #999;
cursor: pointer;
font-size: 14px;
font-weight: bold;
line-height: 19px;
transition: font-size 0.3s ease;
&:hover {
// font-size: 18px;
color: #333;
}
&::before {
position: absolute;
bottom: 0;
left: 50%;
width: 0;
border-bottom: 2px solid #09f;
content: '';
transition: all 0.3s ease;
}
&--active {
background-color: transparent;
color: #333;
font-size: 18px;
// color: #0099ff;
&::before {
left: 0;
width: 100%;
}
}
}
}
.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 {
position: relative;
width: 345px;
height: 460px;
box-sizing: content-box;
border: 1px solid #f0f0f0;
}
&__view {
width: 345px;
height: 460px;
}
&__label {
position: absolute;
z-index: 99;
top: 0;
left: 0;
display: flex;
height: 34px;
align-items: center;
justify-content: center;
// width: 48px;
padding: 0 6px;
background: #09f;
color: #fff;
}
&__tool {
display: flex;
width: 345px;
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 {
width: 140px;
height: 80px;
}
&--text {
color: #999;
font-size: 14px;
line-height: 22px;
}
}
&__scoll-module {
position: absolute;
top: 0%;
left: 0%;
display: flex;
width: 100%;
height: 100%;
align-items: flex-end;
justify-content: space-between;
pointer-events: none;
&__btn {
display: flex;
width: 50px;
height: 50px;
align-items: center;
justify-content: center;
margin: 6px;
border-radius: 50%;
opacity: 0.5;
pointer-events: all;
&>span {
display: flex;
align-items: center;
justify-content: center;
}
}
&__btn:hover {
background-color: #09f !important;
color: #fff !important;
}
}
}
.zhst-image__trackmodel {
&__panel {
position: relative;
@ -645,23 +417,6 @@
}
}
.zhst-image__null {
display: flex;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
&__text {
// margin-left: 105px;
margin-top: 8px;
color: #999;
font-size: 14px;
width: 100%;
text-align: center;
}
}
.zhst-image__attributePanel {
margin: 0 66px;
background: #f6f6f6;
@ -710,45 +465,27 @@
.relatedContent {
width: 100%;
height: 100px;
display: flex;
.relatedPics {
width: 742px;
height: 100px;
// display: flex;
// box-sizing: border-box;
// background: #fafafa;
// border-radius: 2px;
// border: 1px solid #f0f0f0;
// .LeftBtn,
// .RighttBtn {
// width: 34px;
// height: 100%;
// display: flex;
// justify-content: center;
// align-items: center;
// }
// .ListContent {
// flex: 1;
// height: 100%;
// }
}
.disabled {
color: rgba(0, 0, 0, 0.25);
color: rgba(0, 0, 0, 25%);
}
.relatedBtn {
flex: 1;
font-size: 14px;
color: #333333;
color: #333;
display: flex;
align-items: flex-end;
cursor: pointer;
&:hover {
color: #0099ff;
color: #09f;
}
}
}

View File

@ -9,68 +9,5 @@ group:
# 大图弹框
```jsx
import React from 'react';
import { Button } from 'antd'
import { BigImageModal } from '@zhst/biz'
import { DescriptionsProps } from '@zhst/biz'
import { IMAGE_DATA } from './mock.ts'
<code src="./demo/index.tsx">基本</code>
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: '否',
},
]
}
];
export default () => {
console.log(IMAGE_DATA)
return (
<BigImageModal
title="查看大图"
open
dataSource={IMAGE_DATA.dataSource}
imageData={IMAGE_DATA.dataSource}
width={1098}
descriptionConfig={{ data: descriptionList }}
/>
)
}
```

View File

@ -900,3 +900,152 @@ export const IMAGE_DATA = {
},
"specialTitle": ""
}
export const BIG_IMAGE_DATA = [
{
imageKey: 'http://10.0.0.120:30003/file/singer-20240110/1/5/1744894622934503424.jpg',
odRect:{
"x":0.5445312,
"y":0.19166666,
"w":0.08671875,
"h":0.40138888
},
attachImg: [
{
"url": "http://10.0.0.120:30003/file/singer-20240110/1/5/1744894622695428096.jpg","label": "形体"
},{
"url": "http://10.0.0.120:30003/file/singer-20240110/1/5/1744894588427964418.jpg",
"label": "人脸"
}
],
score: '0.6', // 人脸质量分
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,
}
]
},
{
imageKey: 'http://10.0.0.120:30003/file/singer-20240115/1/9/1746795581994436608.jpg',
odRect:{
"x":0.553125,"y":0.29722223,"w":0.048958335,"h":0.2462963
},
attachImg: [
{
"url": "http://10.0.0.120:30003/file/singer-20240115/1/9/1746795581163964416.jpg","label": "形体"
},{
"url": "http://10.0.0.120:30003/file/singer-20240115/1/9/1746795546867140608.jpg",
"label": "人脸"
}
],
score: 0.815207, // 人脸质量分
showScore: true, // 人脸质量分
cameraPosition: 'string', // 摄像头位置
time: '2022-01-01', // 摄像头拍摄时间
objects: [
{
"objectIndex": {
"objectId": "1746816737430472704",
"solutionId": "0",
"deviceId": "0",
"fragmentId": "0"
},
"objectType": "OBJECT_TYPE_PEDESTRAIN",
"sourceObjectId": "0",
"frameInfo": {
"frameId": "0",
"frameTimestamp": "1705308539109",
"width": 0,
"height": 0,
"originWidth": 0,
"originHeight": 0,
"offsetTime": "0",
"skipNumber": "0"
},
"infoOnSource": {
"bboxInFrame": {
"bboxRatio": {
"x": 0.5519352,
"y": 0.2965385,
"w": 0.05185461,
"h": 0.24698898
},
},
"countInSource": 0,
"indexInSource": 0
},
"qualityScore": 0,
},
{
"objectIndex": {
"objectId": "1746816737430472705",
"solutionId": "0",
"deviceId": "0",
"fragmentId": "0"
},
"objectType": "OBJECT_TYPE_PEDESTRAIN",
"sourceObjectId": "0",
"level": 0,
"confidence": 0.9310699,
"frameInfo": {
"frameId": "0",
"frameTimestamp": "1705308539109",
"width": 0,
"height": 0,
"originWidth": 0,
"originHeight": 0,
"offsetTime": "0",
"skipNumber": "0"
},
"infoOnSource": {
"bboxInFrame": {
"bboxRatio": {
"x": 0.58543766,
"y": 0.3203356,
"w": 0.052037954,
"h": 0.2664015
},
},
"countInSource": 0,
"indexInSource": 0
},
"qualityScore": 0,
}
]
}
]

View File

@ -2,44 +2,12 @@
*
*/
import React from 'react';
import { AlgorithmVersionStr, HumanProperty, ObjectType, Rect, ViewOption, AlignType, IScreenshotButtonProp, ODRECT } from '@zhst/types'
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 ImgViewProps extends React.HTMLAttributes<HTMLElement> {
imageKey: string; //不在监听url变化 更新走销毁
odRect: ODRECT;
attachImg?: Array<{ label: string; url: string }>;
showAttachImgLabel: boolean;
/* 截图渲染 */
screenshotButtonAlign: AlignType;
screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement;
/* 可观测值 */
scale$?: number;
showCrop$?: boolean;
hideLeftTopBtn?: boolean;
score?: number;
viewOption?: ViewOption;
}
export interface VideoViewProps {
/* 播放地址 */
flvUrl: string;
/* 播放总时间 */
maxDuration?: number;
/* 截图渲染 */
screenshotButtonAlign?: AlignType;
screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => React.ReactElement;
/* 默认截图框 */
defautlNormalizationRect?: Rect;
/* 截图回调 */
onCropChange?: (showCrop: boolean, normalizationRect: null | Rect) => void;
/* 可观测值 */
showCrop$?: boolean;
}
export interface CarouselProps {
hasPre?: boolean;
hasNext?: boolean;
@ -60,21 +28,6 @@ export interface HeaderProps {
tabsFilter: TAB_TYPE[];
}
export interface ImgViewRef {
/* 图片实例 */
imgInsRef: React.MutableRefObject<any>;
/* 切换图片模式 */
setShowCrop: React.Dispatch<React.SetStateAction<boolean>>;
}
export interface VideoViewRef {
/* 当前图片模式 */
cropAble: boolean;
setShowCrop: React.Dispatch<React.SetStateAction<boolean>>;
downloadVideoframe: () => void;
}
export interface ParamProps {
tab: string;
selectItem: ISelectItem;
@ -134,9 +87,9 @@ interface IOldImageData {
hasNext?: boolean;
selectIndex?: number;
onSelectIndexChange?: (i: number) => void;
dataSource: any[];
dataSources: any[];
relatedData?: any[];
dataSource: BigImageData[];
dataSources: BigImageData[];
relatedData?: BigImageData[];
transformPropFunc: (item: any) => ISelectItem;
transformVideoPropFunc: (
item: ISelectItem
@ -170,8 +123,18 @@ export interface ToolProps {
disableVideo: boolean;
}
export default (data: IOldImageData) => {
const newData = data
return newData
export interface ImageModalDataProps {
targetData: []
compactData: []
}
const adapter = (data: IOldImageData): ImageModalDataProps => {
return {
targetData: [],
compactData: [],
}
}
export default adapter

View File

@ -1 +1 @@
export { default as BigImageModalAdapter } from './BigImageModalAdapter'
export { default as bigImageModalAdapter } from './bigImageModalAdapter'

View File

@ -47,17 +47,17 @@ export interface ImgViewProps extends React.HTMLAttributes<HTMLElement> {
time?: string | number
objects: any[]
}>
showAttachImgLabel: boolean; // 是否显示缩略图
showOpt: boolean; // 是否显示操作面板
showAttachImgLabel?: boolean; // 是否显示缩略图
showOpt?: boolean; // 是否显示操作面板
width?: string | number; // 画布宽度
height?: string | number; // 画布高度
/* 截图渲染 */
screenshotButtonAlign: AlignType;
screenshotButtonRender: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
screenshotButtonAlign?: AlignType;
screenshotButtonRender?: (screenshotButtonProp: IScreenshotButtonProp) => ReactElement;
hideLeftTopBtn?: boolean;
showScore?: boolean // 是否显示相似度
viewOption?: ViewOption;
objects: IOdRectOrigin[] // 图片人物框选
objects?: IOdRectOrigin[] // 图片人物框选
}
export interface ImgViewRef {
/* 图片实例 */

View File

@ -1,5 +1,5 @@
import BigImagePreview from './BigImagePreview'
export type { ImgViewProps } from './BigImagePreview'
export type { ImgViewProps, ImgViewRef } from './BigImagePreview'
export default BigImagePreview

View File

@ -15,14 +15,14 @@ export interface CompareImageProps {
* @description
* @default "默认值"
*/
label: string;
openRoll?: boolean; //开启滚动模式
label?: string;
openRoll?: boolean; //开启翻页
dataSource?: Array<{
url: string;
score: number;
score: number | string;
}>;
showScore?: boolean; // 是否展示相似度
current: number; // 当前图片下标
current?: number; // 当前图片下标
}
export interface CompareImageRefProps {
@ -31,7 +31,7 @@ export interface CompareImageRefProps {
// 对比图组件
const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props, ref) => {
const { label, openRoll = false, dataSource = [], showScore = true, current = 0 } = props;
const { label = '标题', openRoll = true, dataSource = [], showScore = true, current = 0 } = props;
const imgContainerRef = useRef(null);
const imgInsRef = useRef<any>(null);
const [scale, setScale] = useState(0);
@ -40,6 +40,8 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
// 初始化页面
useEffect(() => {
if (!dataSource?.length) return
const handleTransformChange = addEventListenerWrapper(
imgContainerRef.current,
'viewer-transform-change',
@ -87,6 +89,8 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
handleIndexChange
}));
if (!dataSource) return null
return (
<div className={classNames(`${componentName}__container`)}>
<div className={classNames(`${componentName}__label`)}>{label}</div>
@ -125,7 +129,7 @@ const CompareImage = forwardRef<CompareImageRefProps, CompareImageProps>((props,
</Button>
</div>
)}
{showScore && <CornerScore scoreTxt={dataSource[currentIndex].score} />}
{showScore && <CornerScore scoreTxt={dataSource[currentIndex]?.score || 0} />}
<div className={classNames(`${componentName}__tool`)}>
<Button
type="text"

View File

@ -14,8 +14,6 @@
&__container {
position: relative;
width: 345px;
height: 460px;
box-sizing: content-box;
border: 1px solid #f0f0f0;
}
@ -99,6 +97,7 @@
transform: translateY(-100%);
&>img {
margin-bottom: 12px;
width: 140px;
height: 80px;
}

View File

@ -1,6 +1,6 @@
import React, { useState } from 'react';
import type { DescriptionsProps, RadioChangeEvent } from 'antd';
import { Button, ConfigProvider, Descriptions, Radio } from 'antd';
import type { DescriptionsProps, RadioChangeEvent } from '@zhst/meta';
import { Button, ConfigProvider, Descriptions, Radio } from '@zhst/meta';
const borderedItems: DescriptionsProps['items'] = [
{
@ -98,11 +98,14 @@ const App: React.FC = () => {
return (
<ConfigProvider
theme={{
token: {
colorTextSecondary: 'rgba(0,0,0,0.45)'
},
components: {
Descriptions: {
labelBg: '#f6f6f6',
titleColor: 'rgba(0,0,0,0.88)',
colorTextLabel: 'rgba(0,0,0,0.88)',
viewBg: '#f6f6f6',
titleColor: 'rgba(0,0,0,0.45)',
colorTextLabel: 'rgba(0,0,0,0.45)',
titleMarginBottom: 2,
itemPaddingBottom: 8,
colonMarginRight: 10,

View File

@ -7,6 +7,10 @@ import { genStyleHooks, mergeToken } from '../../theme/internal';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
// Component token here
/**
*
*/
viewBg: string;
/**
* @desc
* @descEN Background color of label
@ -49,7 +53,8 @@ export interface ComponentToken {
extraColor: string;
}
interface DescriptionsToken extends FullToken<'Descriptions'> {}
interface DescriptionsToken extends FullToken<'Descriptions'> {
}
const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
const { componentCls, labelBg } = token;
@ -57,6 +62,7 @@ const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
[`&${componentCls}-bordered`]: {
[`> ${componentCls}-view`]: {
border: `${unit(token.lineWidth)} ${token.lineType} ${token.colorSplit}`,
backgroundColor: `${token.viewBg}`,
'> table': {
tableLayout: 'auto',
borderCollapse: 'collapse',
@ -113,6 +119,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
[componentCls]: {
...resetComponent(token),
...genBorderedStyle(token),
backgroundColor: token.viewBg,
[`&-rtl`]: {
direction: 'rtl',
},
@ -137,6 +144,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
[`${componentCls}-view`]: {
width: '100%',
borderRadius: token.borderRadiusLG,
backgroundColor: token.viewBg,
table: {
width: '100%',
tableLayout: 'fixed',

View File

@ -1,9 +1,7 @@
---
category: Components
title: Divider
title: Divider 分割线
subtitle: 分割线
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*7sMiTbzvaDoAAAAAAAAAAAAADrJ8AQ/original
coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*KPSEQ74PLg4AAAAAAAAAAAAADrJ8AQ/original
demo:
cols: 2
group:
@ -42,7 +40,3 @@ group:
| plain | 文字是否显示为普通正文样式 | boolean | false | 4.2.0 |
| style | 分割线样式对象 | CSSProperties | - | |
| type | 水平还是垂直类型 | `horizontal` \| `vertical` | `horizontal` | |
## 主题变量Design Token
<ComponentTokenTable component="Divider"></ComponentTokenTable>

View File

@ -1,8 +1,11 @@
export { default as doubleClick } from './doubleClick';
export { default as Icon } from './iconfont';
export { default as CompareImage } from './CompareImage'
export type { CompareImageProps } from './CompareImage'
export { default as BigImagePreview } from './BigImagePreview'
export type { ImgViewProps, ImgViewRef } from './BigImagePreview'
export { default as VideoPlayer } from './VideoPlayer'
export type { VideoViewProps, VideoViewRef } from './VideoPlayer'
export { default as Tabs } from './tabs'
export type { TabPaneProps, TabsProps } from './tabs';
export { default as Button } from './button'
@ -25,7 +28,7 @@ export type { FormProps, FormItemProps } from './form';
export { default as Select } from './select'
export type { SelectProps } from './select';
export { default as Radio } from './radio'
export type { RadioProps } from './radio';
export type { RadioProps, RadioChangeEvent, RadioGroupButtonStyle, RadioChangeEventTarget, RadioGroupContextProps, RadioGroupProps, RadioGroupOptionType } from './radio';
export { default as Checkbox } from './checkbox'
export type { CheckboxProps, CheckboxGroupProps } from './checkbox';
export { default as Input } from './input'
@ -45,3 +48,7 @@ export { default as Modal } from './modal'
export type { ModalFuncProps, ModalProps } from './modal';
export { default as Divider } from './divider'
export type { DividerProps } from './divider';
export { default as Descriptions } from './descriptions'
export type { DescriptionsContextProps, DescriptionsItemType, DescriptionsProps } from './descriptions'
export { default as Flex } from './flex'
export { default as Score } from './score'

View File

@ -4,7 +4,7 @@ import type { RadioProps, RadioRef } from './interface';
import InternalRadio from './radio';
import Button from './radioButton';
export {
export type {
RadioChangeEvent,
RadioChangeEventTarget,
RadioGroupButtonStyle,

View File

@ -0,0 +1,57 @@
//@ts-nocheck
import React, { useMemo } from 'react';
import classNames from 'classnames';
import './index.less';
const componentName = `zhst-image__score`;
export interface ScoreProps {
score: number;
showTitle?: boolean;
r?: number;
fontSize?: number;
borderColor?: string;
borderSize?: number;
waveColor?: string;
}
export const Score: React.FC<ScoreProps> = (props) => {
const {
score,
r = 44,
showTitle = true,
fontSize = 28,
borderSize = 8,
borderColor = 'rgb(0 153 255 / 10%)',
waveColor = 'linear-gradient(180deg, #a0efff 0%, #09f 100%)',
} = props;
const waveHeight = `${score * r * 2}px`;
return useMemo(
() => (
<div className={classNames(`${componentName}`)}>
<div
className={classNames(`${componentName}-box`)}
style={{ border: `${borderSize}px solid ${borderColor}` }}
>
<div
style={{ width: r * 2, height: r * 2 }}
className={classNames(`${componentName}-box-bg`)}
>
<div
className={classNames(`${componentName}-box-bg-inner`)}
style={{ height: waveHeight, background: waveColor }}
/>
</div>
<div
style={{ fontSize }}
className={classNames(`${componentName}-score`)}
>{`${Math.floor(score * 100)}%`}</div>
</div>
{showTitle && <div className={classNames(`${componentName}-text`)}></div>}
</div>
),
[score]
);
};
Score.displayName = componentName;
export default Score;

View File

@ -0,0 +1,48 @@
.zhst-image__score {
display: flex;
flex-direction: column;
align-items: center;
&-box {
position: relative;
display: flex;
box-sizing: border-box;
align-items: center;
justify-content: center;
margin-bottom: 12px;
border-radius: 50%;
&-bg {
display: flex;
overflow: hidden;
box-sizing: border-box;
align-items: flex-end;
justify-content: center;
border: 2px solid #fff;
background-color: #fff;
border-radius: 50%;
&-inner {
width: 100% !important;
height: 0;
}
}
}
&-score {
position: absolute;
top: 50%;
left: 50%;
color: rgb(0 0 0 / 88%);
font-size: 28px;
transform: translate(-50%, -50%);
}
&-text {
width: 54px;
height: 24px;
color: rgb(0 0 0 / 88%);
font-size: 18px;
line-height: 24px;
}
}

View File

@ -0,0 +1,17 @@
---
group: 数据录入
category: Components
subtitle: 分数
title: Score 分数
---
```jsx
import React from 'react'
import { Score } from '@zhst/meta'
export default () => {
return (
<Score score={0.3} />
)
}
```

View File

@ -0,0 +1,3 @@
import Score from './Score'
export default Score

View File

@ -1,9 +1,5 @@
{
"references": [{ "path": "../../tsconfig.json" }],
"compilerOptions": {
"paths": {
"@zhst/meta": ["./src"]
}
},
"exclude": ["src/**/demo"]
}

View File

@ -26,3 +26,6 @@ export enum IBigImageOpt {
ADD_ARCHIVE_WITH_HK, //添加到档案库
ADD_CURRENT_SRARCH, //添加到当前检索(目标检索)
}
export type TAB_TYPE = 'COMPATER' | 'NORMAL' | 'TRACK';
export type MODEL_TYPE = 'VIDEO' | 'IMAGE';