diff --git a/src/constants/factory.js b/src/constants/factory.js index 4cc16d16..3dbc057c 100644 --- a/src/constants/factory.js +++ b/src/constants/factory.js @@ -1,6 +1,3 @@ -import imageBack1 from '../images/factory/back1.png' -import imageBack2 from '../images/factory/back2.png' -import imageBack3 from '../images/factory/back3.png' export const factoryZoneId = 102 export const dirId = 9 diff --git a/src/factory/components/Resource/index.jsx b/src/factory/components/Resource/index.jsx index 314d9d2f..d6aaa632 100644 --- a/src/factory/components/Resource/index.jsx +++ b/src/factory/components/Resource/index.jsx @@ -13,7 +13,7 @@ gsap.registerPlugin(ScrollTrigger); const resourceInfo = [ { name: '项目', title: '软件项目', icon: 'icon-xiangmu', desc: '汇聚用户需求,形成开发任务,设置质量门槛,提升软件质量,快速构建软件版本,高效应对市场变化。', path: '/softwareFactory/resource/softwareProject' }, - { name: '版本', title: '工厂版本', icon: 'icon-banben', desc: '按照敏捷开发快速迭代的思路,形成解决微小问题的小版本,提供长期支持版本(LTS版)。', path: '/softwareFactory/resource/factoryVersion' }, + { name: '版本', title: '软件工厂基座', icon: 'icon-banben', desc: '按照敏捷开发快速迭代的思路,形成解决微小问题的小版本,提供长期支持版本(LTS版)。', path: '/softwareFactory/resource/factoryVersion' }, { name: '工具', title: '开发工具', icon: 'icon-gongju', desc: '提供开发者所需的各类软件开发工具,包括IDE、Git工具、命令行终端工具、数据库设计工具、图像编辑工具等。', path: '/softwareFactory/resource/developmentTools' }, ] @@ -156,12 +156,14 @@ const Resource = forwardRef(({ zoneId }, ref) => { { resourceList1 && resourceList1.length > 0 && resourceList1.map((item, index) => { const { projectProperties } = item; + let imageUrl = projectProperties.authorImageUrl.split(':4000/') && projectProperties.authorImageUrl.split(':4000/')[1] + const authorImageUrl = imageUrl ? `${window.location.origin}/${ imageUrl }` : projectProperties.authorImageUrl // projectProperties.praisesCount = Math.floor(Math.random(0, 1) * 50) // projectProperties.forkedCount = Math.floor(Math.random(0, 1) * 50) const tags = projectProperties.topics && projectProperties.topics.split(','); return
- +
{projectProperties.name.split('/')[1]}
{ diff --git a/src/factory/components/Resource/index.scss b/src/factory/components/Resource/index.scss index 18bd9159..6ed43556 100644 --- a/src/factory/components/Resource/index.scss +++ b/src/factory/components/Resource/index.scss @@ -245,6 +245,7 @@ display: flex; justify-content: center; align-items: center; + flex-shrink: 0; } h3 { diff --git a/src/factory/components/Resource2/index.jsx b/src/factory/components/Resource2/index.jsx index c8c09d2b..330aaaa0 100644 --- a/src/factory/components/Resource2/index.jsx +++ b/src/factory/components/Resource2/index.jsx @@ -4,17 +4,17 @@ import lessonsRight1 from '../../../images/factory/lessons-right-1.webp' import { Link } from 'react-router-dom'; import KFIcon from '../../../components/KFIcon'; import back1 from '../../../images/factory/back1.png' -import back2 from '../../../images/factory/back2.png' import tagIcon from '../../../images/factory/lessons-tag-icon.webp' import '../../common.scss' import { getSourceList } from '../../api' -import { factoryZoneId, manualId, standardId } from '../../../constants/factory' +import { factoryZoneId, manualId, standardId, lessonId } from '../../../constants/factory' import { downloadFunc } from '../../../forge/Utils/utils' const Resource2 = forwardRef(({ zoneId }, ref) => { const [isVisible, setIsVisible] = useState(false); const [standard, setStandard] = useState({}); const [manualList, setManualList] = useState([]); + const [chapterList, setChapterList] = useState([]); useEffect(() => { const observer = new IntersectionObserver((entries) => { @@ -25,7 +25,7 @@ const Resource2 = forwardRef(({ zoneId }, ref) => { }, { threshold: 0.1 }); getStandard() getManualList() - + getLessonList() if (ref.current) { observer.observe(ref.current); @@ -61,6 +61,35 @@ const Resource2 = forwardRef(({ zoneId }, ref) => { }); } + const getLessonList = () => { + getSourceList({ id: factoryZoneId, keywords: lessonId }).then(res => { + const rows = [] + res.data.rows.forEach(e => { + let extendData = {} + if (e.extendData) { + extendData = JSON.parse(e.extendData) + } + rows.push({ ...e, extendDataUrl: extendData.url, extendDataHeadImg: extendData.headImg }) + }); + // setLesson(rows[0]); + getChapterList(rows[0].name) + }); + }; + + const getChapterList = (id) => { + getSourceList({ id: factoryZoneId, keywords: id }).then(res => { + const rows = [] + res.data.rows.forEach(e => { + let extendData = {} + if (e.extendData) { + extendData = JSON.parse(e.extendData) + } + rows.push({ ...e, extendDataUrl: extendData.url, extendDataHeadImg: extendData.headImg }) + }); + setChapterList(rows); + }); + }; + return (
{

在线课程

全景智治贯通需求到交付,敏捷可视管控风险,打造高效可信软件生产新范式,赋能研发跃迁

-
- -
-

Numpy科学计算

-

本AI核心通识课课程是一门全面且深入的入门课程,旨在为学生提供一个从基础到高级的全方位...

- -
-
-
- -
-

探索数据类型

-

本AI核心通识课课程是一门全面且深入的入门课程,旨在为学生提供一个从基础到高级的全方位...

- -
-
+ { + chapterList.slice(0,2).map((item, index) => { + return
+ +
+

{ item.name }

+

{item.summary}

+ +
+
+ }) + }
diff --git a/src/factory/index.jsx b/src/factory/index.jsx index 8acab641..56aaa4f0 100644 --- a/src/factory/index.jsx +++ b/src/factory/index.jsx @@ -13,23 +13,34 @@ import { factoryZoneId } from '../constants/factory'; import bg1 from '../images/factory/bg-1.mov' import bg2 from '../images/factory/bg-2.mp4' import mouse from '../images/factory/mouse.png' - +import DelayedScroll from '../forge/Utils/delayScroll' gsap.registerPlugin(ScrollTrigger); const bannerInfo = { - title: `软件工厂,开启XX软件研发新时代`, + title: `软件工厂,开启xx软件研发新时代`, desc: '软件开发过程数字化,软件开发活动智能化,软件开发链路敏捷化', - link: '/' + link: '/', + forums: 'forums', + forumsName: '软件工厂' } +let delayScroll + function Index(props) { const contentRef = useRef(null); + const bannerRef = useRef(null); const resourceRef = useRef(null); const resource2Ref = useRef(null); const [isVisible, setIsVisible] = useState(false); + const [banner2isVisible, setBanner2IsVisible] = useState(false); const [firstV, setFirstV] = useState(true) + const isAnimating = useRef(false) + const lastScrollY = useRef(false) + const firstScreenRef = useRef(false) + const ticking = useRef(false) useEffect(() => { + delayScroll = new DelayedScroll() const observer = new IntersectionObserver((entries) => { const entry = entries[0]; // 如果元素进入视口 @@ -46,8 +57,27 @@ function Index(props) { observer.observe(contentRef.current); } + const observer2 = new IntersectionObserver((entries) => { + const entry = entries[0]; + if (entry.isIntersecting) { + setBanner2IsVisible(true); + observer2.disconnect(); + } + }, { + threshold: 0.1 + }); + + if (bannerRef.current) { + observer2.observe(bannerRef.current); + } + + setupScrollListeners() + return () => { if (contentRef.current) observer.disconnect(); + if (bannerRef.current) observer2.disconnect(); + if (delayScroll) delayScroll.cleanup() + window.removeEventListener('scroll', helpScroll) }; }, []); @@ -77,24 +107,108 @@ function Index(props) { }; }, [resourceRef, resource2Ref]); + const setupScrollListeners = () => { + window.addEventListener('scroll', helpScroll); + // 检测第一屏是否离开 + // const observer = new IntersectionObserver( + // (entries) => { + // entries.forEach(entry => { + // if (!entry.isIntersecting) { + // // 第一屏离开视口,禁用snap + // // this.disableSnap(); + // // this.isFirstScreenActive = false; + // } + // }); + // }, + // { + // threshold: 0.1, + // rootMargin: '0px' + // } + // ); + // observer.observe(firstScreenRef.current); + } + + const helpScroll = () => { + if (!ticking.current) { + requestAnimationFrame(() => { + handleScroll(); + ticking.current = false; + }); + ticking.current = true; + } + + } + + const scrollToNextSection = () => { + if (isAnimating.current) return; + isAnimating.current = true; + const targetScroll = window.innerHeight; + // 平滑滚动 + window.scrollTo({ + top: targetScroll, + behavior: 'smooth' + }); + + // 滚动完成后标记 + setTimeout(() => { + isAnimating.current = false; + }, 800); + } + + const scrollToTop = () => { + if (isAnimating.current) return; + isAnimating.current = true; + window.scrollTo({ + top: 0, + behavior: 'smooth' + }); + setTimeout(() => { + isAnimating.current = false; + }, 800); + } + + const handleScroll = () => { + const currentScrollY = window.scrollY; + const firstScreenHeight = window.innerHeight; + // if (this.isFirstScreenActive) { + if (currentScrollY > 50 && currentScrollY < firstScreenHeight && currentScrollY > lastScrollY.current) { + scrollToNextSection(); + } + if ( currentScrollY < firstScreenHeight - 50 && currentScrollY < lastScrollY.current) { + scrollToTop() + } + // } + lastScrollY.current = currentScrollY; + + } + return (
- - +
+ + +
-

{bannerInfo.title}

-

{bannerInfo.desc}

- -
立即体验
- -
+

{bannerInfo.title}

+

{bannerInfo.desc}

+ +
+ +
立即体验
+ + +
论坛交流
+ +
+
{ scrollToNextSection() }}>
- +
下滑了解更多
+
{/*
{ bannerData.map(e => { @@ -108,10 +222,10 @@ function Index(props) { }
*/}
-
-

软件工厂 宣传视频

+ {/*
+

软件工厂 精彩呈现

-
+
*/} diff --git a/src/factory/index.scss b/src/factory/index.scss index d4491ef1..8fe4a0eb 100644 --- a/src/factory/index.scss +++ b/src/factory/index.scss @@ -11,6 +11,7 @@ align-items: center; height: 100vh; overflow: hidden; + background-color: #000316; // background-image: url("../images/factory/banner1.png"); // background-size: cover; @@ -18,6 +19,11 @@ // background-repeat: no-repeat; // background-position: top center; // /* 可选:将图片居中显示 */ + + .video-wpapper { + width: 100%; + } + &-video { width: 100%; display: none; @@ -35,6 +41,12 @@ align-items: center; height: 40vh; + .h-wrapper { + --delay-factor: 0.45; + transition: transform 0.1s ease-out; + transform: translateY(calc(var(--scroll-delay) * 1px)) !important; + } + h1 { line-height: normal; font-family: "DouyinSansBold"; @@ -49,6 +61,13 @@ letter-spacing: 10px; } + .p-wrapper { + --delay-factor: 0.5; + transition: transform 0.1s ease-out; + transform: translateY(calc(var(--scroll-delay) * 1px)) !important; + } + + p { opacity: 0; color: #ffffffd3; @@ -61,7 +80,36 @@ animation-delay: 2s; } + .b-wrapper { + --delay-factor: 0.5; + transition: transform 0.2s ease-out !important; + transform: translateY(calc(var(--scroll-delay) * 1px)) !important; + display: flex; + + a:nth-child(2) { + div { + background: url('../images/factory/header-button.png'); + background-repeat: no-repeat; + background-size: 100% 100%; + margin-right: 0; + &::after { + opacity: 0; + } + &::before { + opacity: 0; + } + } + + } + } + + a { + margin-top: 50px; + + } + &-button { + margin-right: 50px; opacity: 0; width: 230px; height: 64px; @@ -75,11 +123,11 @@ text-align: center; overflow: hidden; line-height: 58px; - margin-top: 50px; animation: fadeInUp 2s ease-in-out forwards; animation-delay: 2s; &::before { + z-index: 1; content: ''; opacity: 0.9; width: 138px; @@ -93,6 +141,7 @@ } &::after { + z-index: 1; content: ''; width: 138px; position: absolute; @@ -113,12 +162,16 @@ flex-direction: column; align-items: center; padding-bottom: 20px; - animation: mouseShow 1s forwards; + animation: mouseShow 1s forwards; animation-delay: 4s; + --delay-factor: 0.05; + transition: transform 0.3s ease-out; + transform: translateY(calc(var(--scroll-delay) * 1px)) !important; div { position: relative; - &::after { + + &::after { content: ""; width: 3px; height: 8px; @@ -126,7 +179,7 @@ position: absolute; top: 8px; left: 50%; - transform: translate(-50%,0); + transform: translate(-50%, 0); animation: mouse 1.5s ease-out infinite; } } @@ -145,6 +198,18 @@ margin-top: 10px; } } + + } + + .banner-2 { + height: 100vh; + width: 100%; + position: absolute; + top: 100vh; + } + + .hide { + opacity: 0 !important; } .banner-data { @@ -297,6 +362,7 @@ 50% { top: 8px } + to { top: 16px; } diff --git a/src/factory/resource/components/Search/index.jsx b/src/factory/resource/components/Search/index.jsx index 12f7666a..a6e6a239 100644 --- a/src/factory/resource/components/Search/index.jsx +++ b/src/factory/resource/components/Search/index.jsx @@ -76,12 +76,12 @@ function Index({searchValue, searchType},ref) { { projectList.map((item, index) => { const project = item.projectProperties || {} - project.praisesCount = 3 - project.forkedCount = 3 + let imageUrl = project.authorImageUrl.split(':4000/') && project.authorImageUrl.split(':4000/')[1] + const authorImageUrl = imageUrl ? `${window.location.origin}/${ imageUrl }` : project.authorImageUrl return
- +
{project.name}
@@ -98,13 +98,8 @@ function Index({searchValue, searchType},ref) {
- - { - project.praisesCount > 0 && {project.praisesCount} - } - { - project.forkedCount > 0 && {project.forkedCount} - } + {project.forkedCount} + {project.praisesCount}
@@ -155,7 +150,7 @@ function Index({searchValue, searchType},ref) { { versionList.length > 0 &&
-

工厂版本

+

软件工厂基座

#版本 {versionTotal}个
diff --git a/src/factory/resource/developmentTools/detail/index.jsx b/src/factory/resource/developmentTools/detail/index.jsx index e862e62b..019d45a4 100644 --- a/src/factory/resource/developmentTools/detail/index.jsx +++ b/src/factory/resource/developmentTools/detail/index.jsx @@ -85,7 +85,7 @@ function Index(props) { 工具类型
- +
更多热门工具
{ diff --git a/src/factory/resource/index.jsx b/src/factory/resource/index.jsx index c22ee1cb..7c46e3e8 100644 --- a/src/factory/resource/index.jsx +++ b/src/factory/resource/index.jsx @@ -31,7 +31,7 @@ const DevelopmentTools = Loadable({ const zoneId = 199 const typeMap = [ - { name: '工厂版本', key: 'factoryVersion', icon: 'icon-gongchangbanben' }, + { name: '软件工厂基座', key: 'factoryVersion', icon: 'icon-gongchangbanben' }, { name: '软件项目', key:'softwareProject', icon: 'icon-ruanjianxiangmu' }, { name: '开发工具', key: 'developmentTools', icon: 'icon-kaifagongju' }, ] diff --git a/src/factory/resource/softwareProject/index.jsx b/src/factory/resource/softwareProject/index.jsx index e470ee00..45d12a35 100644 --- a/src/factory/resource/softwareProject/index.jsx +++ b/src/factory/resource/softwareProject/index.jsx @@ -6,7 +6,7 @@ import KFIcon from '../../../components/KFIcon'; import bg1 from '../../../images/factory/resource/project-top-1.webp'; import bg2 from '../../../images/factory/resource/project-top-2.webp'; -import bg3 from '../../../images/factory/resource/project-top-3.png'; +import bg3 from '../../../images/factory/resource/project-top-3.webp'; import bg4 from '../../../images/factory/resource/project-content-1.webp'; import bg5 from '../../../images/factory/resource/project-content-2.webp'; @@ -74,12 +74,14 @@ function Index(props) { { topList.map((item, index) => { const project = item.projectProperties + let imageUrl = project.authorImageUrl.split(':4000/') && project.authorImageUrl.split(':4000/')[1] + const authorImageUrl = imageUrl ? `${window.location.origin}/${imageUrl}` : project.authorImageUrl // project.praisesCount = Math.floor(Math.random(0, 1) * 50) // project.forkedCount = Math.floor(Math.random(0, 1) * 50) return (
- +
{project.name.split('/')[1]}

{project.description}

@@ -92,8 +94,8 @@ function Index(props) { ) }) } */} - - 捐赠者
{ project.name.split('/')[0] } + + 捐赠者
{project.name.split('/')[0]}
{project.forkedCount} @@ -117,12 +119,14 @@ function Index(props) { { contentList.map((item, index) => { const project = item.projectProperties + let imageUrl = project.authorImageUrl.split(':4000/') && project.authorImageUrl.split(':4000/')[1] + const authorImageUrl = imageUrl ? `${window.location.origin}/${imageUrl}` : project.authorImageUrl // project.praisesCount = Math.floor(Math.random(0, 1) * 50) // project.forkedCount = Math.floor(Math.random(0, 1) * 50) return
- +
{project.name.split('/')[1]}
@@ -133,8 +137,8 @@ function Index(props) { ) }) } */} - - 捐赠者
{ project.name.split('/')[0] } + + 捐赠者
{project.name.split('/')[0]}
{project.description} @@ -161,6 +165,8 @@ function Index(props) { { fullList.map((item, index) => { const project = item.projectProperties + let imageUrl = project.authorImageUrl.split(':4000/') && project.authorImageUrl.split(':4000/')[1] + const authorImageUrl = imageUrl ? `${window.location.origin}/${imageUrl}` : project.authorImageUrl // project.praisesCount = Math.floor(Math.random(0, 1) * 50) // project.forkedCount = Math.floor(Math.random(0, 1) * 50) return @@ -173,19 +179,21 @@ function Index(props) {
{project.name.split('/')[1]}
-
- {!project.description ? '暂无简介' : project.description} -
-
- { +
+ {/* { project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => { return ( {topic} ) }) - } + } */} + + 捐赠者
{project.name.split('/')[0]}
+
+ {!project.description ? '暂无简介' : project.description} +
{project.forkedCount} {project.praisesCount} diff --git a/src/factory/resource/softwareProject/index.scss b/src/factory/resource/softwareProject/index.scss index b70f766c..c5631383 100644 --- a/src/factory/resource/softwareProject/index.scss +++ b/src/factory/resource/softwareProject/index.scss @@ -317,10 +317,10 @@ .item-bg { position: absolute; - width: 420px; - height: 219px; - left: 0; - top: 0; + width: 416px; + height: 215px; + left: 2px; + top: 2px; z-index: -1; } @@ -447,27 +447,59 @@ .item-desc { -webkit-line-clamp: 2; - margin-top: 26px; + margin-top: 16px; } - .item-tags { - margin-top: auto; + .item-bottom-tags { display: flex; justify-content: flex-start; + align-items: center; + margin-top: 20px; + width: fit-content; + background: rgba(179, 190, 252, 0.18); + border: 1px solid; + border-color: #ffffff; + border-radius: 4px; + height: 32px; + padding: 5px 9px; + line-height: 22px; + font-family: alibabareg; + color: #091221; + font-size: 13px; - .item-tag { - display: inline-block; - padding: 0 8px; - margin-right: 8px; - height: 32px; - background: rgba(22, 76, 228, 0.05); - border-radius: 4px; - line-height: 32px; - font-family: alibabareg; - color: #091221; - font-size: 14px; + img { + width: 15px; + margin-right: 5px; + height: 15px; + } + + div { + width: 6px; + height: 6px; + background: #ffffff; + border-radius: 50%; + margin: 0 6px; } } + + // .item-tags { + // margin-top: auto; + // display: flex; + // justify-content: flex-start; + + // .item-tag { + // display: inline-block; + // padding: 0 8px; + // margin-right: 8px; + // height: 32px; + // background: rgba(22, 76, 228, 0.05); + // border-radius: 4px; + // line-height: 32px; + // font-family: alibabareg; + // color: #091221; + // font-size: 14px; + // } + // } } .content-bottom-btn { diff --git a/src/forge/Utils/delayScroll.js b/src/forge/Utils/delayScroll.js new file mode 100644 index 00000000..3a1dfad4 --- /dev/null +++ b/src/forge/Utils/delayScroll.js @@ -0,0 +1,76 @@ +/** + * 延迟滚动 + * 延迟滚动元素class:delayed-element + * 延迟滚动元素css属性(用于设定延迟多少):--scroll-delay + */ +class DelayedScroll { + constructor() { + this.initialized = false; + this.maxScroll = window.innerHeight; // 最多监听2屏的高度 + this.init(); + } + + init() { + if (this.initialized) return; + + let ticking = false; + + const handleScroll = () => { + if (!ticking) { + requestAnimationFrame(() => { + const scrollY = window.scrollY; + + // 只在首屏范围内应用效果 + if (scrollY <= this.maxScroll) { + this.updateElements(scrollY); + } else { + // 超出范围时停止监听 + window.removeEventListener('scroll', scrollHandler); + this.cleanup(); + } + + ticking = false; + }); + ticking = true; + } + }; + + // 使用节流的滚动监听 + const scrollHandler = () => { + if (window.scrollY <= this.maxScroll) { + handleScroll(); + } + }; + + window.addEventListener('scroll', scrollHandler, { passive: true }); + + // 初始执行一次 + this.updateElements(window.scrollY); + + this.initialized = true; + } + + updateElements(scrollY) { + document.querySelectorAll('.delayed-element').forEach(element => { + const delayFactor = this.getDelayFactor(element); + const delay = scrollY * delayFactor; + element.style.setProperty('--scroll-delay', delay); + }); + } + + getDelayFactor(element) { + return parseFloat( + getComputedStyle(element).getPropertyValue('--delay-factor') || 0.2 + ); + } + + cleanup() { + // 可选:移除transform,恢复原状 + document.querySelectorAll('.delayed-element').forEach(element => { + element.style.removeProperty('--scroll-delay'); + element.style.removeProperty('transform'); + }); + } +} + +export default DelayedScroll \ No newline at end of file diff --git a/src/images/factory/header-button.png b/src/images/factory/header-button.png new file mode 100644 index 00000000..fc9ac21b Binary files /dev/null and b/src/images/factory/header-button.png differ diff --git a/src/images/factory/resource/123.webp b/src/images/factory/resource/123.webp new file mode 100644 index 00000000..5838cb43 Binary files /dev/null and b/src/images/factory/resource/123.webp differ diff --git a/src/images/factory/resource/project-content-3.webp b/src/images/factory/resource/project-content-3.webp index 7a176987..98f99a05 100644 Binary files a/src/images/factory/resource/project-content-3.webp and b/src/images/factory/resource/project-content-3.webp differ diff --git a/src/images/factory/resource/project-content-4.webp b/src/images/factory/resource/project-content-4.webp index 443c6034..3467d413 100644 Binary files a/src/images/factory/resource/project-content-4.webp and b/src/images/factory/resource/project-content-4.webp differ diff --git a/src/images/factory/resource/project-top-1.webp b/src/images/factory/resource/project-top-1.webp index bb5e29ef..422c0272 100644 Binary files a/src/images/factory/resource/project-top-1.webp and b/src/images/factory/resource/project-top-1.webp differ diff --git a/src/images/factory/resource/project-top-2.webp b/src/images/factory/resource/project-top-2.webp index 2c80236d..e889c119 100644 Binary files a/src/images/factory/resource/project-top-2.webp and b/src/images/factory/resource/project-top-2.webp differ diff --git a/src/images/factory/resource/project-top-3.png b/src/images/factory/resource/project-top-3.png deleted file mode 100644 index 85c9a6fb..00000000 Binary files a/src/images/factory/resource/project-top-3.png and /dev/null differ diff --git a/src/images/factory/resource/project-top-3.webp b/src/images/factory/resource/project-top-3.webp new file mode 100644 index 00000000..08b25e23 Binary files /dev/null and b/src/images/factory/resource/project-top-3.webp differ diff --git a/src/images/factory/resource/tools-new-1.webp b/src/images/factory/resource/tools-new-1.webp index 9246231a..05ac7b55 100644 Binary files a/src/images/factory/resource/tools-new-1.webp and b/src/images/factory/resource/tools-new-1.webp differ diff --git a/src/images/factory/resource/tools-new-2.webp b/src/images/factory/resource/tools-new-2.webp index 5838cb43..4174227f 100644 Binary files a/src/images/factory/resource/tools-new-2.webp and b/src/images/factory/resource/tools-new-2.webp differ