diff --git a/assets/css/timeline.css b/assets/css/timeline.css new file mode 100644 index 0000000..3796550 --- /dev/null +++ b/assets/css/timeline.css @@ -0,0 +1,431 @@ +/* ============================================ + 智慧时间轴组件 - 横向展开式 + Smart Timeline Component - Horizontal Expansion + ============================================ */ + +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&family=Oswald:wght@400;700&display=swap'); + +:root { + --tl-bg-color: #f8fafc; + --tl-line-color: rgba(20, 129, 255, 0.3); + --tl-active-color: #1481ff; + --tl-text-color: #2a3e5d; + --tl-year-color: #102541; + --tl-transition-speed: 0.5s; +} + +/* Section 容器 */ +.timeline-section { + width: 100%; + background-image: + radial-gradient(circle at 10% 20%, rgba(20, 129, 255, 0.08) 0%, transparent 20%), + radial-gradient(circle at 90% 80%, rgba(20, 129, 255, 0.05) 0%, transparent 20%); + font-family: 'Noto Sans SC', sans-serif; + overflow: hidden; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 60px 0; + position: relative; +} + +/* 标题样式 */ +.timeline-title { + color: var(--tl-year-color); + letter-spacing: 4px; + font-weight: 300; + text-transform: uppercase; + font-size: 24px; + opacity: 0.9; + margin-bottom: 40px; + text-align: center; +} + +/* 主容器 */ +.timeline-container { + display: flex; + width: 100%; + height: 20vh; + min-height: 500px; + align-items: center; + position: relative; +} + +/* 主轴线 */ +.timeline-line { + position: absolute; + top: 66.67%; + left: 0; + width: 100%; + height: 1px; + background: linear-gradient(90deg, + transparent 0%, + var(--tl-line-color) 5%, + var(--tl-line-color) 95%, + transparent 100%); + z-index: 0; + pointer-events: none; +} + +/* 时间节点 */ +.timeline-item { + position: relative; + height: 100%; + flex: 1; + transition: flex var(--tl-transition-speed) cubic-bezier(0.25, 0.1, 0.25, 1); + border-right: 1px solid rgba(20, 129, 255, 0.1); + cursor: pointer; + overflow: hidden; + display: flex; + flex-direction: column; + justify-content: center; + z-index: 1; +} + +.timeline-item:last-child { + border-right: none; +} + +.timeline-item:hover { + flex: 10; + background: linear-gradient(90deg, rgba(20, 129, 255, 0.08) 0%, transparent 100%); +} + +.timeline-container:hover .timeline-item:not(:hover) { + opacity: 0.4; +} + +/* 节点圆点 */ +.dot { + width: 8px; + height: 8px; + background-color: var(--tl-active-color); + border-radius: 50%; + position: absolute; + top: 66.67%; + left: 50%; + transform: translate(-50%, -50%); + box-shadow: 0 0 10px var(--tl-active-color); + transition: all var(--tl-transition-speed); + z-index: 2; +} + +.timeline-item:hover .dot { + background-color: var(--tl-active-color); + transform: translate(-50%, -50%) scale(1.5); + box-shadow: 0 0 20px rgba(20, 129, 255, 0.6); +} + +/* 竖向年份标签 */ +.year-label { + position: absolute; + top: calc(66.67% + 15px); + left: 50%; + transform-origin: 0 0; + transform: rotate(90deg); + + font-family: 'Oswald', sans-serif; + font-size: 14px; + color: var(--tl-year-color); + white-space: nowrap; + transition: all 0.3s; + letter-spacing: 1px; + opacity: 0.8; + + display: flex; + align-items: center; + gap: 12px; + pointer-events: none; +} + +/* 竖向文字中的简短描述 */ +.short-desc { + font-family: 'Noto Sans SC', sans-serif; + font-size: 12px; + opacity: 0.6; + font-weight: 300; + letter-spacing: 1px; +} + +/* Hover 状态下:标签变大并移到底部背景 */ +.timeline-item:hover .year-label { + top: auto; + bottom: -10px; + left: 20px; + transform: rotate(0deg); + font-size: 4rem; + font-weight: 700; + opacity: 0.08; + color: var(--tl-active-color); + pointer-events: none; +} + +/* Hover时隐藏简述 */ +.timeline-item:hover .short-desc { + display: none; +} + +/* 内容区域 - 固定在时间轴线上方 */ +.content { + opacity: 0; + transform: translateY(20px); + transition: all 0.4s ease 0.1s; + padding: 0 40px; + color: var(--tl-text-color); + position: absolute; + + bottom: 36%; + left: 0; + width: 100%; + + text-align: left; + pointer-events: none; + + display: flex; + flex-direction: column; + justify-content: flex-end; +} + +.timeline-item:hover .content { + opacity: 1; + transform: translateY(0); +} + +.content-date { + display: block; + color: var(--tl-active-color); + font-family: 'Oswald', sans-serif; + font-size: 2rem; + margin-bottom: 15px; + font-weight: bold; + text-shadow: 0 0 20px rgba(20, 129, 255, 0.2); +} + +.content-text { + font-size: 1.1rem; + line-height: 1.8; + border-left: 3px solid var(--tl-active-color); + padding-left: 20px; + max-width: 650px; + background: linear-gradient(90deg, rgba(20, 129, 255, 0.08) 0%, transparent 100%); + padding-top: 10px; + padding-bottom: 10px; + border-radius: 0 4px 4px 0; +} + +.content-text p { + margin: 0 0 8px 0; +} + +.content-text p:last-child { + margin-bottom: 0; +} + +/* 重要节点高亮 */ +.timeline-item.highlight .dot { + width: 10px; + height: 10px; + box-shadow: 0 0 15px var(--tl-active-color), 0 0 30px var(--tl-active-color); +} + +.timeline-item.highlight .year-label { + color: var(--tl-active-color); + opacity: 1; +} + +/* ============================================ + 自动轮播展开效果(与hover效果一致) + ============================================ */ +.timeline-item.auto-expanded { + flex: 10; + background: linear-gradient(90deg, rgba(20, 129, 255, 0.08) 0%, transparent 100%); +} + +.timeline-container:has(.auto-expanded) .timeline-item:not(.auto-expanded) { + opacity: 0.4; +} + +.timeline-item.auto-expanded .dot { + background-color: var(--tl-active-color); + transform: translate(-50%, -50%) scale(1.5); + box-shadow: 0 0 20px rgba(20, 129, 255, 0.6); +} + +.timeline-item.auto-expanded .year-label { + top: auto; + bottom: -10px; + left: 20px; + transform: rotate(0deg); + font-size: 4rem; + font-weight: 700; + opacity: 0.08; + color: var(--tl-active-color); + pointer-events: none; +} + +.timeline-item.auto-expanded .short-desc { + display: none; +} + +.timeline-item.auto-expanded .content { + opacity: 1; + transform: translateY(0); +} + +/* ============================================ + 响应式设计 + ============================================ */ +@media (max-width: 1200px) { + .timeline-container { + width: 100%; + height: 20vh; + min-height: 500px; + } + + .year-label { + font-size: 12px; + top: calc(66.67% + 15px); + } + + .short-desc { + font-size: 10px; + } + + .content-text { + font-size: 1rem; + max-width: 500px; + } + + .content-date { + font-size: 1.6rem; + } +} + +@media (max-width: 991px) { + .timeline-section { + padding: 40px 0; + min-height: auto; + height: auto; + } + + .timeline-container { + width: 100%; + height: 20vh; + min-height: 500px; + overflow-x: auto; + overflow-y: visible; + -webkit-overflow-scrolling: touch; + } + + .timeline-item { + min-width: 80px; + flex: none; + } + + .timeline-item:hover { + flex: none; + min-width: 350px; + } + + .content { + padding: 0 20px; + } + + .content-text { + font-size: 0.9rem; + max-width: 300px; + } +} + +@media (max-width: 768px) { + .timeline-title { + font-size: 18px; + letter-spacing: 2px; + margin-bottom: 30px; + } + + .timeline-container { + height: 70vh; + } + + .timeline-item { + min-width: 60px; + } + + .timeline-item:hover { + min-width: 280px; + } + + .year-label { + font-size: 11px; + } + + .short-desc { + font-size: 9px; + display: none; + } + + .content { + padding: 0 15px; + } + + .content-date { + font-size: 1.4rem; + margin-bottom: 10px; + } + + .content-text { + font-size: 0.85rem; + padding-left: 15px; + max-width: 250px; + } + + .dot { + width: 6px; + height: 6px; + } +} + +@media (max-width: 576px) { + .timeline-section { + padding: 30px 0; + } + + .timeline-title { + font-size: 16px; + letter-spacing: 1px; + } + + .timeline-container { + height: 60vh; + } + + .timeline-item { + min-width: 50px; + } + + .timeline-item:hover { + min-width: 220px; + } + + .year-label { + font-size: 10px; + top: calc(66.67% + 12px); + } + + .content-date { + font-size: 1.2rem; + } + + .content-text { + font-size: 0.8rem; + line-height: 1.6; + } + + .timeline-item:hover .year-label { + font-size: 2.5rem; + bottom: -30px; + left: 10px; + } +} diff --git a/assets/images/project/ecommerce/bctp.png b/assets/images/project/ecommerce/bctp.png index ea09bce..d2a0924 100644 Binary files a/assets/images/project/ecommerce/bctp.png and b/assets/images/project/ecommerce/bctp.png differ diff --git a/assets/images/project/ecommerce/booking.png b/assets/images/project/ecommerce/booking.png index 8359a56..e8926d2 100644 Binary files a/assets/images/project/ecommerce/booking.png and b/assets/images/project/ecommerce/booking.png differ diff --git a/assets/images/project/ecommerce/cargo.png b/assets/images/project/ecommerce/cargo.png index 019fa66..103f332 100644 Binary files a/assets/images/project/ecommerce/cargo.png and b/assets/images/project/ecommerce/cargo.png differ diff --git a/assets/images/project/ecommerce/obh.png b/assets/images/project/ecommerce/obh.png index a572d64..698f0ac 100644 Binary files a/assets/images/project/ecommerce/obh.png and b/assets/images/project/ecommerce/obh.png differ diff --git a/assets/images/project/port/bulk.png b/assets/images/project/port/bulk.png index f5d415b..120b6ff 100644 Binary files a/assets/images/project/port/bulk.png and b/assets/images/project/port/bulk.png differ diff --git a/assets/images/project/port/cdi.png b/assets/images/project/port/cdi.png index 0e95941..cadf760 100644 Binary files a/assets/images/project/port/cdi.png and b/assets/images/project/port/cdi.png differ diff --git a/assets/images/project/port/cdi2.png b/assets/images/project/port/cdi2.png new file mode 100644 index 0000000..3c84b44 Binary files /dev/null and b/assets/images/project/port/cdi2.png differ diff --git a/assets/images/project/product_full_logistics_chain_platform/car_management.png b/assets/images/project/product_full_logistics_chain_platform/car_management.png index dc06677..f2c6fbb 100644 Binary files a/assets/images/project/product_full_logistics_chain_platform/car_management.png and b/assets/images/project/product_full_logistics_chain_platform/car_management.png differ diff --git a/assets/images/project/product_full_logistics_chain_platform/cargo_agent.png b/assets/images/project/product_full_logistics_chain_platform/cargo_agent.png index 18eda44..8f5e8ac 100644 Binary files a/assets/images/project/product_full_logistics_chain_platform/cargo_agent.png and b/assets/images/project/product_full_logistics_chain_platform/cargo_agent.png differ diff --git a/assets/images/project/product_full_logistics_chain_platform/platform.png b/assets/images/project/product_full_logistics_chain_platform/platform.png index addcc40..aee1f21 100644 Binary files a/assets/images/project/product_full_logistics_chain_platform/platform.png and b/assets/images/project/product_full_logistics_chain_platform/platform.png differ diff --git a/assets/images/project/product_full_logistics_chain_platform/ship_agent.png b/assets/images/project/product_full_logistics_chain_platform/ship_agent.png index a5eae87..ca61182 100644 Binary files a/assets/images/project/product_full_logistics_chain_platform/ship_agent.png and b/assets/images/project/product_full_logistics_chain_platform/ship_agent.png differ diff --git a/assets/images/project/product_full_logistics_chain_platform/warehouse.png b/assets/images/project/product_full_logistics_chain_platform/warehouse.png index 5382747..4e9597f 100644 Binary files a/assets/images/project/product_full_logistics_chain_platform/warehouse.png and b/assets/images/project/product_full_logistics_chain_platform/warehouse.png differ diff --git a/assets/images/project/shipping/boat.png b/assets/images/project/shipping/boat.png index 3a33b93..f9e7a0c 100644 Binary files a/assets/images/project/shipping/boat.png and b/assets/images/project/shipping/boat.png differ diff --git a/assets/images/project/shipping/company.png b/assets/images/project/shipping/company.png index 2afd929..1cf3671 100644 Binary files a/assets/images/project/shipping/company.png and b/assets/images/project/shipping/company.png differ diff --git a/assets/js/timeline.js b/assets/js/timeline.js new file mode 100644 index 0000000..43a423c --- /dev/null +++ b/assets/js/timeline.js @@ -0,0 +1,252 @@ +/** + * 智慧时间轴组件 - 横向展开式 + * Smart Timeline Component - Horizontal Expansion + */ + +(function() { + 'use strict'; + + // 等待DOM加载完成 + document.addEventListener('DOMContentLoaded', initTimeline); + + function initTimeline() { + const container = document.querySelector('.timeline-container'); + if (!container) return; + + const items = container.querySelectorAll('.timeline-item'); + if (!items.length) return; + + // 入场动画 - 使用 Intersection Observer + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + animateItems(); + observer.unobserve(entry.target); + } + }); + }, observerOptions); + + observer.observe(container); + + // 节点逐个入场动画 + function animateItems() { + items.forEach((item, index) => { + setTimeout(() => { + item.style.opacity = '1'; + item.style.transform = 'translateY(0)'; + }, index * 80); + }); + } + + // 初始化节点样式(用于动画) + items.forEach(item => { + item.style.opacity = '0'; + item.style.transform = 'translateY(20px)'; + item.style.transition = 'opacity 0.5s ease, transform 0.5s ease, flex 0.5s cubic-bezier(0.25, 0.1, 0.25, 1), background 0.5s ease'; + }); + + // 触摸设备支持 + let touchStartX = null; + let scrollLeft = null; + + container.addEventListener('touchstart', (e) => { + touchStartX = e.touches[0].pageX; + scrollLeft = container.scrollLeft; + }, { passive: true }); + + container.addEventListener('touchmove', (e) => { + if (!touchStartX) return; + const x = e.touches[0].pageX; + const walk = (touchStartX - x) * 1.5; + container.scrollLeft = scrollLeft + walk; + }, { passive: true }); + + container.addEventListener('touchend', () => { + touchStartX = null; + }); + + // 鼠标滚轮横向滚动(移动端视图时) + container.addEventListener('wheel', (e) => { + if (container.scrollWidth > container.clientWidth) { + if (Math.abs(e.deltaX) < Math.abs(e.deltaY)) { + e.preventDefault(); + container.scrollLeft += e.deltaY; + } + } + }, { passive: false }); + + // 拖拽滚动(移动端视图时) + let isDragging = false; + let startX; + let dragScrollLeft; + + container.addEventListener('mousedown', (e) => { + if (container.scrollWidth <= container.clientWidth) return; + if (e.target.closest('.timeline-item')) return; + isDragging = true; + container.style.cursor = 'grabbing'; + startX = e.pageX - container.offsetLeft; + dragScrollLeft = container.scrollLeft; + }); + + container.addEventListener('mouseleave', () => { + isDragging = false; + container.style.cursor = ''; + }); + + container.addEventListener('mouseup', () => { + isDragging = false; + container.style.cursor = ''; + }); + + container.addEventListener('mousemove', (e) => { + if (!isDragging) return; + e.preventDefault(); + const x = e.pageX - container.offsetLeft; + const walk = (x - startX) * 2; + container.scrollLeft = dragScrollLeft - walk; + }); + + // 节点点击事件(可扩展) + items.forEach((item) => { + item.addEventListener('click', () => { + // 添加点击反馈动画 + const dot = item.querySelector('.dot'); + if (dot) { + dot.style.transform = 'translate(-50%, -50%) scale(2)'; + setTimeout(() => { + dot.style.transform = ''; + }, 200); + } + }); + }); + + // 键盘导航支持 + let currentIndex = 0; + + document.addEventListener('keydown', (e) => { + if (!isElementInViewport(container)) return; + + if (e.key === 'ArrowLeft') { + currentIndex = Math.max(0, currentIndex - 1); + scrollToItem(currentIndex); + } else if (e.key === 'ArrowRight') { + currentIndex = Math.min(items.length - 1, currentIndex + 1); + scrollToItem(currentIndex); + } + }); + + function scrollToItem(index) { + if (container.scrollWidth <= container.clientWidth) return; + + const item = items[index]; + if (!item) return; + + const containerRect = container.getBoundingClientRect(); + const itemRect = item.getBoundingClientRect(); + + const targetScrollLeft = container.scrollLeft + (itemRect.left - containerRect.left) - (containerRect.width / 2) + (itemRect.width / 2); + + container.scrollTo({ + left: targetScrollLeft, + behavior: 'smooth' + }); + } + + // ============================================ + // 自动轮播功能 - 从左到右循环展开 + // ============================================ + let autoPlayIndex = 0; + let autoPlayTimer = null; + let isUserInteracting = false; + const autoPlayInterval = 3000; // 每个节点展开持续时间(毫秒) + const pauseAfterInteraction = 5000; // 用户交互后暂停时间(毫秒) + + // 添加自动展开的CSS类 + function expandItem(index) { + // 移除所有节点的展开状态 + items.forEach(item => { + item.classList.remove('auto-expanded'); + }); + // 给当前节点添加展开状态 + if (items[index]) { + items[index].classList.add('auto-expanded'); + } + } + + // 自动轮播 + function autoPlay() { + if (isUserInteracting) return; + + expandItem(autoPlayIndex); + autoPlayIndex = (autoPlayIndex + 1) % items.length; + } + + // 启动自动轮播 + function startAutoPlay() { + if (autoPlayTimer) return; + autoPlayTimer = setInterval(autoPlay, autoPlayInterval); + // 立即展开第一个 + autoPlay(); + } + + // 停止自动轮播 + function stopAutoPlay() { + if (autoPlayTimer) { + clearInterval(autoPlayTimer); + autoPlayTimer = null; + } + // 移除所有展开状态 + items.forEach(item => { + item.classList.remove('auto-expanded'); + }); + } + + // 用户交互时暂停自动轮播 + function pauseAutoPlay() { + isUserInteracting = true; + stopAutoPlay(); + + // 一段时间后恢复自动轮播 + setTimeout(() => { + isUserInteracting = false; + if (isElementInViewport(container)) { + startAutoPlay(); + } + }, pauseAfterInteraction); + } + + // 监听用户交互 + container.addEventListener('mouseenter', pauseAutoPlay); + container.addEventListener('touchstart', pauseAutoPlay, { passive: true }); + + // 使用 Intersection Observer 控制自动轮播 + const autoPlayObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting && !isUserInteracting) { + startAutoPlay(); + } else { + stopAutoPlay(); + } + }); + }, { threshold: 0.3 }); + + autoPlayObserver.observe(container); + + console.log("Timeline Loaded with Enhanced Labels and Positioning"); + } + + // 工具函数:检查元素是否在视口中 + function isElementInViewport(el) { + const rect = el.getBoundingClientRect(); + return ( + rect.top < window.innerHeight && + rect.bottom > 0 + ); + } +})(); diff --git a/contact.html b/contact.html index eff984a..66fffd8 100644 --- a/contact.html +++ b/contact.html @@ -25,6 +25,7 @@ + +
+

发展里程

+
+
+ + +
+
+ 2016.08 软件企业 +
+ +
+

荣获"山东省软件企业"资质

+
+
+
+ + +
+
+ 2017.05 科技创新 +
+ +
+

荣获"国家科技型创新企业"资质

+
+
+
+ + +
+
+ 2017.10 ISO认证 +
+ +
+

ISO9001质量管理体系认证

+
+
+
+ + +
+
+ 2017.12 锦江电商 +
+ +
+

建设完成中日韩航线最大的电子商务平台-锦江航运电商平台

+

年线上交易额达到10亿元

+
+
+
+ + +
+
+ 2018.05 云码头 +
+ +
+

国内第一个自主研发的云码头平台在中山港航集团上线

+

建设运营成本仅为原有模式的10%,预计为全国码头节省建设成本近百亿

+
+
+
+ + +
+
+ 2018.06 技术研发 +
+ +
+

荣获市级"基于新旧动能转换的港口物流信息管理智慧云平台的关键技术研发"三等奖

+
+
+
+ + +
+
+ 2018.07 多式联运 +
+ +
+

实现侨益集团粮食物流公、铁、水多式联运信息化管理

+

打通其国际粮食进口、国内北粮南运信息化通道

+
+
+
+ + +
+
+ 2018.08 高新技术 +
+ +
+

荣获"高新技术企业"资质

+
+
+
+ + +
+
+ 2019.11 省级项目 +
+ +
+

承建两个山东省技术创新项目

+
+
+
+ + +
+
+ 2019 国产替代 +
+ +
+

打破港航软件长期依赖国外ORACLE数据库的现状

+

成功研发出基于国产数据库的"码头智能操作系统",解决国外"卡脖子"问题

+

大大提升了国家航运数据安全性

+
+
+
+ + +
+
+ 2020 创新创业 +
+ +
+

荣获"第九届中国创新创业大赛(山东赛区)暨2020年山东省中小微企业创新竞技行动计划优胜企业"

+
+
+
+ + +
+
+ 2020.06 一键通 +
+ +
+

交付完成交通部十三五重点项目之一

+

京津冀协同下的"一键通"大宗干散货智慧物流示范工程

+
+
+
+ + +
+
+ 2021.07 研发中心 +
+ +
+

荣获山东省"一企一技术"研发中心资源认证

+
+
+
+ + +
+
+ 2022.06 专精特新 +
+ +
+

荣获山东省"专精特新"荣誉认证

+
+
+
+ + +
+
+ 2023.07 瞪羚企业 +
+ +
+

荣获山东省"瞪羚企业"荣誉认证

+
+
+
+ + +
+
+ 2025 AI智能 +
+ +
+

省级工业互联网平台入库名单

+

"数字化智能供应链平台"成功跻身省级工业互联网平台行列

+

"基于大语言模型和机器人流程自动化技术的港口AI智能平台"强势入选山东省创新能力提升工程

+
+
+
+ +
+
+ +
@@ -185,5 +397,6 @@ +