Commit 4ab564dd authored by 周宏民's avatar 周宏民

pref: 演示入口功能

parent e50de4a8
......@@ -4,26 +4,69 @@
* @Date: 2023-12-26 18:34:42
*/
import { FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import React, { useMemo, useEffect } from 'react';
import { Button, Image } from 'antd';
import React, { useMemo, useEffect, useState } from 'react';
import classNames from 'classnames';
import DataCarousel from '../DataCarousel';
import styles from './index.less';
const BottomItem = props => {
const { title = '' } = props;
const { title = '', list = [] } = props;
const [listData, setListData] = useState([]);
const renderNum = (num, type) => {
const numStr = num ? num.toString() : '0';
const arr = numStr.split('');
console.log('🚀 ~ arr:', arr);
return arr.map(a => (
<div className={styles.l_item_num_item} type={type}>
{a}
</div>
));
};
useEffect(() => {}, []);
const renderCol = (row, rindex) => {
if (!Array.isArray(row)) return null;
return (
<div className={styles.list_item_col} key={rindex}>
{row.map((col, cIndex) => (
<div key={`${rindex}-${cIndex}`} className={styles.list_item}>
<div className={styles.list_item_img_wrap}>
<div className={styles.list_item_img}>
<Image />
</div>
<div className={styles.list_item_img_tip} />
</div>
<div className={styles.list_item_info_wrap}>
<div className={styles.list_item_info_tip} type="节水">
节水
</div>
<div className={styles.list_item_info_name}>崇左市自来水厂崇左市自来水厂</div>
<div className={styles.list_item_info_address}>广西</div>
</div>
</div>
))}
</div>
);
};
const spliceArr = (arr, num) => {
const reArr = [];
arr.map(item => {
if (!reArr[reArr.length - 1] || reArr[reArr.length - 1].length === num) {
// 新行添加
reArr.push([]);
}
if (reArr[reArr.length - 1].length !== num) {
// 长度不够则直接添加
reArr[reArr.length - 1].push(item);
}
return null;
});
return reArr;
};
useEffect(() => {
const arr = Array(44).fill({});
setListData(spliceArr(arr, 2));
}, []);
return (
<div className={styles.bottom_item}>
<div className={classNames(styles.bottom_item, 'demo_bottom_item')}>
<div className={styles.left}>
<div className={styles.l_title_wrap}>
<div className={styles.l_title_sub}>熊猫智慧水务</div>
......@@ -58,7 +101,17 @@ const BottomItem = props => {
</div>
</div>
<div className={styles.center}>
<div />
<DataCarousel
gap={1}
autoplay={0}
itemHeight={270}
list={listData}
renderItem={renderCol}
config={{
direction: 'horizontal',
width: 212,
}}
/>
</div>
<div className={styles.right}>查看全部</div>
</div>
......
......@@ -6,6 +6,8 @@
height: 100%;
overflow: hidden;
padding: 0 28px 10px;
background: url('@{imgSrc}/bottom_bg.png') no-repeat left top;
background-size: calc(100% - 62px) 42px;
.left {
flex: none;
......@@ -125,6 +127,85 @@
flex: 1;
height: 100%;
overflow: hidden;
padding: 12px 0 0 13px;
}
.list_item {
width: 204px;
height: 130px;
border: 1px solid rgba(71, 88, 114, 0.8);
border-radius: 10px;
overflow: hidden;
margin-right: 8px;
margin-bottom: 8px;
.list_item_img_wrap {
width: 100%;
height: 100px;
background: #2474B8;
position: relative;
.list_item_img_tip {
position: absolute;
right: 0;
top: 0;
width: 57px;
height: 19px;
background: url('@{imgSrc}/案例.png') no-repeat center/100% 100%;
}
}
.list_item_info_wrap {
display: flex;
width: 100%;
overflow: hidden;
align-items: center;
padding: 3px 8px 0;
font-size: 12px;
font-weight: 400;
.list_item_info_tip {
flex: none;
width: 38px;
height: 20px;
text-align: center;
line-height: 20px;
margin-right: 5px;
background: url('@{imgSrc}/供水.png') no-repeat center/100% 100%;
}
.list_item_info_tip[type='农水'] {
background: url('@{imgSrc}/农水.png') no-repeat center/100% 100%;
}
.list_item_info_tip[type='节水'] {
background: url('@{imgSrc}/节水.png') no-repeat center/100% 100%;
}
.list_item_info_tip[type='排水'] {
background: url('@{imgSrc}/排水.png') no-repeat center/100% 100%;
}
.list_item_info_name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.list_item_info_address {
flex: none;
font-size: 12px;
font-weight: 400;
color: #ACCDF0;
line-height: 1;
padding-left: 4px;
border-left: 1px solid rgba(216, 234, 253, 0.4);
}
}
}
.right {
......@@ -142,4 +223,16 @@
letter-spacing: 2px;
cursor: pointer;
}
}
:global {
.demo_bottom_item {
.swiper-wrapper {
display: flex;
.swiper-slide {
width: 212px;
}
}
}
}
\ No newline at end of file
/*
* @Title:数据列表轮播组件
* @Author: hongmye
* @Date: 2023-02-08 16:03:42
*/
import PandaEmpty from '@wisdom-components/empty';
import classNames from 'classnames';
import React, { useEffect, useRef, useState } from 'react';
import 'swiper/components/navigation/navigation.min.css';
import 'swiper/components/pagination/pagination.min.css';
import SwiperCore, { Autoplay, Mousewheel, Navigation, Pagination } from 'swiper/core';
import { Swiper, SwiperSlide } from 'swiper/react';
import 'swiper/swiper.min.css';
import styles from './index.less';
SwiperCore.use([Autoplay, Pagination, Navigation, Mousewheel]);
const DataCarousel = ({ list, itemHeight, renderItem, config, autoplay, onSwiper, showEmpty = true }) => {
const autoplayConfig = {
delay: autoplay,
disableOnInteraction: false,
};
const contentRef = useRef(null);
const swiperRef = useRef(null);
const [listData, setListData] = useState([]);
useEffect(() => {
setListData(list);
}, [list]);
return (
<div
className={classNames(styles.dataCarousel, 'dataCarousel')}
style={{ width: '100%', height: '100%' }}
ref={contentRef}
>
<div className={classNames(styles.dataCarouselSwiper)} style={{ width: '100%', height: '100%' }}>
{listData && listData.length ? (
<Swiper
slidesPerView="auto"
autoplay={autoplay * 1 && listData.length > 1 ? autoplayConfig : false}
loop
height={itemHeight}
direction="vertical"
onSlideChange={e => {}}
mousewheel
onSwiper={swiper => {
swiperRef.current = swiper;
onSwiper && onSwiper(swiper);
// 鼠标悬浮暂停效果
swiper.$el[0].addEventListener('mouseover', () => swiper.autoplay.stop());
// 鼠标移开后继续自动滚屏效果
swiper.$el[0].addEventListener('mouseleave', () => {
listData.length > 1 && autoplay * 1 ? swiper.autoplay.start() : '';
});
}}
{...config}
>
{listData.map((item, index) => (
<SwiperSlide key={index} virtualIndex={index} onClick={() => {}}>
{renderItem(item, index + 1)}
</SwiperSlide>
))}
</Swiper>
) : showEmpty ? (
<div style={{ paddingTop: 10 }}>
<PandaEmpty />
</div>
) : null}
</div>
</div>
);
};
export default DataCarousel;
@root-entry-name: 'default';
@import '~antd/es/style/themes/index.less';
.dataCarousel {
width: 100%;
height: 100%;
overflow-y: auto;
.dataCarouselSwiper {
overflow-y: auto;
}
}
.dataCarousel {
:global {
.swiper-container {
width: 100%;
height: 100%;
}
}
}
......@@ -40,7 +40,14 @@ const VideoItem = props => {
<span />
{selectKey}
</div>
<div className={styles.video_wrap}>{selectKey}</div>
<div className={styles.video_wrap}>
<video
autoPlay="autoPlay"
muted
controls
src="http://vfx.mtime.cn/Video/2021/07/10/mp4/210710122716702150.mp4"
/>
</div>
</div>
</div>
);
......
......@@ -10,7 +10,7 @@
.video_box {
width: 100%;
height: 100%;
height: 450px;
padding: 0 28px 20px;
background: url('@{imgSrc}/视频bg.png') no-repeat center center;
background-size: calc(100% - 56px) 100%;
......@@ -18,11 +18,24 @@
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
}
.video_wrap {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
border-radius: 10px;
padding: 10px;
video {
width: 100%;
height: 100%;
}
}
.video_tip {
......@@ -35,6 +48,7 @@
position: absolute;
left: 28px;
top: 0;
z-index: 12;
span {
......
/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable global-require */
/*
* @Title:
......@@ -8,7 +9,8 @@ import { FullscreenExitOutlined, FullscreenOutlined, RightOutlined } from '@ant-
import exitImg from '@/assets/demonstration/退出.png';
import enterImg from '@/assets/demonstration/进入.png';
import { Button } from 'antd';
import React, { useMemo, useState, useEffect } from 'react';
import React, { useMemo, useState, useEffect, useRef } from 'react';
import { cloneDeep, debounce } from 'lodash';
import useFullScreen from './components/useFullScreen';
import styles from './index.less';
import LeftItem from './components/Left';
......@@ -16,9 +18,16 @@ import VideoItem from './components/VideoItem';
import RightItem from './components/Right';
import BottomItem from './components/Bottom';
import { platformData } from './components/configData';
const boxWidth = 1920;
const boxHeight = 911;
const Demonstration = props => {
const showFullScreen = false;
const showFullScreen = true;
const [selectKey, setSelectKey] = useState('供水产品');
const [scale, setScaley] = useState(1);
const [boxSize, setBoxSize] = useState({
scale: 1,
boxHeight: 911,
});
const [pattern, setPattern] = useState(false);
const [ref, isFullscreen, handleFullScreen, handleExitFullScreen] = useFullScreen(false);
// 退出
......@@ -49,7 +58,32 @@ const Demonstration = props => {
}),
[],
);
useEffect(() => {}, []);
const onResize = () => {
if (ref?.current) {
const { clientWidth, clientHeight } = ref.current;
if (!boxWidth || !boxHeight) return;
const xScale = clientWidth / boxWidth;
const yScale = clientHeight / boxHeight;
const poor = clientHeight / clientWidth - boxHeight / boxWidth;
let n = Math.min(xScale, yScale);
let bHeight = boxHeight;
if (poor > 0.05) {
bHeight = boxHeight + 30;
}
n = Number(n.toFixed(4));
setBoxSize({
scale: n,
boxHeight: bHeight,
});
}
};
useEffect(() => {
window.addEventListener('resize', debounce(onResize, 300));
onResize();
return () => {
window.removeEventListener('resize', onResize);
};
}, []);
return (
<div className={styles.demonstration} ref={ref}>
{showFullScreen ? (
......@@ -59,44 +93,53 @@ const Demonstration = props => {
</Button>
</div>
) : null}
<div className={styles.top}>
<div className={styles.top_l}>
{pattern ? (
<div className={styles.top_l_btn}>
<img src={exitImg} alt="" /> 退出演示模式 <RightOutlined />
</div>
) : (
<div className={styles.top_l_btn}>
<img src={enterImg} alt="" /> 进入演示模式 <RightOutlined />
</div>
)}
</div>
<div className={styles.top_c}>
<div className={styles.top_c_title}>熊猫智慧水务一体化解决方案</div>
</div>
<div className={styles.top_r}>
<div className={styles.top_r_text}>- 引领中国智慧水务 -</div>
<div
className={styles.demonstrationWrap}
style={{
width: boxWidth,
height: boxSize.boxHeight,
transform: `scale(${boxSize.scale}) translate(-50%,-50%)`,
}}
>
<div className={styles.top}>
<div className={styles.top_l}>
{pattern ? (
<div className={styles.top_l_btn}>
<img src={exitImg} alt="" /> 退出演示模式 <RightOutlined />
</div>
) : (
<div className={styles.top_l_btn}>
<img src={enterImg} alt="" /> 进入演示模式 <RightOutlined />
</div>
)}
</div>
<div className={styles.top_c}>
<div className={styles.top_c_title}>熊猫智慧水务一体化解决方案</div>
</div>
<div className={styles.top_r}>
<div className={styles.top_r_text}>- 引领中国智慧水务 -</div>
</div>
</div>
</div>
<div className={styles.row}>
<div className={styles.row_l}>
<LeftItem setSelectKey={setSelectKey} selectKey={selectKey} />
<div className={styles.row}>
<div className={styles.row_l}>
<LeftItem setSelectKey={setSelectKey} selectKey={selectKey} />
</div>
<div className={styles.row_c}>
<VideoItem selectKey={selectKey} setSelectKey={setSelectKey} />
</div>
<div className={styles.row_r}>
<RightItem />
</div>
</div>
<div className={styles.row_c}>
<VideoItem selectKey={selectKey} setSelectKey={setSelectKey} />
<div className={styles.center_wrap}>
<div className={styles.center_tip} />
<div className={styles.center}>{renderCenter}</div>
</div>
<div className={styles.row_r}>
<RightItem />
<div className={styles.bottom}>
<BottomItem />
</div>
</div>
<div className={styles.center_wrap}>
<div className={styles.center_tip} />
<div className={styles.center}>{renderCenter}</div>
</div>
<div className={styles.bottom}>
<BottomItem />
</div>
</div>
);
};
......
......@@ -5,7 +5,6 @@
width: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
background: url('@{imgSrc}/背景.png') no-repeat center center;
background-size: 100% 100%;
position: relative;
......@@ -13,13 +12,29 @@
font-family: Microsoft YaHei;
font-weight: 400;
color: #FFFFFF;
align-items: center;
justify-content: center;
.demonstrationWrap {
height: 100%;
width: 100%;
overflow: hidden;
transform-origin: left top;
position: absolute;
left: 50%;
top: 50%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.CV_exit {
cursor: pointer;
position: absolute;
right: 0px;
top: 0px;
right: 0;
top: 0;
z-index: 10;
}
.top {
......@@ -205,8 +220,10 @@
background: url('@{imgSrc}/水务AI平台.png') no-repeat center/100% 100%;
}
}
.bottom{
flex: 1;
.bottom {
flex: none;
height: 290px;
overflow: hidden;
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment