Commit 3310254d authored by 周宏民's avatar 周宏民

feat: 熊猫智慧水务一体化解决方案

parent 4ab564dd
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
......@@ -62,8 +62,10 @@ const BottomItem = props => {
return reArr;
};
useEffect(() => {
const arr = Array(44).fill({});
setListData(spliceArr(arr, 2));
setTimeout(() => {
const arr = Array(44).fill({});
setListData(spliceArr(arr, 2));
}, 1000);
}, []);
return (
<div className={classNames(styles.bottom_item, 'demo_bottom_item')}>
......@@ -103,7 +105,7 @@ const BottomItem = props => {
<div className={styles.center}>
<DataCarousel
gap={1}
autoplay={0}
autoplay={3000}
itemHeight={270}
list={listData}
renderItem={renderCol}
......
......@@ -3,11 +3,11 @@
* @Author: hongmye
* @Date: 2023-12-26 18:34:42
*/
import { FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import React, { useMemo, useEffect, useState, memo } from 'react';
import { schemeData } from '../configData';
import styles from './index.less';
let timer;
const LeftItem = props => {
const { title = '', setSelectKey, selectKey } = props;
......@@ -16,6 +16,18 @@ const LeftItem = props => {
setSelectKey(row.title);
}
};
const onMouseEnter = (item, index) => {
if (timer) {
timer && clearTimeout(timer);
}
timer = setTimeout(() => {
props.onChangeScheme && props.onChangeScheme(item, index);
}, 500);
};
const onMouseLeave = (item, index) => {
timer && clearTimeout(timer);
};
useEffect(() => {}, []);
return (
<div className={styles.left_item}>
......@@ -29,8 +41,9 @@ const LeftItem = props => {
className={styles.l_list_item}
key={item.title}
type={item.title}
selectType={selectKey === item.title ? 'select' : ''}
onClick={() => onSelect(item)}
onMouseEnter={() => onMouseEnter(item, index)}
onMouseLeave={() => onMouseLeave(item, index)}
>
<div className={styles.l_list_item_title}>- {item.title} -</div>
<div className={styles.l_list_item_tip} />
......
......@@ -39,16 +39,16 @@
flex-wrap: wrap;
}
// .l_list_item:hover {
// opacity: 1;
// top: -8px;
.l_list_item:hover {
opacity: 1;
top: -8px;
// }
}
// .l_list_item:hover .l_list_item_tip {
// opacity: 1;
// }
.l_list_item:hover .l_list_item_tip {
opacity: 1;
}
.l_list_item[selectType='select'] {
opacity: 1;
......
......@@ -3,53 +3,109 @@
* @Author: hongmye
* @Date: 2023-12-26 18:34:42
*/
import { FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import React, { useMemo, useEffect, useRef } from 'react';
import { cloneDeep, debounce } from 'lodash';
import React, { useMemo, useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react';
import classNames from 'classnames';
import SwiperCore, { Autoplay, Mousewheel, Navigation, Pagination, EffectCoverflow } from 'swiper/core';
import { Swiper, SwiperSlide } from 'swiper/react';
import leftIcon from '@/assets/demonstration/arrow_left.png';
import rightIcon from '@/assets/demonstration/arrow_right.png';
import { schemeData } from '../configData';
import 'swiper/components/navigation/navigation.min.css';
import 'swiper/components/pagination/pagination.min.css';
import 'swiper/components/effect-coverflow/effect-coverflow.min.css';
import 'swiper/swiper.min.css';
import styles from './index.less';
const boxWidth = 982;
const boxHeight = 455;
const autoplay = 0;
SwiperCore.use([Autoplay, Pagination, Navigation, Mousewheel, EffectCoverflow]);
const VideoItem = (props, ref) => {
const { selectKey = '' } = props;
const swiperRef = useRef(null);
const onSlideToLoop = index => {
if (swiperRef.current) {
swiperRef.current.slideToLoop(index);
}
};
useImperativeHandle(ref, () => ({
onSlideToLoop,
}));
const VideoItem = props => {
const { selectKey = '', info = {} } = props;
const contentRef = useRef(null);
const onResize = () => {
if (contentRef?.current) {
const { clientWidth, clientHeight } = contentRef.current;
const listData = schemeData.filter(i => !!i.video);
if (!boxWidth || !boxHeight) return;
const xScale = clientWidth / boxWidth;
const yScale = clientHeight / boxHeight;
const scale = Math.min(xScale, yScale);
const n = scale.toFixed(4);
const renderItem = (row, index) => (
<div className={styles.video_box} key={row.title}>
<div className={styles.video_tip} type={row.title}>
<span />
{row.title}
</div>
<div className={styles.video_wrap}>
<video autoPlay="autoPlay" muted controls src={row.video} loop />
</div>
</div>
);
const onSwiper = type => {
if (swiperRef.current) {
if (type === 'left') {
swiperRef.current.slidePrev();
}
if (type === 'right') {
swiperRef.current.slideNext();
}
}
};
useEffect(() => {
window.addEventListener('resize', debounce(onResize, 300));
return () => {
window.removeEventListener('resize', onResize);
};
}, []);
const onSlideChange = e => {
if (e.$el[0]) {
const videoDom = e.$el[0].querySelector('video');
videoDom.play && videoDom.play();
}
};
useEffect(() => {}, []);
return (
<div className={styles.video_item}>
<div className={styles.video_box} ref={contentRef}>
<div className={styles.video_tip} type={selectKey}>
<span />
{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 className={classNames(styles.video_list, 'dt_video_list')}>
<Swiper
slidesPerView="auto"
autoplay={{
delay: autoplay,
disableOnInteraction: false,
}}
loop
height={450}
direction="horizontal"
onSlideChange={onSlideChange}
effect="coverflow"
coverflowEffect={{
rotate: 50,
stretch: 10,
depth: 60,
modifier: 2,
slideShadows: false,
}}
mousewheel
onSwiper={swiper => {
swiperRef.current = swiper;
// 鼠标悬浮暂停效果
swiper.$el[0].addEventListener('mouseover', () => swiper.autoplay.stop());
// 鼠标移开后继续自动滚屏效果
swiper.$el[0].addEventListener('mouseleave', () => {
listData.length > 1 && autoplay * 1 ? swiper.autoplay.start() : '';
});
}}
>
{listData.map((item, index) => (
<SwiperSlide key={index} virtualIndex={index} onClick={() => {}}>
{renderItem(item, index + 1)}
</SwiperSlide>
))}
</Swiper>
<div className={classNames(styles.swiper_btn, styles.swiper_left)} onClick={() => onSwiper('left')}>
<img src={leftIcon} alt="" />
</div>
<div className={classNames(styles.swiper_btn, styles.swiper_right)} onClick={() => onSwiper('right')}>
<img src={rightIcon} alt="" />
</div>
</div>
);
};
export default VideoItem;
export default forwardRef(VideoItem);
@imgSrc: '@/assets/demonstration';
.video_item {
.video_list {
width: 100%;
padding: 0 30px;
height: calc(100% - 25px);
margin-top: 25px;
background: url('@{imgSrc}/视频bg2.png') no-repeat center center;
background-size: calc(100% - 30px) auto;
position: relative;
.swiper_btn {
position: absolute;
width: 36px;
height: 40px;
cursor: pointer;
z-index: 100;
img {
width: 100%;
}
}
.swiper_btn:active {
opacity: 0.8;
}
.swiper_left {
left: 20px;
top: 50%;
transform: translateY(-50%);
}
.swiper_right {
right: 20px;
top: 50%;
transform: translateY(-50%);
}
.video_box {
width: 100%;
......@@ -33,8 +64,10 @@
padding: 10px;
video {
object-fit: fill;
width: 100%;
height: 100%;
border-radius: 10px;
}
}
......@@ -77,4 +110,18 @@
background-size: 100% 100%;
}
}
:global {
.dt_video_list {
.swiper-slide {
width: 100%;
}
.swiper-container {
width: 1100px;
height: 100%;
}
}
}
\ No newline at end of file
......@@ -4,26 +4,34 @@
* @Author: hongmye
* @Date: 2024-01-30 15:29:09
*/
import gongshuiVideo from '@/assets/videos/供水.mp4';
import shuiliVideo from '@/assets/videos/水利.mp4';
import paishuiVideo from '@/assets/videos/排水.mp4';
import jieshuiVideo from '@/assets/videos/节水.mp4';
const schemeData = [
{
title: '供水产品',
background: '',
url: '',
video: gongshuiVideo,
},
{
title: '水利产品',
background: '',
url: '',
video: shuiliVideo,
},
{
title: '排水产品',
background: '',
url: '',
video: paishuiVideo,
},
{
title: '节水产品',
background: '',
url: '',
video: jieshuiVideo,
},
];
const productData = [
......
......@@ -21,9 +21,10 @@ import { platformData } from './components/configData';
const boxWidth = 1920;
const boxHeight = 911;
const Demonstration = props => {
const onLineUrl = window.globalConfig?.mainserver || 'https://panda-water.cn/';
const showFullScreen = true;
const videoRef = useRef(null);
const [selectKey, setSelectKey] = useState('供水产品');
const [scale, setScaley] = useState(1);
const [boxSize, setBoxSize] = useState({
scale: 1,
boxHeight: 911,
......@@ -38,6 +39,13 @@ const Demonstration = props => {
handleFullScreen && handleFullScreen();
}
};
// 切换方案视频
const onChangeScheme = (item, index) => {
if (videoRef.current) {
videoRef.current.onSlideToLoop(index);
}
};
const renderCenter = useMemo(
() =>
platformData.map(col => {
......@@ -123,10 +131,10 @@ const Demonstration = props => {
<div className={styles.row}>
<div className={styles.row_l}>
<LeftItem setSelectKey={setSelectKey} selectKey={selectKey} />
<LeftItem setSelectKey={setSelectKey} selectKey={selectKey} onChangeScheme={onChangeScheme} />
</div>
<div className={styles.row_c}>
<VideoItem selectKey={selectKey} setSelectKey={setSelectKey} />
<VideoItem ref={videoRef} selectKey={selectKey} setSelectKey={setSelectKey} onLineUrl={onLineUrl} />
</div>
<div className={styles.row_r}>
<RightItem />
......
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