24 Commits

Author SHA1 Message Date
bace9fa501 Merge pull request 'zjl' (#1) from zjl into features/warning
Reviewed-on: #1
2024-07-12 15:11:34 +08:00
c6cd097433 1优化 2024-07-12 14:52:07 +08:00
4d7af62305 窑炉优化 2024-07-12 14:12:10 +08:00
214e9fe892 底&顶ok 2024-07-10 15:39:02 +08:00
9968280724 7.9 2024-07-09 14:50:29 +08:00
lb
8b4322996e update 注释 2024-04-29 13:28:08 +08:00
lb
b325c3fc05 update 报警大小 2024-04-28 13:55:59 +08:00
lb
28c9c1906e update 烟气处理 2024-04-25 11:04:52 +08:00
lb
7ddae1b3a4 update videos 2024-04-25 10:01:25 +08:00
lb
61477cdd30 Merge branch 'features/warning' of http://git.picaiba.com/mt-fe-group/xuchang-new into features/warning 2024-04-25 09:44:40 +08:00
lb
6e5badf01a add video 2024-04-25 09:44:36 +08:00
gtz
311cdfc5f7 1' 2024-04-24 17:02:20 +08:00
lb
bc8b68e449 1 2024-04-24 16:58:38 +08:00
lb
024f4bcf14 1 2024-04-23 15:27:54 +08:00
lb
361aedd4ad done alarm 2024-04-23 15:26:55 +08:00
lb
60c6fdda79 1 2024-04-23 11:24:31 +08:00
lb
15708c0eef update 2024-04-23 09:33:41 +08:00
lb
2996c061dc merge bugfix 2024-04-22 16:58:15 +08:00
lb
9894aeca50 update WarnAlert 2024-04-19 17:03:43 +08:00
lb
9f7652d9f3 update ts->js 2024-04-19 16:55:10 +08:00
lb
e854b966dc add fake websocket server 2024-04-19 16:38:41 +08:00
lb
dff017a5a2 update 2024-04-19 16:11:10 +08:00
lb
e796a07e66 update Home Element Position 2024-04-16 10:28:14 +08:00
lb
43635ff398 add warn-alert 2024-04-15 16:18:21 +08:00
162 changed files with 4105 additions and 1017 deletions

2
.gitignore vendored
View File

@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
**/node_modules
/.pnp
.pnp.js

View File

@@ -70,7 +70,9 @@
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
"server": "node websocket/server.js",
"test": "node scripts/test.js",
"ws": "node websocket/server.js"
},
"eslintConfig": {
"extends": [

View File

@@ -29,6 +29,8 @@
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!-- <div id="alarm-list-container"></div> -->
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.

Binary file not shown.

Binary file not shown.

View File

@@ -10,8 +10,8 @@ import RulerContainer from "./components/Tools/Ruler";
import { Switch } from "antd";
import { createPortal } from "react-dom";
const Menus = ["窑炉总览", "窑炉内部", "退火监测", "质检统计", "能耗分析"];
const Menus = ["窑炉总览", "窑炉内部", "窑炉优化","退火监测", "质检统计", "能耗分析"];
const LUNBO_INTERVAL = 60 * 1000;
function App() {
const { styles, value, setValue } = useSlider(100);
const [navActive, setNavActive] = useState("窑炉总览");
@@ -22,7 +22,7 @@ function App() {
if (lunbo) {
timer = setInterval(() => {
handleMenuChange(Menus[(Menus.indexOf(navActive) + 1) % Menus.length]);
}, 5000);
}, LUNBO_INTERVAL);
}
return () => {
clearInterval(timer);

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
src/assets/Icon/kilnTop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
src/assets/kilnSpeed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
src/assets/tempIntr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
src/assets/warn-bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/warn-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -109,6 +109,7 @@ function WindFrequence(props) {
},
};
} else {
console.log('runstate changeD!......')
dataList =
runState != null
? Object.keys(runState).map((fan) => ({

View File

@@ -57,7 +57,7 @@ function WindFrequence(props) {
currentTempList[1 + lines.indexOf(dataSource) + "#"]) ||
[]
);
}, [dataSource]);
}, [dataSource, currentTempList]);
return (
<GraphBase

View File

@@ -35,10 +35,10 @@ const EnergyCostRealtime = () => {
paddingRight: "6px",
}}
>
余热发电(实时)
余热发电(昨日)
</i>
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}kWh
{(+energyInfo?.elecQty1)?.toFixed(2) || 0}kWh
</span>
</div>
@@ -66,7 +66,7 @@ const EnergyCostRealtime = () => {
paddingRight: "6px",
}}
>
水耗量
水耗量(昨日)
</i>
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
{(+energyInfo?.waterQty)?.toFixed(2) || 0}Km³
@@ -80,7 +80,7 @@ const EnergyCostRealtime = () => {
paddingRight: "6px",
}}
>
天然气I
天然气I(累计)
</i>
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
{energyInfo?.ngQty1 || "0Nm³"}
@@ -94,7 +94,7 @@ const EnergyCostRealtime = () => {
paddingRight: "6px",
}}
>
电耗量
电耗量(昨日)
</i>
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}kWh
@@ -108,7 +108,7 @@ const EnergyCostRealtime = () => {
paddingRight: "6px",
}}
>
天然气II
天然气II(累计)
</i>
<span style={{ fontSize: "17px", color: "#3ce8ff" }}>
{energyInfo?.ngQty2 || "0Nm³"}

View File

@@ -44,6 +44,7 @@ function GraphBase(props) {
selectWidth,
legend,
} = props;
const descSmall = props.descSmall || false;
const iconSrc = useIcon(icon);
const colors = useMemo(() => ["#ffd160", "#2760ff", "#15e8f5"], []);
const [showChart, setShowChart] = useState(true);
@@ -72,9 +73,9 @@ function GraphBase(props) {
<span
style={{
color: "#fff",
fontSize: "14px",
fontSize: "calc(14px * var(--scale))",
lineHeight: 1,
paddingLeft: "12px",
paddingLeft: "calc(12px * var(--scale))",
}}
>
- -
@@ -105,7 +106,7 @@ function GraphBase(props) {
<div className={cls.graphBaseTitle}>
<img src={iconSrc} alt="#" />
<h2>{title}</h2>
{desc && <div className={cls.graphBaseDesc}>{desc}</div>}
{desc && <div className={`${cls.graphBaseDesc} ${descSmall ? cls.graphBaseDescSmall : ''}`}>{desc}</div>}
</div>
<div className={cls.graphBaseContent}>
{switchOptions && (

View File

@@ -93,6 +93,11 @@
color: #76fff9;
}
.graphBaseDescSmall {
font-size: 16px;
color: #76fff9;
}
.graphBaseSwitch {
position: absolute;
top: 30px;

View File

@@ -9,6 +9,7 @@
.xc-date-selector-menu .ant-select-item-option-content {
text-align: center;
font-size: calc(14px * var(--scale));
}
.xc-date-selector-menu .ant-select-item-option-selected {
@@ -20,10 +21,16 @@
background-color: #02457E !important;
color: #fff !important;
}
.xc-date-selector-menu .ant-select-item-option {
/* padding: 5px 8px; */
padding: .3em .35em;
min-height: unset;
}
/*
.ant-select-selector::after {
content: '\25BC' !important;
visibility: visible !important;
visibility: visible !important; L
position: absolute;
top: 2px;
right: 22px;

View File

@@ -1,5 +1,4 @@
import * as echarts from "echarts";
import { randomInt } from "../../../../utils";
export default function getOptions(seriesData, name) {
const colors = [

View File

@@ -5,8 +5,9 @@ export default function CenterMenu({ active, onChangeActive }) {
const menuList = [
["窑炉总览", "/kilnSummary"],
["窑炉内部", "/kilnInner"],
["窑炉优化", "/kilnOptimize"],
["退火监测", "/stopFire"],
["质检统计", "/quailtyCheck"],
["质检统计", "/quailtyCheck"],
["能耗分析", "/energyCost"],
];
return (

View File

@@ -2,7 +2,7 @@
position: fixed;
top: 120px;
// left: 1340px;
left: 1460px;
left: 1338px;
color: white;
z-index: 10000;
}

View File

@@ -11,10 +11,10 @@ const SmokeHandleTable = () => {
<div className={cls.info__item}>
氮氧化物浓度: {(+smokeInfo?.NOX_float)?.toFixed(2) || 0}mg/
</div>
<div className={cls.info__item}>
<div className={cls.info__item} style={{ gridColumn: "span 2" }}>
二氧化硫浓度: {(+smokeInfo?.SO2_float)?.toFixed(2) || 0}mg/
</div>
<div className={cls.info__item}>
<div className={cls.info__item + " " + cls.disabled}>
颗粒物浓度: {(+smokeInfo?.dust_float)?.toFixed(2) || 0}mg/
</div>
</div>

View File

@@ -33,9 +33,9 @@ const SmokeTrendChart = (props) => {
switch (period) {
case "day":
setDesc(
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().format("YYYY.MM.DD") +
dayjs().add(1, "day").format("YYYY.MM.DD") +
" 7点"
);
break;

View File

@@ -1,29 +1,36 @@
.smokeHandle {
// background: #b730305c;
background: url(../../../assets/smoke.png) no-repeat;
background-size: 100% 100%;
width: 626px;
height: 490px;
.smokeHandle__content {
margin-top: 8px;
}
// background: #b730305c;
background: url(../../../assets/smoke.png) no-repeat;
background-size: 100% 100%;
width: 626px;
height: 490px;
.smokeHandle__content {
margin-top: 8px;
}
}
.info__item {
border-radius: 2px;
color: hsl(0, 0%, 100%, 0.9);
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
height: 32px;
font-size: 16px;
letter-spacing: 1.43px;
line-height: 32px;
text-align: center;
user-select: none;
border-radius: 2px;
color: hsl(0, 0%, 100%, 0.9);
box-shadow: inset 0 0 17px 0px hsla(0, 0%, 100%, 0.15);
height: 32px;
font-size: 16px;
letter-spacing: 1.43px;
line-height: 32px;
text-align: center;
user-select: none;
}
.info__item_groups {
margin-bottom: 12px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4px;
margin-bottom: 12px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 4px;
}
.disabled {
display: none;
pointer-events: none;
opacity: 0.5;
color: transparent;
}

View File

@@ -1,18 +1,30 @@
import BlueRect from "../BlueRect";
import { useSelector } from "react-redux";
import { motion, AnimatePresence } from "framer-motion";
import { useEffect, useState } from "react";
const blueTe = [
"TE401",
"TE402",
"TE403",
"PE401",
"PE402",
"PE403",
];
const blueTe = ["TE401", "TE402", "TE403", "PE401", "PE402", "PE403"];
function TemperatureBottom(props) {
const tempBottom = useSelector((state) => state.temperature.bottom);
const speed = props.speed;
const floor = props.floor;
const [speedAn, setSpeedAn] = useState({});
useEffect(() => {
// 23互切不用展示动画
if (speed === "f") {
setSpeedAn({});
} else {
if (floor === 2) {
setSpeedAn({
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 1.8 },
});
} else {
setSpeedAn({});
}
}
}, [floor]);
return (
<motion.div
@@ -24,15 +36,17 @@ function TemperatureBottom(props) {
width: "100%",
height: "80vh",
zIndex: "-1",
...props.style
}}
animate={{
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 2 },
...props.style,
}}
animate={speedAn}
>
{Object.keys(tempBottom).map((d) => (
<BlueRect title={d} key={d + Math.random()} value={tempBottom[d]} blue={blueTe.includes(d)} />
<BlueRect
title={d}
key={d + Math.random()}
value={tempBottom[d]}
blue={blueTe.includes(d)}
/>
))}
</motion.div>
);

View File

@@ -28,15 +28,20 @@ function TemperatureTop(props) {
width: "100%",
height: "80vh",
zIndex: "-1",
...props.style
...props.style,
}}
animate={{
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 2 },
transition: { duration: 0.3, delay: 1.5 },
}}
>
{Object.keys(tempTop).map((d) => (
<BlueRect title={d} key={d + Math.random()} value={tempTop[d]} blue={blueTe.includes(d)} />
<BlueRect
title={d}
key={d + Math.random()}
value={tempTop[d]}
blue={blueTe.includes(d)}
/>
))}
</motion.div>
);

View File

@@ -33,10 +33,9 @@ function FaultTotal(props) {
// time hint
let timeDesc = "";
const now = new Date();
switch (currentSelect) {
case "日":
timeDesc = dayjs().subtract(1, 'day').format('YYYY.MM.DD') + " 7点 - " + dayjs().format('YYYY.MM.DD') + " 7点";
timeDesc = dayjs().format('YYYY.MM.DD') + " 7点 - " + dayjs().add(1, 'day').format('YYYY.MM.DD') + " 7点";
break;
case "周":
timeDesc = dayjs().subtract(7, 'day').format('YYYY.MM.DD') + " - " + dayjs().subtract(1, 'day').format('YYYY.MM.DD') ;
@@ -52,7 +51,6 @@ function FaultTotal(props) {
<GraphBase
icon="chart"
title="产线缺陷统计"
dateOptions={["日", "周", "月", "年"]}
defaultSelect={currentSelect}
onDateChange={handleDateChange}
size={bgSize}

View File

@@ -3,8 +3,8 @@ import GraphBase from "../GraphBase";
import ReactECharts from "echarts-for-react";
import { useSelector } from "react-redux";
import { useEffect, useState } from "react";
import { randomInt } from "../../../utils";
import * as echarts from "echarts";
import dayjs from "dayjs";
function FaultType(props) {
const [init, setInit] = useState(true);
@@ -17,6 +17,11 @@ function FaultType(props) {
: [];
const lines = currentStatistic.map((item) => item.name);
const CHART_TYPE = "line"; // "pie" | "line";
const timestr =
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().add(1, "d").format("YYYY.MM.DD") +
" 7点";
useEffect(() => {
if (init == false) return;
@@ -47,6 +52,8 @@ function FaultType(props) {
<GraphBase
icon="default"
title="产线当日缺陷分类"
desc={timestr}
descSmall={true}
dateOptions={[...lines]}
defaultSelect={currentLine}
onDateChange={handleLineChange}
@@ -146,7 +153,7 @@ function getOptions(data, chart_type) {
axisPointer: {
type: "shadow",
},
symbol: 'rect',
symbol: "rect",
className: "xc-chart-tooltip",
// backgroundColor: ''
},
@@ -210,7 +217,9 @@ function getOptions(data, chart_type) {
color: "#fffc",
},
data: (dataList || []).map((item) =>
item.value == null || isNaN(+item.value) ? null : (+item.value).toFixed(0)
item.value == null || isNaN(+item.value)
? null
: (+item.value).toFixed(0)
),
},
],

View File

@@ -29,9 +29,9 @@ const GoodRateChart = (props) => {
}
const [timestr, setTimestr] = useState(
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().format("YYYY.MM.DD") +
dayjs().add(1, "day").format("YYYY.MM.DD") +
" 7点"
);
function handleDateChange(value) {
@@ -40,9 +40,9 @@ const GoodRateChart = (props) => {
switch (value) {
case "日":
setTimestr(
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().format("YYYY.MM.DD") +
dayjs().add(1, "day").format("YYYY.MM.DD") +
" 7点"
);
break;

View File

@@ -0,0 +1,40 @@
// import cls from "./index.module.css";
import "./video-monitor.css";
function VideoMonitor(props) {
return (
<div className="video-monitor">
<h2>泡界线监控</h2>
<div className="video-container">
<div>
{/* <video muted autoPlay loop src="https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"></video> */}
<img
style={{
width: "100%",
height: "100%",
display: "block",
margin: "auto",
backgrounColor: "hsl(0, 0%, 25%)",
}}
src="http://10.70.180.10:8001/video_feed"
></img>
</div>
<div>
{/* <video muted autoPlay loop src="https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4"></video> */}
<img
style={{
width: "100%",
height: "100%",
display: "block",
margin: "auto",
backgrounColor: "hsl(0, 0%, 25%)",
}}
src="http://10.70.180.10:8000/video_feed"
></img>
</div>
</div>
</div>
);
}
export default VideoMonitor;

View File

@@ -0,0 +1,35 @@
.video-monitor {
display: flex;
flex-direction: column;
margin-left: 80px;
height: 200px;
width: 500px;
}
.video-monitor > h2 {
margin: 0;
padding: 10px 0;
background: #16253c;
color: #fff;
font-weight: 400;
letter-spacing: 2px;
font-size: 18px;
text-align: center;
}
.video-monitor > .video-container {
display: flex;
gap: 8px;
flex: 1;
max-height: 150px;
}
.video-container > div {
flex: 1;
height: 100%;
background: #ccc1;
}
.video-container > div > video {
width: 100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,130 @@
import WarnAlert from ".";
import { useSelector } from "react-redux";
import posMap from "./position.json";
const total = `AN_1_1,助燃风故障报警
AN_1_2,压延机冷却风故障报警
AN_1_3,L吊墙冷却风机故障报警
AN_1_4,熔化带及部分澄清部冷却风机故障报警
AN_2_1,澄清带池壁冷却风机故障报警
AN_2_2,钢碴碴冷却风机故障报警
AN_2_3,支通路拐角冷却风机报警
AN_2_4,吊墙吊钩砖结构温升报警
AN_3_1,深层水包冷却水温升报警
AN_3_2,深层水包冷却水断水报警
AN_3_3,卡脖吊平冷却水断水报警
AN_3_4,卡脖吊平喧冷却水温升报警
AN_4_1,液面计冷却水断水报警
AN_4_2,液面计冷却水温升报警
AN_4_3,循环水入口压力低报警
AN_4_4,天然气压力高低报警
AN_5_1,助燃风风压低报警
AN_5_2,净化压缩气压力低报警
AN_5_3,普通压缩空气压力高低报警
AN_5_4,焦炉煤气气压力高低报警
AN_6_1,换向过程故障报警
AN_6_2,空交机换向不到位报警
AN_6_3,投料机故障报警
AN_6_4,备用
AN_7_1,1#压延机冷却水断水报警
AN_7_2,1#压延机冷却水温升报警
AN_7_3,1#过渡辊台冷却水断水报警
AN_7_4,1过渡辊台冷却水温升报警
AN_8_1,1#线唇砖冷却水断水报警
AN_8_2,1#线唇砖冷却水温升报警
AN_8_3,1#退火窑A区风机报警
AN_8_4,1#退火窑B区风机报警
AN_9_1,1#退火窑c区风机报警
AN_9_2,1#退火窑Ret1区风机报警
AN_9_3,1#退火窑Ret2区风机报警
AN_9_4,1#退火窑F1区风机报警
AN_10_1,1#退火窑F2区风机报警
AN_10_2,1#主传动报警
AN_10_3,1#压延机报警
AN_10_4,备用
AN_11_1,2#压延机冷却水断水报警
AN_11_2,2#压延机冷却水温升报警
AN_11_3,2#过渡辊台冷却水断水报警
AN_11_4,2#过渡辊台冷却水温升报警
AN_12_1,2#线唇砖冷却水断水报警
AN_12_2,2#线唇砖冷却水温升报警
AN_12_3,2#退火窑A区风机报警
AN_12_4,2#退火窑B区风机报警
AN_13_1,2#退火窑c区风机报警
AN_13_2,2#退火窑Ret1区风机报警
AN_13_3,2#退火窑Ret2区风机报警
AN_13_4,2#退火窑F1区风机报警
AN_14_1,2#退火窑F2区风机报警
AN_14_2,2#主传动报警
AN_14_3,2#压延机报警
AN_14_4,备用
AN_15_1,3#压延机冷却水断水报警
AN_15_2,3压延机冷却水温升报警
AN_15_3,3#过渡辊台冷却水断水报警
AN_15_4,3#过渡辊台冷却水温升报警
AN_16_1,3#线唇砖冷却水断水报警
AN_16_2,3#线唇砖冷却水温升报警
AN_16_3,3#退火窑A区风机报警
AN_16_4,3#退火窑B区风机报警
AN_17_1,3#退火窑c区风机报警
AN_17_2,3#退火窑Ret1区风机报警
AN_17_3,3#退火窑Ret2区风机报警
AN_17_4,3#退火窑F1区风机报警
AN_18_1,3#退火窑F2区风机报警
AN_18_2,3#主传动报警
AN_18_3,3#压延机报警
AN_18_4,备用
AN_19_1,4#压延机冷却水断水报警
AN_19_2,4压延机冷却水温升报警
AN_19_3,4#过渡辊台冷却水断水报警
AN_19_4,4#过渡辊台冷却水温升报警
AN_20_1,4#线唇砖冷却水断水报警
AN_20_2,4#线唇砖冷却水温升报警
AN_20_3,4#退火窑A区风机报警
AN_20_4,4#退火窑B区风机报警
AN_21_1,4#退火窑c区风机报警
AN_21_2,4#退火窑Ret1区风机报警
AN_21_3,4#退火窑Ret2区风机报警
AN_21_4,4#退火窑F1区风机报警
AN_22_1,4#退火窑F2区风机报警
AN_22_2,4#主传动报警
AN_22_3,4#压延机报警
AN_23_1,5#压延机冷却水断水报警
AN_23_2,5#压延机冷却水温升报警
AN_23_3,5#过渡辊台冷却水断水报警
AN_23_4,5#过渡台冷却水温升报警
AN_24_1,5#线唇砖冷却水断水报警
AN_24_2,5#线唇砖冷却水温升报警
AN_24_3,5#退火窑A区风机报警
AN_24_4,5#退火窑B区风机报警
AN_25_1,5#退火窑c区风机报警
AN_25_2,5#退火窑Ret1区风机报警
AN_25_3,5#退火窑Ret2区风机报警
AN_25_4,5#退火窑F1区风机报警
AN_26_1,5#退火窑F2区风机报警
AN_26_2,5#主传动报警
AN_26_3,5#压延机报警
`;
function AlarmListContainer(props) {
const alarmList = useSelector((state) => state.alarm.list);
// const alarmList = total
// .split("\n")
// .filter((str) => str.trim())
// .map((item) => ({
// id: item.split(",")[0],
// title: item.split(",")[0],
// content: item.split(",")[1],
// }));
return alarmList.map((alarm) => (
<WarnAlert
key={alarm.id}
title={alarm.title}
content={alarm.content}
x={posMap[alarm.title]?.x || 0}
y={posMap[alarm.title]?.y || 0}
/>
));
}
export default AlarmListContainer;

View File

@@ -0,0 +1,18 @@
// import cls from "./index.module.css";
import "./warn-alert.css";
import AlertIcon from "./warn-icon.png";
function WarnAlert(props) {
const { x, y, title, content } = props;
return (
<div className="warn-alert" style={{ top: `${y}px`, left: `${x}px` }}>
<h1 className="">
<img src={AlertIcon} width={24} alt="icon" />
{title || "test"}
</h1>
<p>{content || "Lorem ipsum dolor sit amet consectetur."}</p>
</div>
);
}
export default WarnAlert;

View File

@@ -0,0 +1,104 @@
{
"AN_1_1": { "x": 650, "y": 645 },
"AN_1_2": { "x": 1450, "y": 540 },
"AN_1_3": { "x": 640, "y": 285 },
"AN_1_4": { "x": 720, "y": 645 },
"AN_2_1": { "x": 1250, "y": 540 },
"AN_2_2": { "x": 1200, "y": 540 },
"AN_2_3": { "x": 1460, "y": 410 },
"AN_2_4": { "x": 650, "y": 420 },
"AN_3_1": { "x": 1360, "y": 380 },
"AN_3_2": { "x": 1360, "y": 380 },
"AN_3_3": { "x": 1360, "y": 420 },
"AN_3_4": { "x": 1360, "y": 420 },
"AN_4_1": { "x": 1350, "y": 460 },
"AN_4_2": { "x": 1350, "y": 460 },
"AN_4_3": { "x": 1270, "y": 320 },
"AN_4_4": { "x": 900, "y": 420 },
"AN_5_1": { "x": 650, "y": 645 },
"AN_5_2": { "x": 980, "y": 420 },
"AN_5_3": { "x": 1050, "y": 420 },
"AN_5_4": { "x": 1130, "y": 420 },
"AN_6_1": { "x": 1220, "y": 420 },
"AN_6_2": { "x": 1290, "y": 420 },
"AN_6_3": { "x": 650, "y": 440 },
"AN_6_4": { "x": 1400, "y": 650 },
"AN_7_1": { "x": 1450, "y": 540 },
"AN_7_2": { "x": 1450, "y": 540 },
"AN_7_3": { "x": 1470, "y": 540 },
"AN_7_4": { "x": 1470, "y": 540 },
"AN_8_1": { "x": 1470, "y": 540 },
"AN_8_2": { "x": 1470, "y": 540 },
"AN_8_3": { "x": 1480, "y": 540 },
"AN_8_4": { "x": 1580, "y": 540 },
"AN_9_1": { "x": 1700, "y": 540 },
"AN_9_2": { "x": 1760, "y": 540 },
"AN_9_3": { "x": 1780, "y": 540 },
"AN_9_4": { "x": 1780, "y": 540 },
"AN_10_1": { "x": 1780, "y": 540 },
"AN_10_2": { "x": 1390, "y": 540 },
"AN_10_3": { "x": 1450, "y": 540 },
"AN_10_4": { "x": 1400, "y": 650 },
"AN_11_1": { "x": 1450, "y": 480 },
"AN_11_2": { "x": 1450, "y": 480 },
"AN_11_3": { "x": 1450, "y": 480 },
"AN_11_4": { "x": 1450, "y": 480 },
"AN_12_1": { "x": 1450, "y": 480 },
"AN_12_2": { "x": 1450, "y": 480 },
"AN_12_3": { "x": 1550, "y": 480 },
"AN_12_4": { "x": 1650, "y": 480 },
"AN_13_1": { "x": 1750, "y": 480 },
"AN_13_2": { "x": 1850, "y": 480 },
"AN_13_3": { "x": 1900, "y": 480 },
"AN_13_4": { "x": 1910, "y": 480 },
"AN_14_1": { "x": 1920, "y": 480 },
"AN_14_2": { "x": 1450, "y": 480 },
"AN_14_3": { "x": 1450, "y": 480 },
"AN_14_4": { "x": 1400, "y": 650 },
"AN_15_1": { "x": 1450, "y": 430 },
"AN_15_2": { "x": 1450, "y": 430 },
"AN_15_3": { "x": 1470, "y": 430 },
"AN_15_4": { "x": 1470, "y": 430 },
"AN_16_1": { "x": 1470, "y": 430 },
"AN_16_2": { "x": 1470, "y": 430 },
"AN_16_3": { "x": 1600, "y": 430 },
"AN_16_4": { "x": 1700, "y": 430 },
"AN_17_1": { "x": 1800, "y": 430 },
"AN_17_2": { "x": 1900, "y": 430 },
"AN_17_3": { "x": 1950, "y": 430 },
"AN_17_4": { "x": 1960, "y": 430 },
"AN_18_1": { "x": 1970, "y": 430 },
"AN_18_2": { "x": 1450, "y": 430 },
"AN_18_3": { "x": 1450, "y": 430 },
"AN_18_4": { "x": 1400, "y": 650 },
"AN_19_1": { "x": 1450, "y": 370 },
"AN_19_2": { "x": 1450, "y": 370 },
"AN_19_3": { "x": 1460, "y": 370 },
"AN_19_4": { "x": 1460, "y": 370 },
"AN_20_1": { "x": 1460, "y": 370 },
"AN_20_2": { "x": 1460, "y": 370 },
"AN_20_3": { "x": 1500, "y": 370 },
"AN_20_4": { "x": 1600, "y": 370 },
"AN_21_1": { "x": 1700, "y": 370 },
"AN_21_2": { "x": 1800, "y": 370 },
"AN_21_3": { "x": 1850, "y": 370 },
"AN_21_4": { "x": 1860, "y": 370 },
"AN_22_1": { "x": 1870, "y": 370 },
"AN_22_2": { "x": 1450, "y": 370 },
"AN_22_3": { "x": 1460, "y": 370 },
"AN_23_1": { "x": 1460, "y": 320 },
"AN_23_2": { "x": 1460, "y": 320 },
"AN_23_3": { "x": 1465, "y": 320 },
"AN_23_4": { "x": 1465, "y": 320 },
"AN_24_1": { "x": 1465, "y": 320 },
"AN_24_2": { "x": 1465, "y": 320 },
"AN_24_3": { "x": 1480, "y": 320 },
"AN_24_4": { "x": 1580, "y": 320 },
"AN_25_1": { "x": 1680, "y": 320 },
"AN_25_2": { "x": 1780, "y": 320 },
"AN_25_3": { "x": 1750, "y": 320 },
"AN_25_4": { "x": 1760, "y": 320 },
"AN_26_1": { "x": 1770, "y": 320 },
"AN_26_2": { "x": 1430, "y": 320 },
"AN_26_3": { "x": 1460, "y": 320 }
}

View File

@@ -0,0 +1,65 @@
.warn-alert {
position: fixed;
top: 200px;
left: 200px;
/* height: 72px; */
z-index: 10000;
display: inline-block;
/* background: url(../../../assets/warn-bg.png) 0 0 / 116px 100% repeat-x; */
background: url(./3.png) 0 0 / 116px 100% repeat-x;
box-shadow: 0 0 24px 6px rgba(0, 0, 0, 0.5);
user-select: none;
transform: scale(1);
cursor: pointer;
}
.warn-alert:hover {
transform: scale(1.1);
box-shadow: 0 0 32px 12px rgba(0, 0, 0, 0.5);
z-index: 10001;
}
.warn-alert::before {
box-sizing: border-box;
content: "";
position: absolute;
top: 0;
left: -24px;
width: 24px;
height: 100%;
display: inline-block;
border: 12px solid transparent;
border-right-color: #ff2c2c;
}
.warn-alert::after {
box-sizing: border-box;
content: "";
position: absolute;
top: 0;
right: -24px;
width: 24px;
height: 100%;
display: inline-block;
border: 12px solid transparent;
border-left-color: #ff2c2c;
}
.warn-alert > h1 {
display: flex;
margin: 8px 0 0;
align-items: center;
color: #fff;
font-size: 16px;
text-transform: uppercase;
}
.warn-alert > h1 img {
padding-top: 3px;
margin-left: 10px;
}
.warn-alert > p {
color: #fff;
margin: 0 22px 16px 14px;
font-size: 14px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -2,33 +2,40 @@ import cls from "./index.module.css";
import GradientText from "../../../Common/GradientText";
import { useSelector } from "react-redux";
import { useEffect, useState } from "react";
import eIcon1 from "../../../../assets/Icon/dontknowwhatitis.png";
import eIcon2 from "../../../../assets/Icon/lightnen.png";
function Energy(props) {
const [isPage1, setIsPage1] = useState(true);
const [isPage1] = useState(props.page === 1);
const energyInfo = useSelector((state) => state.energy?.info);
useEffect(() => {
const timer = setInterval(() => {
setIsPage1((pre) => !pre);
}, 10000);
// useEffect(() => {
// const timer = setInterval(() => {
// setIsPage1((pre) => !pre);
// }, 10000);
return () => {
clearInterval(timer);
}
}, []);
// return () => {
// clearInterval(timer);
// }
// }, []);
return (
<div className={" " + cls.layout} style={{ color: "#fff" }}>
<span
className={cls.shadowBorder}
className={`${cls.shadowBorder} ${cls.border}`}
style={{
gridRow: "1 / 3",
paddingTop: "104px",
paddingLeft: "32px",
userSelect: "none",
textAlign: "center",
paddingTop: "96px",
}}
>
<GradientText text="能源" />
{isPage1 ? (
<img src={eIcon1} width={32} alt="eicon1" />
) : (
<img src={eIcon2} width={32} alt="eicon2" />
)}
<GradientText text={"\u2002\u2002能源"} />
</span>
{!isPage1 && (
<div
@@ -65,7 +72,9 @@ function Energy(props) {
{(+energyInfo?.elecQty7)?.toFixed(2) || 0}
</span>
</div>
<div className={cls.shadowBorder + " " + cls.infoText}>
<div
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
>
<span style={{ lineHeight: 1.5 }}>智慧能源光伏发电(总量)/kWh</span>
<span
style={{
@@ -77,7 +86,9 @@ function Energy(props) {
{(+energyInfo?.elecQty4)?.toFixed(2) || 0}
</span>
</div>
<div className={cls.shadowBorder + " " + cls.infoText}>
<div
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
>
<span style={{ lineHeight: 1.5 }}>许昌安彩光伏发电(总量)/kWh</span>
<span
style={{
@@ -105,7 +116,7 @@ function Energy(props) {
style={{ flex: 1 }}
className={cls.shadowBorder + " " + cls.infoText}
>
<span style={{ lineHeight: 1.5 }}>余热发电(实时)/kWh</span>
<span style={{ lineHeight: 1.5 }}>余热发电(昨日)/kWh</span>
<span
style={{
lineHeight: 1.5,
@@ -118,7 +129,9 @@ function Energy(props) {
</div>
<div
style={{ flex: 1 }}
className={cls.shadowBorder + " " + cls.infoText}
className={
cls.shadowBorder + " " + cls.infoText + " " + cls.border
}
>
<span style={{ lineHeight: 1.5 }}>余热发电(总量)/kWh</span>
<span
@@ -133,25 +146,29 @@ function Energy(props) {
</div>
</div>
<span className={cls.shadowBorder + " " + cls.infoText}>
<span style={{ lineHeight: 1.5 }}>水耗量/Km³</span>
<span style={{ lineHeight: 1.5 }}>水耗量(昨日)/Km³</span>
<span style={{ lineHeight: 1.5 }}>
{(+energyInfo?.waterQty)?.toFixed(2) || 0}
</span>
</span>
<span className={cls.shadowBorder + " " + cls.infoText}>
<span style={{ lineHeight: 1.5 }}>天然气I/Nm³</span>
<span style={{ lineHeight: 1.5 }}>天然气I(累计)/Nm³</span>
<span style={{ lineHeight: 1.5 }}>
{energyInfo?.ngQty1?.replace("Nm³", "") || "0Nm³"}
</span>
</span>
<span className={cls.shadowBorder + " " + cls.infoText}>
<span style={{ lineHeight: 1.5 }}>电耗量/kWh</span>
<span
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
>
<span style={{ lineHeight: 1.5 }}>电耗量(昨日)/kWh</span>
<span style={{ lineHeight: 1.5 }}>
{(+energyInfo?.elecQty2)?.toFixed(2) || 0}
</span>
</span>
<span className={cls.shadowBorder + " " + cls.infoText}>
<span style={{ lineHeight: 1.5 }}>天然气II/Nm³</span>
<span
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
>
<span style={{ lineHeight: 1.5 }}>天然气II(累计)/Nm³</span>
<span style={{ lineHeight: 1.5 }}>
{energyInfo?.ngQty2?.replace("Nm³", "") || "0Nm³"}
</span>

View File

@@ -4,13 +4,38 @@
/* grid-template-columns: 133px 158px 292px 292px; */
grid-template-columns: 125px 250px 250px 250px;
/* grid-template-rows: 60px 60px; */
grid-template-rows: 129px 129px;
grid-template-rows: auto;
height: 100%;
}
.shadowBorder {
box-shadow: inset 0 0 12px 3px #fff2;
border-radius: 4px;
padding: 4px;
backdrop-filter: blur(3px);
}
.shadowBorder.border {
position: relative;
border-bottom: 2px solid #00fff7;
}
.shadowBorder.border::before,
.shadowBorder.border::after {
content: "";
position: absolute;
bottom: 0;
display: inline-block;
height: 100%;
width: 2px;
background: linear-gradient(to top, #00fff7, #00fff708, transparent);
}
.shadowBorder.border::before {
left: 0;
}
.shadowBorder.border::after {
right: 0;
}
.infoText {
@@ -27,6 +52,6 @@
}
.infoText > span:last-child {
color: #00FFF7;
color: #00fff7;
font-size: 24px;
}

View File

@@ -6,17 +6,38 @@ import { useState } from "react";
import * as echarts from "echarts";
import dayjs from "dayjs";
function getTimeStr(period) {
return {
:
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().add(1, "d").format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[period];
}
function NO(props) {
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
const [period, setPeriod] = useState("日");
const [timestr, setTimestr] = useState(
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD")
);
let timestr = getTimeStr(period);
const currentTrend =
period === "日"
@@ -33,35 +54,13 @@ function NO(props) {
function handleDateChange(value) {
setPeriod(value);
setTimestr(
{
:
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
" 7点 - " +
dayjs().format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[value]
);
timestr = getTimeStr(value);
}
return (
<GraphBase
icon="smoke"
title="氮氧化物"
desc={`能耗趋势图 ${timestr}`}
desc={`烟气趋势图 ${timestr}`}
switchOptions={false}
defaultSelect={period}
onSwitch={handleSwitch}

View File

@@ -6,17 +6,38 @@ import { useState } from "react";
import * as echarts from "echarts";
import dayjs from "dayjs";
function getTimeStr(period) {
return {
:
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().add(1, 'd').format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[period];
}
function Dust(props) {
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
const [period, setPeriod] = useState("日");
const [timestr, setTimestr] = useState(
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD")
);
let timestr = getTimeStr(period);
const currentTrend =
period === "日"
? dayTrend
@@ -32,36 +53,14 @@ function Dust(props) {
function handleDateChange(value) {
setPeriod(value);
setTimestr(
{
:
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
" 7点 - " +
dayjs().format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[value]
);
timestr = getTimeStr(value);
}
return (
<GraphBase
icon="smoke"
title="颗粒物"
desc={`能耗趋势图 ${timestr}`}
desc={`烟气趋势图 ${timestr}`}
switchOptions={false}
defaultSelect={period}
onSwitch={handleSwitch}

View File

@@ -8,7 +8,8 @@ import { lunarYear } from "../../../../utils/energeChartOption";
import dayjs from "dayjs";
function NatGas(props) {
const elecTrend = useSelector((state) => state.energy.trend.natGas1);
const natGasTrend = useSelector((state) => state.energy.trend.natGas1);
const gasTrend = useSelector((state) => state.energy.trend.natGas2);
const [period, setPeriod] = useState("周");
const [timestr, setTimestr] = useState(
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
@@ -18,7 +19,7 @@ function NatGas(props) {
const options = getOptions(
{ : "week", : "month", : "year" }[period],
elecTrend ?? { week: [], month: [], year: [] }
[natGasTrend, gasTrend] ?? { week: [], month: [], year: [] }
);
function handleSwitch(v) {
@@ -50,7 +51,7 @@ function NatGas(props) {
return (
<GraphBase
icon="battery"
title="天然气I"
title="天然气"
desc={`能耗趋势图 ${timestr}`}
switchOptions={false}
onSwitch={handleSwitch}
@@ -60,6 +61,45 @@ function NatGas(props) {
onDateChange={handleDateChange}
size={["long", "middle"]}
>
<div
className="nat-gas-legend"
style={{
position: "absolute",
top: 28,
right: 144,
display: "flex",
gap: "24px",
}}
>
<div className="legend-item">
<div
className="legend-color"
style={{
display: "inline-block",
width: "12px",
height: "12px",
borderRadius: "2px",
marginRight: "8px",
backgroundColor: "#FFD160",
}}
/>
<span style={{ color: "#fff" }}>天然气I</span>
</div>
<div className="legend-item">
<div
className="legend-color"
style={{
display: "inline-block",
width: "12px",
height: "12px",
borderRadius: "2px",
marginRight: "8px",
backgroundColor: "#12FFF5",
}}
/>
<span style={{ color: "#fff" }}>天然气II</span>
</div>
</div>
{/* real echarts here */}
{options && (
<ReactECharts
@@ -89,8 +129,9 @@ function NatGas(props) {
export default NatGas;
function getOptions(period, trend) {
if (trend[period].length === 0) return null;
function getOptions(period, trendArr) {
if (trendArr[0][period].length === 0 || trendArr[1][period].length === 0)
return null;
// export default function getOptions(seriesData, name) {
const today = new Date();
const currentYear = today.getFullYear();
@@ -185,21 +226,38 @@ function getOptions(period, trend) {
},
},
},
series: {
data: trend[period].map((item) =>
item != null ? (+item).toFixed(2) : null
),
type: "line",
symbol: "circle",
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[0] + "40" },
{ offset: 0.5, color: colors[0] + "20" },
{ offset: 1, color: colors[0] + "00" },
]),
series: [
{
data: trendArr[0][period].map((item) =>
item != null ? (+item).toFixed(2) : null
),
type: "line",
symbol: "circle",
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[0] + "40" },
{ offset: 0.5, color: colors[0] + "20" },
{ offset: 1, color: colors[0] + "00" },
]),
},
},
},
{
data: trendArr[1][period].map((item) =>
item != null ? (+item).toFixed(2) : null
),
type: "line",
symbol: "circle",
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[1] + "40" },
{ offset: 0.5, color: colors[1] + "20" },
{ offset: 1, color: colors[1] + "00" },
]),
},
},
],
// series: seriesData.map((arr, index) => ({
// name: index + 1 + '#' + name,
// data: arr,

View File

@@ -6,17 +6,37 @@ import { useState } from "react";
import * as echarts from "echarts";
import dayjs from "dayjs";
function getTimeStr(period) {
return {
:
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().add(1, "d").format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[period];
}
function Oxygen(props) {
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
const monthTrend = useSelector((state) => state.smoke?.monthTrend);
const yearTrend = useSelector((state) => state.smoke?.yearTrend);
const [period, setPeriod] = useState("日");
const [timestr, setTimestr] = useState(
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD")
);
let timestr = getTimeStr(period);
const currentTrend =
period === "日"
@@ -33,35 +53,13 @@ function Oxygen(props) {
function handleDateChange(value) {
setPeriod(value);
setTimestr(
{
:
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
" 7点 - " +
dayjs().format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[value]
);
timestr = getTimeStr(value);
}
return (
<GraphBase
icon="smoke"
title="氧气含量"
desc={`能耗趋势图 ${timestr}`}
desc={`烟气趋势图 ${timestr}`}
switchOptions={false}
defaultSelect={period}
onSwitch={handleSwitch}

View File

@@ -6,6 +6,30 @@ import { useState } from "react";
import * as echarts from "echarts";
import dayjs from "dayjs";
function getTimeStr(period) {
return {
:
dayjs().format("YYYY.MM.DD") +
" 7点 - " +
dayjs().add(1, 'd').format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[period];
}
function SO2(props) {
const dayTrend = useSelector((state) => state.smoke?.dayTrend);
const weekTrend = useSelector((state) => state.smoke?.weekTrend);
@@ -21,47 +45,22 @@ function SO2(props) {
: period === "月"
? monthTrend
: yearTrend;
const [timestr, setTimestr] = useState(
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD")
);
let timestr = getTimeStr(period);
const options = getOptions("SO2_float", period, currentTrend);
function handleSwitch(v) {}
function handleDateChange(value) {
setPeriod(value);
setTimestr(
{
:
dayjs().subtract(1, "day").format("YYYY.MM.DD") +
" 7点 - " +
dayjs().format("YYYY.MM.DD") +
" 7点",
:
dayjs().subtract(1, "year").endOf("year").format("YYYY.MM.") +
"29 - " +
dayjs().endOf("year").format("YYYY.MM.") +
"28",
:
dayjs().subtract(7, "day").format("YYYY.MM.DD") +
" - " +
dayjs().subtract(1, "day").format("YYYY.MM.DD"),
:
dayjs().subtract(1, "month").format("YYYY.MM.") +
"29 - " +
dayjs().format("YYYY.MM.") +
"28",
}[value]
);
timestr = getTimeStr(value);
}
return (
<GraphBase
icon="smoke"
title="二氧化硫"
desc={`能耗趋势图 ${timestr}`}
desc={`烟气趋势图 ${timestr}`}
switchOptions={false}
defaultSelect={period}
onSwitch={handleSwitch}

View File

@@ -1,21 +1,23 @@
import cls from "./index.module.css";
import GradientText from "../../../Common/GradientText";
import { useSelector } from "react-redux";
import eIcon1 from "../../../../assets/Icon/oilstation.png";
function SmokeHandle(props) {
const smokeInfo = useSelector((state) => state.smoke?.info);
return (
<div className={" " + cls.smoke} style={{ color: "#fff" }}>
<span
className={cls.shadowBorder}
className={cls.shadowBorder + " " + cls.border}
style={{
gridRow: "1 / 3",
paddingTop: "96px",
paddingLeft: "32px",
userSelect: "none",
textAlign: "center",
}}
>
<GradientText text="烟气处理" />
<img src={eIcon1} width={32} alt="eIcon1" />
<GradientText text={"\u2002\u2002烟气处理"} />
</span>
<span
className={cls.shadowBorder + " " + cls.infoText}
@@ -32,13 +34,26 @@ function SmokeHandle(props) {
{(+smokeInfo?.NOX_float)?.toFixed(2) || 0}
</span>
</span>
<span className={cls.shadowBorder + " " + cls.infoText}>
<span
className={cls.shadowBorder + " " + cls.infoText + " " + cls.border}
style={{ gridColumn: "span 2" }}
>
<span style={{ lineHeight: 1.5 }}>二氧化硫浓度 mg/</span>
<span style={{ lineHeight: 1.5 }}>
{(+smokeInfo?.SO2_float)?.toFixed(2) || 0}
</span>
</span>
<span className={cls.shadowBorder + " " + cls.infoText}>
<span
className={
cls.shadowBorder +
" " +
cls.infoText +
" " +
cls.border +
" " +
cls.disabled
}
>
<span style={{ lineHeight: 1.5 }}>颗粒物浓度 mg/</span>
<span style={{ lineHeight: 1.5 }}>
{(+smokeInfo?.dust_float)?.toFixed(2) || 0}

View File

@@ -3,7 +3,8 @@
gap: 6px;
grid-template-columns: 187px 347px 347px;
/* grid-template-rows: 60px 60px; */
grid-template-rows: 129px 129px;
/* grid-template-rows: 129px 129px; */
grid-template-rows: auto;
height: 100%;
}
@@ -11,6 +12,30 @@
box-shadow: inset 0 0 12px 3px #fff2;
border-radius: 4px;
padding: 4px;
backdrop-filter: blur(3px);
}
.shadowBorder.border {
position: relative;
border-bottom: 2px solid #00fff7;
}
.shadowBorder.border::before,
.shadowBorder.border::after {
content: "";
position: absolute;
bottom: 0;
display: inline-block;
height: 100%;
width: 2px;
background: linear-gradient(to top, #00fff7, #00fff708, transparent);
}
.shadowBorder.border::before {
left: 0;
}
.shadowBorder.border::after {
right: 0;
}
.infoText {
@@ -30,3 +55,10 @@
color: #00fff7;
font-size: 28px;
}
.disabled {
display: none;
pointer-events: none;
opacity: 0.5;
color: transparent;
}

View File

@@ -1,6 +1,7 @@
import React from 'react';
import Item2 from './RightTable';
import Item1 from '../../../Common/TimeFireDir';
// import Item1 from '../../../Common/TimeFireDir';
import Item1 from '../../../Common/VideoMonitor';
import cls from './index.module.scss';

View File

@@ -1,104 +1,108 @@
import EnterVideo from './videoComponents/EnterVideo';
import EnterToFloorOne from './videoComponents/EnterToFloor1';
import EnterToFloorTwo from './videoComponents/EnterToFloor2';
import FloorOneToTwo from './videoComponents/Floor1To2';
import FloorTwoToOne from './videoComponents/Floor2To1';
import { useRef, useEffect, useReducer } from 'react';
import { AnimatePresence } from 'framer-motion';
import EnterVideo from "./videoComponents/EnterVideo";
import EnterToFloorOne from "./videoComponents/EnterToFloor1";
import EnterToFloorTwo from "./videoComponents/EnterToFloor2";
import FloorOneToTwo from "./videoComponents/Floor1To2";
import FloorTwoToOne from "./videoComponents/Floor2To1";
import { useRef, useEffect, useReducer } from "react";
import { AnimatePresence } from "framer-motion";
const initOpacity = {
enterVideo: 1,
enterToFloorOne: 0,
enterToFloorTwo: 0,
floorOneToTwo: 0,
floorTwoToOne: 0,
enterVideo: 1,
enterToFloorOne: 0,
enterToFloorTwo: 0,
floorOneToTwo: 0,
floorTwoToOne: 0,
};
const opacityReducer = (state, action) => {
switch (action.type) {
case 'enter-to-1': {
return {
...initOpacity,
enterToFloorOne: 1,
enterVideo: 0,
};
}
case 'enter-to-2': {
return {
...initOpacity,
enterToFloorTwo: 1,
enterVideo: 0,
};
}
case 'floor-1-to-2': {
return {
...initOpacity,
floorOneToTwo: 1,
enterToFloorOne: 0,
enterVideo: 0,
floorTwoToOne: 0,
};
}
case 'floor-2-to-1': {
return {
...initOpacity,
floorTwoToOne: 1,
enterToFloorTwo: 0,
floorOneToTwo: 0,
enterVideo: 0,
};
}
}
switch (action.type) {
case "enter-to-1": {
return {
...initOpacity,
enterToFloorOne: 1,
enterVideo: 0,
};
}
case "enter-to-2": {
return {
...initOpacity,
enterToFloorTwo: 1,
enterVideo: 0,
};
}
case "floor-1-to-2": {
return {
...initOpacity,
floorOneToTwo: 1,
enterToFloorOne: 0,
enterVideo: 0,
floorTwoToOne: 0,
};
}
case "floor-2-to-1": {
return {
...initOpacity,
floorTwoToOne: 1,
enterToFloorTwo: 0,
floorOneToTwo: 0,
enterVideo: 0,
};
}
}
};
function VideoContainer(props) {
const floor = props.floor || null;
const lastFloor = useRef(null);
const [opacity, dispatch] = useReducer(opacityReducer, initOpacity);
const floor = props.floor || null;
const lastFloor = useRef(null);
const [opacity, dispatch] = useReducer(opacityReducer, initOpacity);
useEffect(() => {
if (floor) {
if (floor == 1) {
if (lastFloor.current == 2) {
dispatch({ type: 'floor-2-to-1' });
} else {
dispatch({ type: 'enter-to-1' });
}
} else if (floor == 2) {
if (lastFloor.current == 1) {
dispatch({ type: 'floor-1-to-2' });
} else {
dispatch({ type: 'enter-to-2' });
}
}
lastFloor.current = floor;
}
}, [floor]);
useEffect(() => {
if (floor) {
if (floor == 1) {
if (lastFloor.current == 2) {
dispatch({ type: "floor-2-to-1" });
} else {
dispatch({ type: "enter-to-1" });
}
} else if (floor == 2) {
if (lastFloor.current == 1) {
dispatch({ type: "floor-1-to-2" });
} else {
dispatch({ type: "enter-to-2" });
}
}
lastFloor.current = floor;
}
}, [floor]);
const enterToFloorOne = () => {
// 更新层数
props.onFloorUpdate(1);
// floor1 one 立即显示enter 延迟点消失
dispatch({ type: 'enter-to-1' });
};
const enterToFloorOne = () => {
// 更新层数
props.onFloorUpdate(1);
// floor1 one 立即显示enter 延迟点消失
dispatch({ type: "enter-to-1" });
};
function handleEnterVideoEnd() {
// console.log('video end');
enterToFloorOne();
}
function handleEnterVideoEnd() {
// console.log('video end');
enterToFloorOne();
}
return (
<AnimatePresence>
<EnterVideo
key="enter"
onVideoEnd={handleEnterVideoEnd}
opacity={opacity.enterVideo}
/>
<EnterToFloorOne key="enter-to-1" opacity={opacity.enterToFloorOne} />
<EnterToFloorTwo key="enter-to-2" opacity={opacity.enterToFloorTwo} />
<FloorOneToTwo key="1-to-2" opacity={opacity.floorOneToTwo} />
<FloorTwoToOne key="2-to-1" opacity={opacity.floorTwoToOne} />
</AnimatePresence>
);
return (
<AnimatePresence>
<EnterVideo
key="enter"
onVideoEnd={handleEnterVideoEnd}
opacity={opacity.enterVideo}
/>
<EnterToFloorOne key="enter-to-1" opacity={opacity.enterToFloorOne} />
<EnterToFloorTwo key="enter-to-2" opacity={opacity.enterToFloorTwo} />
<FloorOneToTwo
key="1-to-2"
opacity={opacity.floorOneToTwo}
floor={floor}
/>
<FloorTwoToOne key="2-to-1" opacity={opacity.floorTwoToOne} />
</AnimatePresence>
);
}
export default VideoContainer;

View File

@@ -19,7 +19,7 @@ function EnterToFloorOne(props) {
setTimeout(() => {
// console.log("开启enter的火播放");
setFireCanPlay(true);
}, 5000);
}, 1800);
}
return () => {
// console.log("关闭enter的火播放");
@@ -49,7 +49,7 @@ function EnterToFloorOne(props) {
<source src="/video/floor1.webm" type="video/mp4" />
</video>
{/* {fireCanPlay && fireDir == "东火" && (
{fireCanPlay && fireDir == "东火" && (
<video
src="/video/fire_top.webm"
muted
@@ -68,7 +68,7 @@ function EnterToFloorOne(props) {
width={3900}
style={{ position: "absolute", top: "-20px", left: "-20px" }}
></video>
)} */}
)}
<TemperatureTop
style={{

View File

@@ -1,9 +1,8 @@
import { motion, AnimatePresence } from "framer-motion";
import { useRef, useEffect, useMemo, useState } from "react";
import { useRef, useEffect, useState } from "react";
import FeederStatus from "../../../../Common/Feeder";
import TemperatureTop from "../../../../../components/Common/TemperatureTop";
import TemperatureBottom from "../../../../Common/TemperatureBottom";
import { useSelector, useDispatch } from "react-redux";
import { useSelector } from "react-redux";
function FloorOneToTwo(props) {
const fireInfo = useSelector((state) => state.fireInfo);
@@ -13,6 +12,7 @@ function FloorOneToTwo(props) {
const vd = useRef(null);
const show = props.opacity || 0;
const speed = "s";
useEffect(() => {
if (show) {
@@ -20,7 +20,7 @@ function FloorOneToTwo(props) {
setTimeout(() => {
// console.log("开启1-2的火播放");
setFireCanPlay(true);
}, 3000);
}, 2000);
}
if (!show) setFireCanPlay(false);
return () => {
@@ -81,6 +81,8 @@ function FloorOneToTwo(props) {
width: "2380px",
zIndex: 0,
}}
speed={speed}
floor={props.floor}
/>
<FeederStatus />
</motion.div>

View File

@@ -19,7 +19,7 @@ function FloorTwoToOne(props) {
setTimeout(() => {
// console.log("开启2-1的火播放");
setFireCanPlay(true);
}, 3000);
}, 1800);
}
if (!show) setFireCanPlay(false);
return () => {

View File

@@ -0,0 +1,120 @@
import EnterVideo from "./videoComponents/EnterVideo";
import EnterToFloorOne from "./videoComponents/EnterToFloor1";
import EnterToFloorTwo from "./videoComponents/EnterToFloor2";
import FloorOneToTwo from "./videoComponents/Floor1To2";
import FloorTwoToOne from "./videoComponents/Floor2To1";
import { useRef, useEffect, useReducer } from "react";
import { AnimatePresence } from "framer-motion";
const initOpacity = {
enterVideo: 1,
enterToFloorOne: 0,
enterToFloorTwo: 0,
floorOneToTwo: 0,
floorTwoToOne: 0,
};
const opacityReducer = (state, action) => {
switch (action.type) {
case "enter-to-1": {
return {
...initOpacity,
enterToFloorOne: 1,
enterVideo: 0,
};
}
case "enter-to-2": {
return {
...initOpacity,
enterToFloorTwo: 1,
enterVideo: 0,
};
}
case "floor-1-to-2": {
return {
...initOpacity,
floorOneToTwo: 1,
enterToFloorOne: 0,
enterVideo: 0,
floorTwoToOne: 0,
};
}
case "floor-2-to-1": {
return {
...initOpacity,
floorTwoToOne: 1,
enterToFloorTwo: 0,
floorOneToTwo: 0,
enterVideo: 0,
};
}
}
};
function VideoContainer(props) {
const floor = props.floor || null;
const preFloor = props.preFloor.current || null;
const lastFloor = useRef(null);
const [opacity, dispatch] = useReducer(opacityReducer, initOpacity);
useEffect(() => {
if (floor) {
if (floor == 1) {
if (lastFloor.current == 2 || lastFloor.current == 3) {
dispatch({ type: "floor-2-to-1" });
} else {
dispatch({ type: "enter-to-1" });
}
} else if (floor == 2) {
if (lastFloor.current == 1) {
dispatch({ type: "floor-1-to-2" });
} else if (lastFloor.current == 3) {
// 视频不变画面隐藏,通过判断floor的值隐藏3显示2
} else {
dispatch({ type: "enter-to-2" });
}
} else if (floor == 3) {
if (lastFloor.current == 1) {
dispatch({ type: "floor-1-to-2" });
} else if (lastFloor.current == 2) {
// 视频不变画面隐藏通过判断floor的值隐藏2显示3
} else {
dispatch({ type: "enter-to-2" });
}
}
lastFloor.current = floor;
}
}, [floor]);
const enterToFloorOne = () => {
// 更新层数
props.onFloorUpdate(1);
// floor1 one 立即显示enter 延迟点消失
dispatch({ type: "enter-to-1" });
};
function handleEnterVideoEnd() {
// console.log('video end');
enterToFloorOne();
}
return (
<AnimatePresence>
<EnterVideo
key="enter"
onVideoEnd={handleEnterVideoEnd}
opacity={opacity.enterVideo}
/>
<EnterToFloorOne key="enter-to-1" opacity={opacity.enterToFloorOne} />
<EnterToFloorTwo key="enter-to-2" opacity={opacity.enterToFloorTwo} />
<FloorOneToTwo
key="1-to-2"
opacity={opacity.floorOneToTwo}
floor={floor}
preFloor={preFloor}
/>
<FloorTwoToOne key="2-to-1" opacity={opacity.floorTwoToOne} />
</AnimatePresence>
);
}
export default VideoContainer;

View File

@@ -0,0 +1,95 @@
import { useState, useRef } from "react";
import cls from "./index.module.css";
import Chart2 from "../../../Common/TimeFireDir";
import VideoContainer from "./VideoContainer";
function KilnCenter() {
const [floor, setFloor] = useState(0);
const preFloor = useRef();
function onFloorUpdate(flr) {
preFloor.current = floor;
setFloor(flr);
}
return (
<div
className="bgKilnInner"
style={{
width: "100%",
position: "absolute",
top: "12%",
display: "flex",
flexDirection: "column",
}}
>
{/* 时间火向数据 */}
<div
className="fireAndTime"
style={{ position: "absolute", top: "-112px", height: "212px" }}
>
<Chart2 />
</div>
{/* menu */}
<div
className="subMenu"
style={{
display: "flex",
marginBottom: "24px",
justifyContent: "center",
}}
>
<div
className={
"flr flr1 " + cls.menuItem + " " + (floor === 1 ? cls.active : "")
}
onClick={() => onFloorUpdate(1)}
>
碹顶温度
</div>
<div
className={
"flr flr2 " + cls.menuItem + " " + (floor === 2 ? cls.active : "")
}
onClick={() => onFloorUpdate(2)}
>
池底温度
</div>
<div
className={
"flr flr2 " + cls.menuItem + " " + (floor === 3 ? cls.active : "")
}
onClick={() => onFloorUpdate(3)}
>
溶液速度
</div>
</div>
{/* 颜色指示图 */}
<div
style={{
position: "absolute",
top: "30px",
right: "450px",
width: "300px",
height: "41px",
}}
>
<img
src={require("../../../../assets/tempIntr.png")}
alt=""
style={{ width: "300px", height: "41px" }}
/>
</div>
{/* video */}
<VideoContainer
onFloorUpdate={onFloorUpdate}
floor={floor}
preFloor={preFloor}
/>
</div>
);
}
export default KilnCenter;

View File

@@ -0,0 +1,46 @@
.menuItem {
transition: all 0.3s ease-out;
cursor: pointer;
user-select: none;
padding: 10px 50px;
font-size: 32px;
line-height: 48px;
letter-spacing: 6px;
background: url(../../../../assets/bg_center_menu.png) no-repeat;
background-size: 100% 50%;
background-position: bottom;
color: #00fff788;
font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue',
'PingFang SC', 'Microsoft YaHei', '微软雅黑', 'Microsoft YaHei UI',
'Source Han Sans SC', 'Noto Sans CJK SC', 'WenQuanYi Micro Hei', sans-serif;
}
.menuItem.active,
.menuItem:hover {
color: #00fff7;
}
.menuItem:not(:first-child) {
margin-left: 50px;
}
.videoLayer2 {
width: 2440px;
height: 720px;
background: url(../../../../assets/video-layer-2.png) no-repeat;
background-size: 100% 100%;
background-position: 0 0;
position: fixed;
top: 0;
left: 0;
}
.videoLayer1 {
width: 2440px;
height: 720px;
background: url(../../../../assets/floor1-status.png) no-repeat;
background-size: 100% 100%;
background-position: 0 0;
position: fixed;
top: 0;
left: 0;
}

View File

@@ -0,0 +1,101 @@
import { motion, AnimatePresence } from "framer-motion";
import { useRef, useEffect, useMemo, useCallback, useState } from "react";
import FeederStatus from "../../../../Common/Feeder";
import TemperatureBottom from "../../../../Common/TemperatureBottom";
import TemperatureTop from "../../../../Common/TemperatureTop";
import { useSelector, useDispatch } from "react-redux";
import TopColorBlockEnter from "./../../components/TopColorBlockEnter";
function EnterToFloorOne(props) {
const fireInfo = useSelector((state) => state.fireInfo);
const fireDir = fireInfo?.fireDirection || null;
const [fireCanPlay, setFireCanPlay] = useState(false);
const vd = useRef(null);
const show = props.opacity || 0;
useEffect(() => {
if (show) {
vd.current.play();
setTimeout(() => {
// console.log("开启enter的火播放");
setFireCanPlay(true);
}, 1800);
}
return () => {
// console.log("关闭enter的火播放");
setFireCanPlay(false);
};
}, [show]);
return (
<AnimatePresence>
{show && (
<motion.div
className="video-wrapper"
style={{
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "100%",
zIndex: -999,
overflow: "hidden",
}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: [1, 1, 0], transition: { duration: 0.5 } }}
>
<video ref={vd} muted width={"100%"}>
<source src="/video/floor1.webm" type="video/mp4" />
</video>
{fireCanPlay && fireDir == "东火" && (
<video
src="/video/fire_top.webm"
muted
autoPlay
loop
width={3900}
style={{
position: "absolute",
top: "-20px",
left: "-20px",
zIndex: 9,
}}
></video>
)}
{fireCanPlay && fireDir == "西火" && (
<video
src="/video/fire_down.webm"
muted
autoPlay
loop
width={3900}
style={{
position: "absolute",
top: "-20px",
left: "-20px",
zIndex: 9,
}}
></video>
)}
<TopColorBlockEnter />
<TemperatureTop
style={{
top: "218px",
left: "678px",
width: "2380px",
zIndex: 10,
}}
/>
<FeederStatus />
</motion.div>
)}
</AnimatePresence>
);
}
export default EnterToFloorOne;

View File

@@ -0,0 +1,44 @@
import { motion } from 'framer-motion';
import { useRef, useEffect } from 'react';
function EnterToFloorTwo(props) {
const vd = useRef(null);
const opacity = props.opacity || 0;
if (opacity == 1) {
setTimeout(() => {
vd.current.play();
}, 100);
}
useEffect(() => {
vd.current.addEventListener('ended', () => {
setTimeout(() => {
vd.current.currentTime = 0;
}, 1000);
});
}, []);
return (
<motion.div
className="video-wrapper"
style={{
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: -1000,
opacity: opacity,
zIndex: -999,
}}
transition={{ type: 'tween', duration: 1 }}
>
<video ref={vd} muted width={'100%'}>
<source src="/video/floor2.webm" type="video/mp4" />
</video>
</motion.div>
);
}
export default EnterToFloorTwo;

View File

@@ -0,0 +1,38 @@
import { motion, AnimatePresence } from 'framer-motion';
import { useEffect, useRef, useMemo } from 'react';
function EnterVideo(props) {
const show = props.opacity || 0;
const vd = useRef(null);
useEffect(() => {
vd.current.addEventListener('ended', props.onVideoEnd);
}, []);
return (
<AnimatePresence>
{show && (
<motion.div
className="video-wrapper"
style={{
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: -1000,
}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: [1, 1, 0], transition: { duration: 0.5 } }}
>
<video ref={vd} muted autoPlay={true} width={'100%'}>
<source src="/video/enter.webm" type="video/mp4" />
</video>
</motion.div>
)}
</AnimatePresence>
);
}
export default EnterVideo;

View File

@@ -0,0 +1,155 @@
import { motion, AnimatePresence } from "framer-motion";
import { useRef, useEffect, useState } from "react";
import FeederStatus from "../../../../Common/Feeder";
import TemperatureBottom from "../../../../Common/TemperatureBottom";
import { useSelector } from "react-redux";
import BotttomColorBlock from "./../../components/BotttomColorBlock";
import image from "./../../../../../assets/kilnSpeed.png";
function FloorOneToTwo(props) {
const fireInfo = useSelector((state) => state.fireInfo);
const fireDir = fireInfo?.fireDirection || null;
const [fireCanPlay, setFireCanPlay] = useState(false);
const vd = useRef(null);
const show = props.opacity || 0;
// 是否显示溶液速度标签的内容
// 池底温度和溶液速度写在一个页面上
const showSpeed = props.floor == 3 ? true : false; //显示3
const showBottom = props.floor == 2 ? true : false; //显示2
const speed = props.preFloor == 2 || props.preFloor == 3 ? "f" : "s";
const [speedAn, setSpeedAn] = useState({});
useEffect(() => {
// 23互切不用展示动画
if (speed === "f") {
setSpeedAn({
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 0 },
});
} else {
if (props.floor === 3) {
setSpeedAn({
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 1.5 },
});
} else {
setSpeedAn({});
}
}
}, [props.floor]);
useEffect(() => {
if (show) {
vd.current.play();
setTimeout(() => {
// console.log("开启1-2的火播放");
setFireCanPlay(true);
}, 2000);
}
if (!show) setFireCanPlay(false);
return () => {
// console.log("关闭1-2的火播放");
setFireCanPlay(false);
};
}, [show]);
return (
<AnimatePresence>
{show && (
<motion.div
className="video-wrapper"
style={{
position: "fixed",
top: "0px",
left: "0px",
width: "calc(100% - 50px)",
height: "calc(100% - 7px)",
zIndex: -998,
overflow: "clip",
}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, transition: { duration: 0, delay: 0.1 } }}
>
<video ref={vd} muted>
<source src="/video/1to2.webm" type="video/mp4" />
</video>
{/* 窑炉的色块 */}
{showBottom && (
<BotttomColorBlock speed={speed} floor={props.floor} />
)}
{showBottom && fireCanPlay && fireDir == "东火" && (
<video
src="/video/fire_top.webm"
muted
autoPlay
loop
width={3700}
style={{
position: "absolute",
top: "18px",
left: "72px",
zIndex: 9,
}}
></video>
)}
{showBottom && fireCanPlay && fireDir == "西火" && (
// {fireCanPlay && (
<video
src="/video/fire_down.webm"
muted
autoPlay
loop
width={3780}
style={{
position: "absolute",
top: "-24px",
left: "12px",
zIndex: 9,
}}
></video>
)}
{/* 温度组件 */}
{showBottom && (
<TemperatureBottom
style={{
top: "208px",
// left: "638px",
left: "690px",
width: "2380px",
zIndex: 10,
}}
speed={speed}
floor={props.floor}
/>
)}
{/* 溶液速度色块 */}
{showSpeed && (
<motion.div
style={{
position: "absolute",
top: "242px",
left: "445px",
zIndex: "999",
}}
animate={speedAn}
>
<img
src={image}
alt=""
width="100%"
height="100%"
style={{ transform: "scale(0.583, 0.593)" }}
/>
</motion.div>
)}
<FeederStatus />
</motion.div>
)}
</AnimatePresence>
);
}
export default FloorOneToTwo;

View File

@@ -0,0 +1,104 @@
import { motion, AnimatePresence } from "framer-motion";
import { useRef, useEffect, useMemo, useState } from "react";
import FeederStatus from "../../../../Common/Feeder";
import TemperatureBottom from "../../../../Common/TemperatureBottom";
import TemperatureTop from "../../../../Common/TemperatureTop";
import { useSelector, useDispatch } from "react-redux";
import TopColorBlock from "./../../components/TopColorBlock";
function FloorTwoToOne(props) {
const fireInfo = useSelector((state) => state.fireInfo);
const fireDir = fireInfo?.fireDirection || null;
const [fireCanPlay, setFireCanPlay] = useState(false);
const vd = useRef(null);
const show = props.opacity || 0;
useEffect(() => {
if (show) {
vd.current.play();
setTimeout(() => {
// console.log("开启2-1的火播放");
setFireCanPlay(true);
}, 1800);
}
if (!show) setFireCanPlay(false);
return () => {
// console.log("关闭2-1的火播放");
setFireCanPlay(false);
};
}, [show]);
return (
<AnimatePresence>
{show && (
<motion.div
className="video-wrapper"
style={{
position: "fixed",
top: "0px",
left: "0px",
width: "calc(100% - 50px)",
height: "calc(100% - 7px)",
zIndex: -998,
overflow: "clip",
}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, transition: { duration: 0.2, delay: 0.2 } }}
>
<video ref={vd} muted>
<source src="/video/2to1.webm" type="video/mp4" />
</video>
{fireCanPlay && fireDir == "东火" && (
// {fireCanPlay && (
<video
src="/video/fire_top.webm"
muted
autoPlay
loop
width={3800}
style={{
position: "absolute",
top: "10px",
left: "0px",
zIndex: 9,
}}
></video>
)}
{fireCanPlay && fireDir == "西火" && (
// {fireCanPlay && (
<video
src="/video/fire_down.webm"
muted
autoPlay
loop
width={3800}
style={{
position: "absolute",
top: "-12px",
left: "-10px",
zIndex: 9,
}}
></video>
)}
<TopColorBlock />
<TemperatureTop
style={{
top: "200px",
left: "652px",
width: "2380px",
zIndex: 10,
}}
/>
<FeederStatus style={{ left: "680px" }} />
</motion.div>
)}
</AnimatePresence>
);
}
export default FloorTwoToOne;

View File

@@ -0,0 +1,22 @@
import React from 'react';
import KilnPress from './../components/KilnPress';
import LiquidTrend from './../components/LiquidTrend';
import { motion } from 'framer-motion';
import cls from './index.module.scss';
export default function index() {
return (
<motion.div
className={cls.leftBar}
initial={{ opacity: 0, position: 'absolute' }}
animate={{ opacity: 1, position: 'relative' }}
exit={{ opacity: 0, position: 'relative' }}
transition={{ type: 'tween' }}
>
<KilnPress style={{ flex: 1, width: '100%', marginTop: '24px' }} />
<LiquidTrend style={{ flex: 1, width: '100%', marginTop: '24px' }} />
</motion.div>
);
}

View File

@@ -0,0 +1,9 @@
.leftBar {
width: 625px;
height: 966px;
// margin-left: 40px;
display: flex;
flex-direction: column;
justify-content: space-between;
}

View File

@@ -0,0 +1,22 @@
import React from 'react';
import KilnTop from './../components/KilnTop';
import KilnBottom from './../components/KilnBottom';
import { motion } from 'framer-motion';
import cls from './index.module.scss';
export default function index() {
return (
<motion.div
className={cls.leftBar}
initial={{ opacity: 0, position: 'absolute' }}
animate={{ opacity: 1, position: 'relative' }}
exit={{ opacity: 0, position: 'relative' }}
transition={{ type: 'tween' }}
>
<KilnTop style={{ flex: 1, width: '100%', marginTop: '24px' }} />
<KilnBottom style={{ flex: 1, width: '100%', marginTop: '24px' }} />
</motion.div>
);
}

View File

@@ -0,0 +1,9 @@
.leftBar {
width: 625px;
height: 966px;
// margin-left: 40px;
display: flex;
flex-direction: column;
justify-content: space-between;
}

View File

@@ -0,0 +1,369 @@
import { useSelector } from "react-redux";
import React from "react";
import { useEffect, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ReactComponent as B1 } from "./pic/b1.svg";
import { ReactComponent as B2 } from "./pic/b2.svg";
import { ReactComponent as B3 } from "./pic/b3.svg";
import { ReactComponent as B4 } from "./pic/b4.svg";
import { ReactComponent as B5 } from "./pic/b5.svg";
import { ReactComponent as B6 } from "./pic/b6.svg";
import { ReactComponent as B7 } from "./pic/b7.svg";
import { ReactComponent as B8 } from "./pic/b8.svg";
import { ReactComponent as T1 } from "./pic/t1.svg";
import { ReactComponent as T2 } from "./pic/t2.svg";
import { ReactComponent as T3 } from "./pic/t3.svg";
import { ReactComponent as T4 } from "./pic/t4.svg";
import { ReactComponent as T5 } from "./pic/t5.svg";
import { ReactComponent as T6 } from "./pic/t6.svg";
import { ReactComponent as T7 } from "./pic/t7.svg";
import { ReactComponent as T8 } from "./pic/t8.svg";
const BotttomColorBlock = (props) => {
const tempBottom = useSelector((state) => state.temperature.bottom);
const speed = props.speed;
const floor = props.floor;
const [speedAn, setSpeedAn] = useState({});
useEffect(() => {
// 23互切不用展示动画
if (speed === "f") {
setSpeedAn({});
} else {
if (floor === 2) {
setSpeedAn({
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 1.8 },
});
} else {
setSpeedAn({});
}
}
}, [floor]);
function returnColor(n) {
let num = Number(tempBottom[n].slice(0, tempBottom[n].length - 1));
if (num <= 100) {
return "rgba(96, 0, 189, 0.7)";
} else if (num > 100 && num <= 200) {
return "rgba(102, 7, 255, 0.7)";
} else if (num > 200 && num <= 300) {
return "rgba(10, 20, 255, 0.7)";
} else if (num > 300 && num <= 400) {
return "rgba(7, 89, 255, 0.7)";
} else if (num > 400 && num <= 500) {
return "rgba(7, 139, 255, 0.7)";
} else if (num > 500 && num <= 600) {
return "rgba(7, 194, 255, 0.7)";
} else if (num > 600 && num <= 700) {
return "rgba(7, 255, 253, 0.7)";
} else if (num > 700 && num <= 800) {
return "rgba(7, 255, 205, 0.7)";
} else if (num > 800 && num <= 900) {
return "rgba(20, 237, 127, 0.7)";
} else if (num > 900 && num <= 1000) {
return "rgba(0, 193, 39, 0.7)";
} else if (num > 1000 && num <= 1100) {
return "rgba(147, 210, 1, 0.7)";
} else if (num > 1100 && num <= 1200) {
return "rgba(206, 206, 0, 0.7)";
} else if (num > 1200 && num <= 1300) {
return "rgba(255, 226, 13, 0.7)";
} else if (num > 1300 && num <= 1400) {
return "rgba(249, 240, 146, 0.7)";
} else if (num > 1400 && num <= 1500) {
return "rgba(250, 204, 93, 0.7)";
} else if (num > 1500 && num <= 1600) {
return "rgba(240, 139, 32, 0.7)";
} else if (num > 1600 && num <= 1700) {
return "rgba(241, 88, 26, 0.7)";
} else if (num > 1700 && num <= 1800) {
return "rgba(255, 0, 0, 0.7)";
} else if (num > 1800 && num <= 1900) {
return "rgba(182, 0, 0, 0.7)";
} else if (num > 1900) {
return "rgba(140, 0, 33, 0.7)";
}
}
function returnColor2(n) {
let num = Number(tempBottom[n].slice(0, tempBottom[n].length - 1));
if (num <= 100) {
return "rgba(96, 0, 189, 0.9)";
} else if (num > 100 && num <= 200) {
return "rgba(102, 7, 255, 0.9)";
} else if (num > 200 && num <= 300) {
return "rgba(10, 20, 255, 0.9)";
} else if (num > 300 && num <= 400) {
return "rgba(7, 89, 255, 0.9)";
} else if (num > 400 && num <= 500) {
return "rgba(7, 139, 255, 0.9)";
} else if (num > 500 && num <= 600) {
return "rgba(7, 194, 255, 0.9)";
} else if (num > 600 && num <= 700) {
return "rgba(7, 255, 253, 0.9)";
} else if (num > 700 && num <= 800) {
return "rgba(7, 255, 205, 0.9)";
} else if (num > 800 && num <= 900) {
return "rgba(20, 237, 127, 0.9)";
} else if (num > 900 && num <= 1000) {
return "rgba(0, 193, 39, 0.9)";
} else if (num > 1000 && num <= 1100) {
return "rgba(147, 210, 1, 0.9)";
} else if (num > 1100 && num <= 1200) {
return "rgba(206, 206, 0, 0.9)";
} else if (num > 1200 && num <= 1300) {
return "rgba(255, 226, 13, 0.9)";
} else if (num > 1300 && num <= 1400) {
return "rgba(249, 240, 146, 0.9)";
} else if (num > 1400 && num <= 1500) {
return "rgba(250, 204, 93, 0.9)";
} else if (num > 1500 && num <= 1600) {
return "rgba(240, 139, 32, 0.9)";
} else if (num > 1600 && num <= 1700) {
return "rgba(241, 88, 26, 0.9)";
} else if (num > 1700 && num <= 1800) {
return "rgba(255, 0, 0, 0.9)";
} else if (num > 1800 && num <= 1900) {
return "rgba(182, 0, 0, 0.9)";
} else if (num > 1900) {
return "rgba(140, 0, 33, 0.9))";
}
}
// 窑炉内部svg变色
function BigSvg() {
return (
<svg
width="2050px"
height="700px"
style={{
position: "absolute",
top: "320px",
left: "1100px",
zIndex: 0,
}}
>
<defs>
<linearGradient id="Gradient" x1="0" x2="1" y1="0" y2="0">
<stop offset="0%" stopColor={returnColor2("TE302")} />
<stop offset="7%" stopColor={returnColor2("TE304")} />
<stop offset="14%" stopColor={returnColor2("TE306")} />
<stop offset="21%" stopColor={returnColor2("TE308")} />
<stop offset="28%" stopColor={returnColor2("TE309")} />
<stop offset="35%" stopColor={returnColor2("TE310")} />
<stop offset="42%" stopColor={returnColor2("TE312")} />
<stop offset="49%" stopColor={returnColor2("TE314")} />
<stop offset="56%" stopColor={returnColor2("TE315")} />
<stop offset="63%" stopColor={returnColor2("TE316")} />
<stop offset="70%" stopColor={returnColor2("TE318")} />
<stop offset="77%" stopColor={returnColor2("TE321")} />
<stop offset="84%" stopColor={returnColor2("TE331")} />
<stop offset="91%" stopColor={returnColor2("TE332")} />
<stop offset="100%" stopColor={returnColor2("TE332")} />
</linearGradient>
</defs>
<polygon
points="65 251,1515 251,1524 311,1640 311,1645 290,1609 90,1650 90,1650 95,1758 95,1760 107,1665 106,1658 130,1669 190,1865 190,1867 200,1685 200,1678 223,1693 313,1990 315,1992 325,1710 325,1703 347,1717 430,1910 430,1915 446,1731 445,1725 470,1738 544,1856 544,1860 562,1755 562,1752 572,1700 572,1655 340,1543 340,1534 360,1540 395,1080 397,1080 390,1024 390,1022 398,962 398,962 390,908 390,908 398,840 398,840 390,786 390,786 398,720 398,720 390,665 390,665 398,598 398,598 390,542 390,542 398,476 398,476 390,420 390,420 398,354 398,354 391,296 391,296 400,228 400,228 392,48 392"
fill="url(#Gradient)"
/>
</svg>
);
}
return (
<motion.div animate={speedAn}>
<BigSvg />
<B1
style={{
fill: returnColor("TE334"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "5px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B2
style={{
fill: returnColor("TE336"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "9px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B3
style={{
fill: returnColor("TE338"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "10px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B4
style={{
fill: returnColor("TE340"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "12px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B5
style={{
fill: returnColor("TE342"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "14px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B6
style={{
fill: returnColor("TE344"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "16px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B7
style={{
fill: returnColor("TE346"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "18px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B8
style={{
fill: returnColor("TE348"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "21px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T1
style={{
fill: returnColor("TE333"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "5px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T2
style={{
fill: returnColor("TE335"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "9px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T3
style={{
fill: returnColor("TE337"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "10px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T4
style={{
fill: returnColor("TE339"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "12px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T5
style={{
fill: returnColor("TE341"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "13px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T6
style={{
fill: returnColor("TE343"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "16px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T7
style={{
fill: returnColor("TE345"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "18px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T8
style={{
fill: returnColor("TE347"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "20px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
</motion.div>
);
};
export default BotttomColorBlock;

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path class="cls-2" d="M374,684.78c.67-3.25-.17-7.48,1.32-9.68,4.12-6.1,3.08-12.76,3.87-19.21,1.14-9.35,2-18.74,2.83-28.13.46-4.94.68-9.91,1.1-14.86.21-2.35,1.08-4,4-4,8,0,15.88-1.32,23.88-.92,10.47.52,20.87-1.41,31.37-1.09,3.77.12,4.88,1.19,4.72,4.88-.53,12.25-1.55,24.44-2.87,36.62-.32,3,0,6-.28,9-.24,2.31.05,5.21-3.43,5.73-.94.14-1.28.88-1.46,1.77-1.14,5.74-1.63,11.45-.05,17.23.63,2.29,1.68,3,3.93,2.46,5.1-1.14,10.29-.2,15.42-.55,2.83-.19,3.92,1,3.72,3.77-.44,6.11-.48,12.27-1.17,18.35-1.4,12.35-1.89,24.76-2.9,37.13-1.16,14.2-2.68,28.36-3.07,42.61-.11,4.35-1.77,6.43-7,6.29-17.64-.48-35.3-.23-52.94-.25-6.26-1.06-12.57-.31-18.85-.43-9.37-.19-12.74-3.23-12.56-12.59.27-14,2.08-27.79,4-41.61.36-2.63,1.12-5.23.95-7.9-.82-12.7,1.41-25.14,3.1-37.63C371.93,689.25,372.3,686.78,374,684.78Z" transform="translate(277 -158)"/><path class="cls-3" d="M374,684.78c-1,7.35-1.83,14.72-3,22-.48,3-1.14,5.84-.95,8.85,1,15-2.57,29.58-3.76,44.38-.61,7.58-1.82,15.14-1.25,22.8.33,4.37,4.69,7.93,10.3,8.07,5,.12,10,0,15,.05,1.6,0,3.37-.57,4.7.93-14.8,0-29.6,0-44.39.19-3.37,0-4.36-.41-3.87-4.41,1.81-15.11,2.94-30.29,4.34-45.45,1.68-18.12,3.4-36.23,5-54.36.21-2.45,1.31-3.05,3.49-3C364.37,684.9,369.19,684.81,374,684.78Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:#fefefe;}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M480.88,792.94c-3.83,0-7.66,0-11.49,0-2,0-3.19-.13-3-3,1.07-14.33,1.48-28.72,2.72-43,1.11-12.89,2.22-25.76,2.95-38.68.46-8.24,1.27-16.46,2-24.69.14-1.59.47-2,2.68-1.87a181.45,181.45,0,0,0,20.32-.36c1.22-.06,2.78-.14,3.16-2.66.67-4.4,1.28-8.55-.11-12.95-2.19-6.89.21-13.88.14-20.84-.06-6.66,1.64-13.34,1.64-20,0-6,1.56-11.78,1.16-17.74-.14-2,.76-3.13,2.89-3.14,8.5-.05,17-.08,25.49-.22,7.34-.12,14.71-.85,22-.41,4.39.27,8.82.39,13.14.24,3.78-.13,3.73,1.65,3.4,4-1.36,9.61-1.61,19.29-2,29-.3,7.76-.25,15.65-1.79,23.18-1.08,5.35-2.77,10.4-2.64,16.06.08,3.8.43,5.56,4.65,5.27s8.33.06,12.49-.11c2.45-.1,3.59.4,3.38,3.21-1.2,16.07-1.4,32.2-2.92,48.27-.92,9.67-.31,19.48-1.26,29.15-.93,9.47-.5,19-1.35,28.42-.16,1.75-1.07,1.94-2.43,2-9.27.23-18.54.51-27.81.72-6,.14-11.95.24-17.93.26Q505.64,793,480.88,792.94Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M688.32,678.37c6.48-1.08,13,.16,19.42-.34,1.14-.09,1.78.47,1.69,2.11-.34,5.79.05,11.64-.48,17.4-1.39,15-.26,30.1-1.71,45.12-.76,7.79-.07,15.7-.25,23.55s-.81,15.51-.89,23.26c0,3.15-1.9,2.46-3.58,2.46-16.33,0-32.66,0-49,0q-28.53,0-57,.16c-7.62,0-7.43.11-6.55-7.79.62-5.55.56-11.18.83-16.75.42-8.63,1-17.28,1.34-25.92.64-16.17,1.82-32.32,2.47-48.5.12-2.84.93-5.77.35-8.49-1.27-6,2.93-7,6.56-6.37,6.94,1.15,13.84-.2,20.71.67,1.72.22,1.85-.78,1.85-2.09a47.69,47.69,0,0,1,.65-10.39c.2-.92-.46-2.91-.91-3-5.09-.61-2.73-4.41-2.65-6.68.55-15.06.41-30.18,2.86-45.13a7.54,7.54,0,0,0-.17-1.47c-.37-9.21-.37-9.07,8.66-9.27,18.49-.4,37,.7,55.49-.37,2-.11,3.2.49,3.09,2.94-.71,16.32-.84,32.66-1.89,49C688.61,661,687,669.58,688.32,678.37Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M811.77,680c5.44,0,11,.23,16.42-.09,3.78-.22,5,.73,4.93,4.77-.21,26.57-.11,53.14-.11,79.71,0,7.49-.09,15,0,22.48.06,3-.88,4.18-4,4.15-12.62-.12-25.25-.17-37.87,0-8.65.11-17.3.82-26,.91-14.36.16-28.73-.25-43.08.21-5,.16-6-2.93-5.63-5.86.84-6,0-11.89.51-17.79,1.4-16,.48-32.14,1.79-48.2.83-10.23.17-20.57.19-30.86,0-9.47,0-9.24,9.15-8.88,5.28.22,10.57-.91,15.92-.23,2.79.35,4.43-.89,4-4.26-.37-2.95,0-6-.11-9-.08-1.69,1.13-4.1-2.33-4.33-1-.06-.61-2.05-.62-3.18-.2-17.65,1.65-35.27,1-52.93-.13-3.43,1.83-3.66,4.46-3.64,10.66.07,21.34.3,32-.06,8.42-.29,16.85.86,25.28-.69,1.7-.31,4.53.29,4.41,4.08-.6,18.58.32,37.18-.51,55.78C811.35,667.88,811.57,673.78,811.77,680Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M843,740.81q0-22.23,0-44.47c0-10.87,2.11-12.72,13.14-11.72,4.78.43,9.55-1,14.37,0,.89.2,1.52-1.36,1.51-2.65-.06-6.15,1.89-13.19-.44-18.28-4.35-9.47-.72-18.86-2.11-28.22a72.45,72.45,0,0,1,.19-21.69c.18-1.1.56-2.48.1-3.33-1.74-3.2.15-3.45,2.52-3.49,1,0,2,0,3,0,18.19-.06,36.39-.09,54.58-.22,2.19,0,3.08.42,3.2,2.89.7,13.84,1.45,27.68.85,41.51-.44,10.23,1.61,20.32,1.05,30.51-.13,2.24,1,2.33,2.69,2.31,4.33-.07,8.67.09,13-.07,2.46-.1,3.57.4,3.41,3.21a193,193,0,0,0,.27,28.67c1.52,16.25-.37,32.49,1.33,48.72a137.51,137.51,0,0,1,.37,20c-.17,4.23-1,6.62-6.36,6.55-25.32-.34-50.66-.3-76-.07-9,.08-18.1-.43-27.16.48-2.16.22-3.7-1-3.64-4.22C843.17,771.8,843,756.3,843,740.81Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M966,771.59c0-8.14-.48-16.25-.82-24.38-.6-13.94.17-27.94-.31-41.89-.24-7.24-.64-14.48-1-21.72-.18-4.27,1-6,5.52-5.73,7.48.37,15,0,22.49.15,3.54.08,4.3-1.95,3.9-4.62-1.5-10-1.66-20-1.94-30.11-.37-13.11-.87-26.21-1-39.33,0-3,.39-3.1,3.15-3.11q18.24-.06,36.48-.86c6-.27,12,1.1,18.07.12,2.19-.35,2.8,1.9,2.9,3.93.49,9.59,1.12,19.17,1.52,28.75.55,13.51.85,27,1.47,40.52.12,2.8,1,5.22,5.1,4.64s8.35-.18,12.53-.19c2.83,0,4.08,1.18,4,4.23-.47,13.4.72,26.78,1.3,40.13.36,8.46-.59,17.13,1.6,25.53.5,1.93,0,4-.09,6-.37,11,1,21.85,1.2,32.78.06,2.79-.67,3.55-3.53,3.59-12.86.18-25.7.55-38.58.06-9.55-.37-19.15.7-28.73.81-14.17.17-28.36,0-42.54.1-2.31,0-2.75-.84-2.71-2.9C966.08,782.59,966,777.09,966,771.59Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M1150.13,789.94c-15.52.45-34.88-.55-54.23.45-2.17.11-3.91-.9-4-3.81-.22-13.2-.23-26.43-1-39.61-1-16-1.51-32.05-2.15-48.08-.2-5-.3-10.19-.81-15.25-.33-3.28,1-3.82,3.92-3.74,7.49.2,15-.1,22.48.14,3.54.11,4.55-1.46,4.69-4.59a66,66,0,0,0-2-17.46c-1.54-6.78-.47-13.84-1.33-20.68-1.14-9-.41-18.11-1.62-27.14-1-7.47,0-8.5,7.3-8.08,14,.81,27.93-1.05,41.91.44,2.66.29,6.62-1.71,8.24.22s.8,5.62.94,8.55c.52,11.41.24,22.92,1.69,34.2,1.35,10.48-.14,21,1.56,31.41.51,3.2,1.82,3.47,4,3,4.32-.89,8.72.9,13.12-.68,1-.34,4.07,0,4.21,3.73.65,17.54,1.54,35.09,2.93,52.58,1.35,17.11,2.33,34.22,3.33,51.35.14,2.35-.69,3-4,3C1184.28,790,1169.12,789.94,1150.13,789.94Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M1261.82,604c9.2,0,18.42.29,27.61-.14,4-.19,5.26,1.62,5.5,4.78,1.09,14.09,2,28.21,3.06,42.31s2.12,28,3.54,42c.48,4.68.78,9.39,1.3,14.08,1.7,15.25,2.87,30.57,4.07,45.88.84,10.74,1.32,21.51,2.12,32.26.23,3.07-.71,3.87-3.82,3.89-8.89.06-17.77.79-26.66.86-20.14.14-40.29,0-60.43.11-3.19,0-4.15-1.65-4.07-4.1.21-5.8-.68-11.5-1-17.24-1.17-18.88-2.08-37.77-3.78-56.63-.82-9-1.88-18.08-1.3-27.21.12-2,.42-2.6,2.66-3a66.19,66.19,0,0,1,17.75-.73c5.59.57,7.29-2.14,7.6-6.75.27-4.05.41-9.56-1.38-11.76-4-4.87-2.48-10.09-3.42-15-1-5.36-.38-11-1.27-16.41-1.13-6.81-.2-13.74-1.8-20.52-1.29-5.5,0-6.66,5.77-6.66Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.75.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M417,240c17.2,0,34.41.12,51.61-.05,7.73-.08,15.47.23,23.21-.64,2.33-.26,5.77-.17,5.23,4.2-1.93,15.53-2.35,31.19-3.78,46.77-1,10.78-1.72,21.63-2.25,32.47-.49,9.79-1.8,19.51-2.21,29.32-.22,5.29-6.43,4.19-9,3.63-4.49-1-8.86,1.21-13.13-.56-1.19-.49-1.42.54-1.74,1.65-1.71,6-2,12.6.41,17.81,3,6.41,1,12.32,1.09,18.39.17,11.48-4.33,22.59-2.92,34.25.29,2.36-2.21,1.82-3.69,1.79-12.47-.24-24.93-1.51-37.41-.92-6.67.31-13.23-1.65-19.94-.63-1.66.26-2.73-1.11-2.5-3.25,1.73-16.17,3.48-32.34,5-48.54.56-6.17-2.43-12-2.88-18.05-.14-1.88-1.33-1.54-2.43-1.56-2,0-4,0-6,0-5.51,0-6.77-1.11-5.51-6.41s1.17-10.8,1.76-16.19c1.67-15.15,2.33-30.42,4.26-45.53,1.72-13.43,2.65-26.9,3.84-40.35.5-5.64,2-7.06,8.49-7.48H417Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M559,241.07c14.66,0,29.31,0,44,0,3,0,4.49-.27,4.37,4.25-.25,10-1.06,20-1.44,29.94-.8,20.66-2.55,41.28-3.78,61.92-.28,4.65-.11,9.32,0,14,0,3.32-1.27,4.52-4.69,4.07a74.81,74.81,0,0,0-9.48-.16c-6.53,0-6.64,0-6.81,6.83-.08,3.58.71,7.28.67,10.72-.08,7.64-.69,15.32-.91,23-.07,2.27-.89,4.56-.74,6.81.53,7.8-1.48,15.45-1.1,23.24.16,3.14-1.3,4.5-4.74,4.45-12.66-.19-25.33-.22-38,0-5.26.09-10.51.14-15.77,0-3.06-.07-3.8-.46-3.66-4,.28-7.22.67-14.43,1.21-21.64.64-8.43.87-16.94,2.26-25.25.44-2.63,1.7-5.48,2.42-8.29,1.21-4.67-.61-9.11-1.08-13.64-.13-1.24-1.06-2.88-3-2.24-4.79,1.52-9.72-1-14.67.69-1.43.49-4.57-.47-4.1-4.63,1.22-10.83,1.36-21.78,2.25-32.66q2.28-27.82,4.13-55.67c.31-4.75.65-9.5.87-14.27.27-5.93,2-7.43,7.94-7.44Q537,241.05,559,241.07Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.75.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M671.48,239.07c15.49,0,31,.08,46.48-.06,3.08,0,4.28.53,4.14,4-.68,16.69-1.16,33.38-1.55,50.08-.3,12.5.15,25-.74,37.49-.51,7.17-.63,14.31-.77,21.47,0,2.44-1.35,3.07-3.52,3-4.72-.06-9.45.17-14.17-.08-3-.16-3.18.91-3.32,3.65-.54,11,1.74,21.95,1,33-.69,10.29-1.29,20.59-1,30.91.06,1.95-.58,2.56-2.54,2.55q-20.44-.1-40.91,0c-5.52,0-11.05-.34-16.56.43-3.09.43-5.19.1-5.13-4.23.23-14.46.73-28.9,2.11-43.3.08-.82-.06-2.25.26-2.36,7.29-2.56,3.45-8.66,3.44-12.8,0-7.74-.71-7.45-8.57-7.48-5.08,0-10.13-.32-15.22.2-1.75.18-2.7-1.24-2.61-3.16.74-15,1.48-30,1.81-45s1.55-30,2.08-45c.22-6.39.68-12.81.87-19.23,0-1.53-1-3.05,2.71-3.37,16.41-1.44,32.81-.08,49.19-.64C669.81,239.05,670.65,239.07,671.48,239.07Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M744.69,244.07c21.59-.76,43.18.55,64.79-.41,8-.35,16.21.22,24.33.33,2.71,0,3.4.86,3.23,3.39-.54,8-.95,16.13-1.2,24.05-.28,8.9-.22,18.1-.26,27.07,0,10.6-.18,21.28-.53,31.92-.22,7-.26,14,.06,21,.15,3.38-1.16,3.78-4,3.64-4.16-.21-8.34.09-12.49-.11-2.65-.12-3.67.41-3.72,3.43-.34,20.73-1.19,41.45-.93,62.19.08,6.78,0,7.33-6.16,6.95-11.2-.69-22.37.33-33.58-.15a161,161,0,0,0-20.79.57c-2.82.24-3.42-1.9-3.26-3.09,1.37-9.73.53-19.49.81-29.23.16-5.8.31-11.6.51-17.4a2.9,2.9,0,0,1,.52-1.85c5.68-5.22,2-11.94,2.88-17.91.36-2.56-.86-3.69-3.78-3.54-5.86.29-11.74.07-17.62.08-2.85,0-4.43.34-3.84-4.21,1.07-8.3.15-16.84.36-25.28.49-19.18,1.18-38.34,1-57.53-.05-7,.77-14.08.85-21.12,0-2.67,1.11-3,3.26-2.86C738.35,244.17,741.52,244.07,744.69,244.07Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M930,379.68c0,14.68,1.5,29.32,1.06,44-.07,2.45-.46,3.43-3.23,3.41C909,427,890.14,427,871.3,427c-1.55,0-3.25.57-3.35-2.24-.58-15.57-3-31.06-2-46.71.15-2.34,0-4.43,3.31-4,2.23.26,1.71-1.51,1.72-2.71,0-4.33-.13-8.67.07-13,.13-2.58-.62-3.43-3.29-3.34-5.82.21-11.66-.06-17.49.11-3.25.1-4.21-1.12-4.35-4.35-.61-13.2.56-26.39,0-39.56-.54-12.73,0-25.45-.1-38.17-.11-10.06-.47-20.19.14-30.28.17-2.85.78-4.27,4.28-4.2,10.77.19,21.6.33,32.3,0,14.92-.44,29.83,0,44.74-.44,5.14-.16,10.32.29,15.44-.14,3.2-.28,3.83,1.93,3.87,3.62.35,14.83.45,29.66.54,44.49,0,7.38-.79,14.83,0,22.11,1.55,14.42.26,28.83,1,43.22.13,2.75-.71,3.52-3,3.64-.83,0-1.66,0-2.49,0-12.19.05-12.23,0-12.58,12.15C929.9,371.36,930,375.52,930,379.68Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.75.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M972.41,355c-4,0-8-.07-12,0-2.29.05-2.7-1.05-2.84-3.11-1.29-18.17-.09-36.39-1.23-54.58-.86-13.51-.36-27.11-.47-40.66a131.73,131.73,0,0,0-.75-16.49c-.45-3.42-.23-6.2,5-6.33,11-.25,21.89.19,32.84.18,15.53,0,31.06.18,46.58-.11,5.49-.1,11,0,16.43-.17,3.29-.13,2.88,1.07,3.06,3.07,1.31,15,1.78,30.09,2.23,45.16.45,15.27.85,30.55,1.88,45.79.52,7.73.75,15.43.91,23.16.06,3-1,4.32-4,4.1-2.32-.17-4.66,0-7,0-6.12,0-8.13,1.79-8,7.86.41,16.09,1,32.17,1.55,48.25,0,1.22-.78,2.2-.43,3.61,1.62,6.6-.76,9.46-7.28,8.14-7-1.41-13.93-.75-20.87-.74-8.28,0-16.55,1.16-24.82-.07-2.39-.35-6,3.3-6.88-1.14-.42-2.19-2.88-4.8-.51-7.43.24-.27-.29-1.7-.83-2.12-5.69-4.45-3-11-3.09-16.16-.09-7.37-.38-14.71-.82-22.07-.12-2-.62-4.67,3.05-3.15a.72.72,0,0,0,.5,0c1.54-.69,3.85-1.16,2.49-3.54-2.06-3.59,4.1-9.71-3.22-11.3C980.21,354.39,976.24,355,972.41,355Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.75.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M1080.55,225.08c15.33,0,30.65,0,46,0,13.13,0,26.25-.68,39.39-.07,2.93.13,4.16.91,4.12,4-.15,12.67,1.79,25.31,1.6,37.89-.22,15.8,1.33,31.48,1.61,47.23.21,12,1.25,24,1.87,36,.15,3,.7,5.07-4.31,4.71-3.66-.26-7.77-1.48-11.65,0-1.05.41-2,.18-2.24,1.86a52.16,52.16,0,0,0,.29,17.94c1.12,6.34.85,12.7,1.63,19,1,8,.81,16.16,1.16,24.24a8.09,8.09,0,0,0,.39,2.9c1.7,3.69-.67,3.28-3,3.29-7.44,0-14.88.26-22.31.29q-14,.07-27.93-.06c-1.85,0-2.16-1.34-2.17-3.06-.09-8.73-.66-17.47-1.22-26.15-.5-7.77-.5-15.51-.74-23.25-.12-4,.44-8,.43-12,0-6.78-4.37-5-7.54-5.17-6.45-.24-12.94.06-19.4.29-2.43.09-2.65-1.15-3-3.13-1.18-7-.15-14.05-.7-21.06-1.1-14.09-1.22-28.25-2-42.36-.64-12.23-1.25-24.46-1.93-36.69-.43-7.77-1.08-15.52-1-23.33,0-2.91.92-3.69,3.66-3.48C1074.54,225.25,1077.55,225.08,1080.55,225.08Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M960,921.91q-616.2,0-1232.41.09c-3.74,0-4.59-.84-4.59-4.59q.15-377.42,0-754.82c0-3.74.84-4.59,4.59-4.59q1232.42.15,2464.82,0c3.74,0,4.59.84,4.59,4.59q-.15,377.42,0,754.82c0,3.74-.84,4.59-4.59,4.59Q1576.21,921.85,960,921.91Z" transform="translate(277 -158)"/><path d="M1249,426c-9.66,0-19.32-.11-29,.05-3.4.06-4.7-.66-5.19-4.56-1.21-9.43-1.53-18.93-2.46-28.38-.85-8.61-1-17.44,1-26.16.78-3.33-.18-7.06-.34-10.61-.09-2-1.61-1.28-2.59-1.31-6.8-.2-13.65-.92-20.37-.27-4.56.44-4.94-2.66-4.86-4.79.33-8.89-1-17.68-1.41-26.5-.76-15.51-1.84-31-3-46.52-1.06-14.83-2.63-29.62-2.83-44.51-.08-6.39-.14-6.39,6.33-6.39,26.63,0,53.26.08,79.89-.09,4.16,0,5.2,1.13,5.39,5.31.81,17.84,2.49,35.62,3.51,53.45,1.17,20.41,3.3,40.76,4.8,61.15.24,3.29.53,6.57-1.67,10-3,4.58-2.39,11.58.16,14.67,6.59,8,3.45,16.69,4.6,25,1.23,8.95,1.66,18,2,27,.13,2.87-.79,3.59-3.58,3.54C1269.29,425.93,1259.13,426,1249,426Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,100 @@
import * as echarts from "echarts";
export default function getOptions(seriesData,pieces,range,yName) {
return {
grid: { top: 38, right: 44, bottom: 20, left: 48 },
xAxis: {
type: "category",
data: Array(7)
.fill(1)
.map((_, index) => {
const today = new Date();
const dtimestamp = today - (index+1) * 24 * 60 * 60 * 1000;
return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
dtimestamp
).getDate()}`;
})
.reverse(),
axisLabel: {
color: "#fff",
fontSize: 12,
},
axisTick: { show: false },
axisLine: {
lineStyle: {
width: 1,
color: "#213259",
},
},
},
yAxis: {
name: "单位: "+yName,
nameTextStyle: {
color: "#fff",
fontSize: 10,
align: "right",
},
type: "value",
axisLabel: {
color: "#fff",
fontSize: 12,
formatter: "{value}",
},
axisLine: {
show: true,
lineStyle: {
color: "#213259",
},
},
splitLine: {
lineStyle: {
color: "#213259a0",
},
},
min:range[0],
max:range[1]
},
visualMap: {
show: false,
dimension: 1,
pieces: pieces
},
series: [
{
type: 'line',
label: {
show: true,
position: 'top',
color:'inherit'
},
symbol: 'circle',
symbolSize: 6,
// prettier-ignore
data: seriesData.data,
markLine: {
symbol: 'none',
label:{
show:true,
position:'end',
formatter:'标准线',
color:'#FFCB59',
fontSize: 12,
},
lineStyle:{
color:'#FFCB59'
},
data: seriesData.markLineData
},
areaStyle: seriesData.areaStyle
}
],
tooltip: {
trigger: "axis",
axisPointer: {
type: 'cross'
},
className: "xc-chart-tooltip",
// backgroundColor: ''
},
};
}

View File

@@ -0,0 +1,93 @@
import cls from "./index.module.css";
import ReactECharts from "echarts-for-react";
import getOptions from "./chart.config";
import * as echarts from "echarts";
import { useEffect, useState } from "react";
function CommonChart(props) {
const { dataSource } = props;
const data = dataSource.data || [];
const yName = dataSource.yName;
let seriesData = {
data: data,
markLineData: [
{ name: "标准线1", yAxis: dataSource.msg ? dataSource.msg.lte : 0 },
{ name: "标准线2", yAxis: dataSource.msg ? dataSource.msg.gt : 0 },
],
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: dataSource.areaColor0,
},
{
offset: 1,
color: dataSource.areaColor1,
},
]),
origin: "start",
},
};
let pieces = [
{
lte: dataSource.msg ? dataSource.msg.lte : 0,
color: "#FFCB59",
},
{
gt: dataSource.msg ? dataSource.msg.lte : 0,
lte: dataSource.msg ? dataSource.msg.gt : 0,
color: dataSource.color,
},
{
gt: dataSource.msg ? dataSource.msg.gt : 0,
color: "#FFCB59",
},
];
const [yRange, setYRange] = useState([]);
useEffect(() => {
if (data.length > 0) {
var standardValue = dataSource.msg.sp;
var maxY = (standardValue * 100 + dataSource.range[1] * 100) / 100;
var minY = (standardValue * 100 + dataSource.range[0] * 100) / 100;
// 计算最大最小值是否超标
const maxValue = Math.max(...data);
const minValue = Math.min(...data);
if (maxValue > maxY) {
maxY = Math.ceil(maxValue);
}
if (minValue < minY) {
minY = Math.floor(minValue);
}
setYRange([minY, maxY]);
}
}, [dataSource, data]);
return (
<div className={cls.commonChart}>
{data.length > 0 && (
<ReactECharts
option={getOptions(seriesData, pieces, yRange, yName)}
style={{ height: "100%" }}
/>
)}
{data.length <= 0 && (
<p
style={{
paddingTop: "88px",
color: "#fffc",
textAlign: "center",
fontSize: "24px",
userSelect: "none",
}}
>
暂无数据
</p>
)}
</div>
);
}
export default CommonChart;

View File

@@ -0,0 +1,3 @@
.commonChart {
height: 100%;
}

View File

@@ -0,0 +1,38 @@
// 窑炉压力
import cls from "./index.module.css";
import BottomBarItem from "./../../../../../components/Common/BottomItemBackground";
import CommonChart from "./../CommonChart"
import { useSelector } from "react-redux";
function KilnBottom(props) {
const kilnOptimize = useSelector((state) => state.kilnOptimize);
const dataSource = {
color:'#146CFF',
yName:'℃',
areaColor0:'rgba(20, 108, 255, 0.4)',
areaColor1:'rgba(20, 108, 255, 0)',
msg: kilnOptimize.bottomTempAvg,
data: kilnOptimize.bottomTempAvg ? kilnOptimize.bottomTempAvg.bottomTempAvgFor7Day : [],
range:[-10,10]
}
return (
<BottomBarItem
icon="kilnBottom"
title="池底温度趋势图"
style={props.style}
>
{/* legend */}
<div className={cls.legend}>
<span className={cls.item}>
<span className={cls.block} style={{backgroundColor:'#FFCB59'}}></span>标准值外
</span>
<span className={cls.item}>
<span className={cls.block} style={{backgroundColor:'#146CFF'}}></span>标准值内
</span>
</div>
<div className={cls.chart}>
<CommonChart dataSource={dataSource}/>
</div>
</BottomBarItem>
)
}
export default KilnBottom;

View File

@@ -0,0 +1,21 @@
.chart {
height: 100%;
}
.legend {
position: absolute;
right: 25px;
top: 30px;
}
.item{
display: inline-block;
margin-right: 10px;
font-size: 11px;
color: #DFF1FE;
}
.block {
width: 8px;
height: 8px;
border-radius: 2px;
display: inline-block;
margin-right: 4px;
}

View File

@@ -0,0 +1,44 @@
// 窑炉压力
import cls from "./index.module.css";
import BottomBarItem from "./../../../../../components/Common/BottomItemBackground";
import CommonChart from "./../CommonChart";
import { useSelector } from "react-redux";
function KilnPress(props) {
const kilnOptimize = useSelector((state) => state.kilnOptimize);
const dataSource = {
color: "#12FFF5",
yName: "Pa",
areaColor0: "rgba(18, 255, 245, 0.4)",
areaColor1: "rgba(18, 255, 245, 0)",
msg: kilnOptimize.pressureAvg,
data: kilnOptimize.pressureAvg
? kilnOptimize.pressureAvg.pressureAvgFor7Day
: [],
range: [-4, 4],
};
return (
<BottomBarItem icon="kilnPress" title="窑压趋势图" style={props.style}>
{/* legend */}
<div className={cls.legend}>
<span className={cls.item}>
<span
className={cls.block}
style={{ backgroundColor: "#FFCB59" }}
></span>
标准值外
</span>
<span className={cls.item}>
<span
className={cls.block}
style={{ backgroundColor: "#12FFF5" }}
></span>
标准值内
</span>
</div>
<div className={cls.chart}>
<CommonChart dataSource={dataSource} />
</div>
</BottomBarItem>
);
}
export default KilnPress;

View File

@@ -0,0 +1,21 @@
.chart {
height: 100%;
}
.legend {
position: absolute;
right: 25px;
top: 30px;
}
.item{
display: inline-block;
margin-right: 10px;
font-size: 11px;
color: #DFF1FE;
}
.block {
width: 8px;
height: 8px;
border-radius: 2px;
display: inline-block;
margin-right: 4px;
}

View File

@@ -0,0 +1,38 @@
// 窑炉压力
import cls from "./index.module.css";
import BottomBarItem from "./../../../../../components/Common/BottomItemBackground";
import CommonChart from "./../CommonChart"
import { useSelector } from "react-redux";
function KilnTop(props) {
const kilnOptimize = useSelector((state) => state.kilnOptimize);
const dataSource = {
color:'#12FFF5',
yName:'℃',
areaColor0:'rgba(18, 255, 245, 0.4)',
areaColor1:'rgba(18, 255, 245, 0)',
msg:kilnOptimize.topTempAvg,
data:kilnOptimize.topTempAvg ? kilnOptimize.topTempAvg.topTempAvgFor7Day : [],
range:[-10,10]
}
return (
<BottomBarItem
icon="kilnTop"
title="碹顶温度趋势图"
style={props.style}
>
{/* legend */}
<div className={cls.legend}>
<span className={cls.item}>
<span className={cls.block} style={{backgroundColor:'#FFCB59'}}></span>标准值外
</span>
<span className={cls.item}>
<span className={cls.block} style={{backgroundColor:'#12FFF5'}}></span>标准值内
</span>
</div>
<div className={cls.chart}>
<CommonChart dataSource={dataSource}/>
</div>
</BottomBarItem>
)
}
export default KilnTop;

View File

@@ -0,0 +1,21 @@
.chart {
height: 100%;
}
.legend {
position: absolute;
right: 25px;
top: 30px;
}
.item{
display: inline-block;
margin-right: 10px;
font-size: 11px;
color: #DFF1FE;
}
.block {
width: 8px;
height: 8px;
border-radius: 2px;
display: inline-block;
margin-right: 4px;
}

View File

@@ -0,0 +1,45 @@
import { motion } from "framer-motion";
import { useEffect, useState } from "react";
import image from "./../../../../../assets/kilnSpeed.png";
function LiquidSpeedColor(props) {
const speed = props.speed;
const floor = props.floor;
const [speedAn, setSpeedAn] = useState({});
useEffect(() => {
// 23互切不用展示动画
if (speed === "f") {
setSpeedAn({});
} else {
if (floor === 3) {
setSpeedAn({
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 1.5 },
});
} else {
setSpeedAn({});
}
}
}, [floor]);
console.log(speedAn);
console.log("speedAnspeedAnspeedAnspeedAnspeedAnspeedAnspeedAn");
return (
<motion.div
style={{
position: "absolute",
top: "242px",
left: "445px",
zIndex: 999,
}}
animate={speedAn}
>
<img
src={image}
alt=""
width="100%"
height="100%"
style={{ transform: "scale(0.583, 0.593)" }}
/>
</motion.div>
);
}
export default LiquidSpeedColor;

View File

@@ -0,0 +1,38 @@
// 窑炉压力
import cls from "./index.module.css";
import BottomBarItem from "./../../../../../components/Common/BottomItemBackground";
import CommonChart from "./../CommonChart"
import { useSelector } from "react-redux";
function LiquidTrend(props) {
const kilnOptimize = useSelector((state) => state.kilnOptimize);
const dataSource = {
color:'#146CFF',
yName:'mm',
areaColor0:'rgba(20, 108, 255, 0.4)',
areaColor1:'rgba(20, 108, 255, 0)',
msg:kilnOptimize.liquidAvg,
data:kilnOptimize.liquidAvg ? kilnOptimize.liquidAvg.liquidAvgFor7Day : [],
range:[-1,1]
}
return (
<BottomBarItem
icon="liquidTrend"
title="液位趋势图"
style={props.style}
>
{/* legend */}
<div className={cls.legend}>
<span className={cls.item}>
<span className={cls.block} style={{backgroundColor:'#FFCB59'}}></span>标准值外
</span>
<span className={cls.item}>
<span className={cls.block} style={{backgroundColor:'#146CFF'}}></span>标准值内
</span>
</div>
<div className={cls.chart}>
<CommonChart dataSource={dataSource}/>
</div>
</BottomBarItem>
)
}
export default LiquidTrend;

View File

@@ -0,0 +1,21 @@
.chart {
height: 100%;
}
.legend {
position: absolute;
right: 25px;
top: 30px;
}
.item{
display: inline-block;
margin-right: 10px;
font-size: 11px;
color: #DFF1FE;
}
.block {
width: 8px;
height: 8px;
border-radius: 2px;
display: inline-block;
margin-right: 4px;
}

View File

@@ -0,0 +1,362 @@
import { useSelector } from "react-redux";
import React from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ReactComponent as B1 } from "./pic/b1.svg";
import { ReactComponent as B2 } from "./pic/b2.svg";
import { ReactComponent as B3 } from "./pic/b3.svg";
import { ReactComponent as B4 } from "./pic/b4.svg";
import { ReactComponent as B5 } from "./pic/b5.svg";
import { ReactComponent as B6 } from "./pic/b6.svg";
import { ReactComponent as B7 } from "./pic/b7.svg";
import { ReactComponent as B8 } from "./pic/b8.svg";
import { ReactComponent as T1 } from "./pic/t1.svg";
import { ReactComponent as T2 } from "./pic/t2.svg";
import { ReactComponent as T3 } from "./pic/t3.svg";
import { ReactComponent as T4 } from "./pic/t4.svg";
import { ReactComponent as T5 } from "./pic/t5.svg";
import { ReactComponent as T6 } from "./pic/t6.svg";
import { ReactComponent as T7 } from "./pic/t7.svg";
import { ReactComponent as T8 } from "./pic/t8.svg";
const TopColorBlock = ({ condition }) => {
const tempTop = useSelector((state) => state.temperature.top);
function returnColor(n) {
let num = Number(tempTop[n].slice(0, tempTop[n].length - 1));
if (num <= 100) {
return "rgba(96, 0, 189, 0.7)";
} else if (num > 100 && num <= 200) {
return "rgba(102, 7, 255, 0.7)";
} else if (num > 200 && num <= 300) {
return "rgba(10, 20, 255, 0.7)";
} else if (num > 300 && num <= 400) {
return "rgba(7, 89, 255, 0.7)";
} else if (num > 400 && num <= 500) {
return "rgba(7, 139, 255, 0.7)";
} else if (num > 500 && num <= 600) {
return "rgba(7, 194, 255, 0.7)";
} else if (num > 600 && num <= 700) {
return "rgba(7, 255, 253, 0.7)";
} else if (num > 700 && num <= 800) {
return "rgba(7, 255, 205, 0.7)";
} else if (num > 800 && num <= 900) {
return "rgba(20, 237, 127, 0.7)";
} else if (num > 900 && num <= 1000) {
return "rgba(0, 193, 39, 0.7)";
} else if (num > 1000 && num <= 1100) {
return "rgba(147, 210, 1, 0.7)";
} else if (num > 1100 && num <= 1200) {
return "rgba(206, 206, 0, 0.7)";
} else if (num > 1200 && num <= 1300) {
return "rgba(255, 226, 13, 0.7)";
} else if (num > 1300 && num <= 1400) {
return "rgba(249, 240, 146, 0.7)";
} else if (num > 1400 && num <= 1500) {
return "rgba(250, 204, 93, 0.7)";
} else if (num > 1500 && num <= 1600) {
return "rgba(240, 139, 32, 0.7)";
} else if (num > 1600 && num <= 1700) {
return "rgba(241, 88, 26, 0.7)";
} else if (num > 1700 && num <= 1800) {
return "rgba(255, 0, 0, 0.7)";
} else if (num > 1800 && num <= 1900) {
return "rgba(182, 0, 0, 0.7)";
} else if (num > 1900) {
return "rgba(140, 0, 33, 0.7)";
}
}
function returnColor2(n) {
let num = Number(tempTop[n].slice(0, tempTop[n].length - 1));
if (num <= 100) {
return "rgba(96, 0, 189, 0.9)";
} else if (num > 100 && num <= 200) {
return "rgba(102, 7, 255, 0.9)";
} else if (num > 200 && num <= 300) {
return "rgba(10, 20, 255, 0.9)";
} else if (num > 300 && num <= 400) {
return "rgba(7, 89, 255, 0.9)";
} else if (num > 400 && num <= 500) {
return "rgba(7, 139, 255, 0.9)";
} else if (num > 500 && num <= 600) {
return "rgba(7, 194, 255, 0.9)";
} else if (num > 600 && num <= 700) {
return "rgba(7, 255, 253, 0.9)";
} else if (num > 700 && num <= 800) {
return "rgba(7, 255, 205, 0.9)";
} else if (num > 800 && num <= 900) {
return "rgba(20, 237, 127, 0.9)";
} else if (num > 900 && num <= 1000) {
return "rgba(0, 193, 39, 0.9)";
} else if (num > 1000 && num <= 1100) {
return "rgba(147, 210, 1, 0.9)";
} else if (num > 1100 && num <= 1200) {
return "rgba(206, 206, 0, 0.9)";
} else if (num > 1200 && num <= 1300) {
return "rgba(255, 226, 13, 0.9)";
} else if (num > 1300 && num <= 1400) {
return "rgba(249, 240, 146, 0.9)";
} else if (num > 1400 && num <= 1500) {
return "rgba(250, 204, 93, 0.9)";
} else if (num > 1500 && num <= 1600) {
return "rgba(240, 139, 32, 0.9)";
} else if (num > 1600 && num <= 1700) {
return "rgba(241, 88, 26, 0.9)";
} else if (num > 1700 && num <= 1800) {
return "rgba(255, 0, 0, 0.9)";
} else if (num > 1800 && num <= 1900) {
return "rgba(182, 0, 0, 0.9)";
} else if (num > 1900) {
return "rgba(140, 0, 33, 0.9))";
}
}
// 窑炉内部svg变色
function BigSvg() {
return (
<svg
width="2050px"
height="700px"
style={{
position: "absolute",
top: "320px",
left: "1080px",
zIndex: 0,
}}
>
<defs>
<linearGradient id="Gradient1" x1="0" x2="1" y1="0" y2="0">
<stop offset="0%" stopColor={returnColor2("TE201")} />
<stop offset="9%" stopColor={returnColor2("TE202")} />
<stop offset="18%" stopColor={returnColor2("TE203")} />
<stop offset="27%" stopColor={returnColor2("TE204")} />
<stop offset="36%" stopColor={returnColor2("TE205")} />
<stop offset="45%" stopColor={returnColor2("TE206")} />
<stop offset="54%" stopColor={returnColor2("TE208")} />
<stop offset="63%" stopColor={returnColor2("TE210")} />
<stop offset="72%" stopColor={returnColor2("TE211")} />
<stop offset="81%" stopColor={returnColor2("TE212")} />
<stop offset="90%" stopColor={returnColor2("TE213")} />
<stop offset="100%" stopColor={returnColor2("TE213")} />
</linearGradient>
<linearGradient id="Gradient2" x1="0" x2="1" y1="0" y2="0">
<stop offset="0%" stopColor={returnColor2("TE216")} />
<stop offset="33%" stopColor={returnColor2("TE221")} />
<stop offset="66%" stopColor={returnColor2("TE225")} />
<stop offset="100%" stopColor={returnColor2("TE225")} />
</linearGradient>
</defs>
<polygon
points="27 238,1535 238,1543 310,1555 310,1558 351,1551 361,1555 420,1076 421,1076 423,1020 423,1020 421,958 421,958 423,900 423,900 421,832 421,775 423,775 421,200 425,193 399,12 400"
fill="url(#Gradient1)"
/>
<polygon
points="1585 308,1655 308,1670 290,1640 50,1688 50,1688 58,1800 58,1804 93,1692 93,1700 168,1900 168,1906 201,1706 200,1718 312,2024 311,2029 343,1724 344,1736 445,1940 444,1946 478,1740 478,1753 573,1874 573, 1878 608,1710 608,1678 349,1668 360,1590 360"
fill="url(#Gradient2)"
/>
</svg>
);
}
return (
<motion.div
animate={{
opacity: [0, 0, 0, 0.6, 1],
transition: { duration: 0.3, delay: 1.5 },
}}
>
<BigSvg />
<B1
style={{
fill: returnColor("TE228"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "5px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B2
style={{
fill: returnColor("TE230"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "7px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B3
style={{
fill: returnColor("TE232"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "10px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B4
style={{
fill: returnColor("TE234"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "12px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B5
style={{
fill: returnColor("TE236"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "14px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B6
style={{
fill: returnColor("TE238"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "16px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B7
style={{
fill: returnColor("TE240"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "18px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<B8
style={{
fill: returnColor("TE242"),
width: "100%",
height: "100%",
position: "absolute",
top: "120px",
left: "19px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T1
style={{
fill: returnColor("TE227"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "5px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T2
style={{
fill: returnColor("TE229"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "9px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T3
style={{
fill: returnColor("TE231"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "10px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T4
style={{
fill: returnColor("TE233"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "12px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T5
style={{
fill: returnColor("TE235"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "13px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T6
style={{
fill: returnColor("TE237"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "16px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T7
style={{
fill: returnColor("TE239"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "18px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
<T8
style={{
fill: returnColor("TE241"),
width: "100%",
height: "100%",
position: "absolute",
top: "114px",
left: "19px",
zIndex: 0,
transform: "scale(0.7)",
}}
/>
</motion.div>
);
};
export default TopColorBlock;

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M2197,922H-277V158H2197ZM421.92,703.81c-2.21-.15-4-.39-5.76-.37-26.5.16-53,.46-79.48.44-4.48,0-5.5,1.52-5.71,5.7-.59,11.58-.8,11.57-12.2,11.61-1,0-2,.09-3,0-2.63-.22-3.4,1.09-3.54,3.56-.57,10-1.28,19.93-2,29.9-1.54,22.09-3.13,44.17-4.65,66.26-.56,8.08-1,16.16-1.46,24.91h6.08l60-.14c13.16,0,26.33-.19,39.49,0,3.89,0,5.23-1.25,5.21-5.17,0-5.82.55-11.64.86-17.46q1.85-34.66,3.69-69.34C420.3,737.36,421.07,721.06,421.92,703.81Z" transform="translate(277 -158)"/><path d="M421.92,703.81c-.85,17.25-1.62,33.55-2.46,49.84q-1.8,34.67-3.69,69.34c-.31,5.82-.9,11.64-.86,17.46,0,3.92-1.32,5.21-5.21,5.17-13.16-.14-26.33,0-39.49,0l-60,.14h-6.08c.5-8.75.9-16.83,1.46-24.91,1.52-22.09,3.11-44.17,4.65-66.26.7-10,1.41-19.93,2-29.9.14-2.47.91-3.78,3.54-3.56,1,.09,2,0,3,0,11.4,0,11.61,0,12.2-11.61.21-4.18,1.23-5.71,5.71-5.7,26.49,0,53-.28,79.48-.44C417.93,703.42,419.71,703.66,421.92,703.81Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2474 764"><defs><style>.cls-1{fill:rgba(255,255,255,0);}.cls-2{fill:#none;}</style></defs><path class="cls-1" d="M2197,922H-277V158H2197ZM544.59,703.38q-53.33,0-106.49,0c-2.87,0-3.72,1.28-3.8,3.94-.17,5.65-.58,11.3-.87,17-2,38.74-3.87,77.48-5.95,116.21-.21,3.84,1.08,5,4.69,5q51.72-.4,103.43-.61c2.88,0,4.18-.76,4.23-3.91.1-7.15.55-14.3.85-21.46,1.31-30.6,2.68-61.21,3.86-91.82C544.85,719.69,544.59,711.75,544.59,703.38Z" transform="translate(277 -158)"/><path d="M544.59,703.38c0,8.37.26,16.31-.05,24.24-1.18,30.61-2.55,61.22-3.86,91.82-.3,7.16-.75,14.31-.85,21.46-.05,3.15-1.35,3.89-4.23,3.91q-51.71.2-103.43.61c-3.61,0-4.9-1.14-4.69-5,2.08-38.73,4-77.47,5.95-116.21.29-5.65.7-11.3.87-17,.08-2.66.93-3.94,3.8-3.94Q491.3,703.43,544.59,703.38Z" transform="translate(277 -158)"/></svg>

After

Width:  |  Height:  |  Size: 872 B

Some files were not shown because too many files have changed in this diff Show More