feat: 完成智能制造订单班展示页面开发
详细说明:
- 项目主题: 物流输送线节拍优化的PLC与机器人联合调试
- 技术栈: 西门子S7-1500 PLC + ABB IRB 2600工业机器人
- 设计风格: 钢铁蓝主题(#3b82f6, #64748b, #94a3b8),工业制造专业感
页面结构:
- Hero区域: 全屏图片背景,汽车零部件分拣系统展示
- 导航栏: 4个区块(项目概述/设备选型/功能流程/编程实现)
- Section 1: 自动化控制工程师 - 项目背景与挑战
- Section 2: 数据采集技术员 - PLC/机器人/通信配置
- Section 3: PLC工程师 - 控制流程与I/O分配
- Section 4: 机器人调试工程师 - 梯形图/RAPID编程实现
- Footer: 项目成果总结
技术实现:
- HTML: 704行完整页面,4个expert代理,7张技术图片
- CSS: 962行钢铁蓝主题,light/dark模式切换
- JS: 268行交互逻辑,统计数据动画,懒加载优化
关键数据:
- 机器人负载: 20kg
- 工作半径: 1.65m
- 定位精度: ±0.04mm
- I/O点数: 32点
- PLC网络: 7个
- 机器人位置点: 3个
- 握手信号: 6个
资源配置:
- Agent头像: 4个(自动化控制工程师/数据采集技术员/PLC工程师/机器人调试工程师)
- 技术图片: 7个(产线运输图/传送带零部件/PLC控制器/工业机器人等)
- 主题色系: 钢铁蓝工业风,体现智能制造专业性
🤖 智能制造订单班展示页面开发完成!
This commit is contained in:
268
web_frontend/web_result/order-classes/manufacturing/js/main.js
Normal file
268
web_frontend/web_result/order-classes/manufacturing/js/main.js
Normal file
@@ -0,0 +1,268 @@
|
||||
// 物流输送线节拍优化的PLC与机器人联合调试 - 主要JavaScript逻辑
|
||||
|
||||
// 页面初始化
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('🤖 智能制造订单班PLC机器人联调页面加载完成');
|
||||
|
||||
// 初始化Lucide图标
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
|
||||
// 初始化组件
|
||||
initNavigation();
|
||||
initAnimations();
|
||||
initLazyLoading();
|
||||
initSmoothScroll();
|
||||
updateStats();
|
||||
initThemeToggle();
|
||||
});
|
||||
|
||||
// 导航功能
|
||||
function initNavigation() {
|
||||
const navItems = document.querySelectorAll('.nav-item');
|
||||
const sections = document.querySelectorAll('.section');
|
||||
|
||||
// 点击导航项滚动到对应区块
|
||||
navItems.forEach((item, index) => {
|
||||
item.addEventListener('click', () => {
|
||||
// 移除所有活跃状态
|
||||
navItems.forEach(nav => nav.classList.remove('active'));
|
||||
// 添加当前活跃状态
|
||||
item.classList.add('active');
|
||||
|
||||
// 滚动到对应区块
|
||||
if (sections[index]) {
|
||||
const targetSection = sections[index];
|
||||
const offsetTop = targetSection.offsetTop - 100;
|
||||
|
||||
window.scrollTo({
|
||||
top: offsetTop,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 滚动时更新导航活跃状态
|
||||
window.addEventListener('scroll', () => {
|
||||
let current = '';
|
||||
sections.forEach((section, index) => {
|
||||
const sectionTop = section.offsetTop - 150;
|
||||
if (scrollY >= sectionTop) {
|
||||
current = index;
|
||||
}
|
||||
});
|
||||
|
||||
navItems.forEach((item, index) => {
|
||||
item.classList.remove('active');
|
||||
if (index === current) {
|
||||
item.classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 动画初始化
|
||||
function initAnimations() {
|
||||
// 使用 Intersection Observer 实现滚动动画
|
||||
const observerOptions = {
|
||||
root: null,
|
||||
rootMargin: '0px',
|
||||
threshold: 0.1
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('fade-in');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, observerOptions);
|
||||
|
||||
// 观察所有需要动画的元素
|
||||
const animatedElements = document.querySelectorAll('.card, .expert-intro');
|
||||
animatedElements.forEach(el => {
|
||||
el.style.opacity = '0';
|
||||
observer.observe(el);
|
||||
});
|
||||
}
|
||||
|
||||
// 图片懒加载
|
||||
function initLazyLoading() {
|
||||
const images = document.querySelectorAll('img[data-src]');
|
||||
|
||||
const imageObserver = new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
const img = entry.target;
|
||||
const src = img.getAttribute('data-src');
|
||||
|
||||
// 创建新图片对象来预加载
|
||||
const tempImg = new Image();
|
||||
tempImg.onload = function() {
|
||||
img.src = src;
|
||||
img.classList.add('loaded');
|
||||
};
|
||||
tempImg.onerror = function() {
|
||||
// 如果图片加载失败,使用钢铁蓝主题占位图
|
||||
img.src = 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300"%3E%3Crect width="400" height="300" fill="%23f0f4f8"/%3E%3Ctext x="50%25" y="50%25" dominant-baseline="middle" text-anchor="middle" font-family="system-ui" font-size="20" fill="%233b82f6"%3E图片加载中%3C/text%3E%3C/svg%3E';
|
||||
img.classList.add('error');
|
||||
};
|
||||
tempImg.src = src;
|
||||
|
||||
img.removeAttribute('data-src');
|
||||
observer.unobserve(img);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
images.forEach(img => {
|
||||
imageObserver.observe(img);
|
||||
});
|
||||
}
|
||||
|
||||
// 平滑滚动
|
||||
function initSmoothScroll() {
|
||||
// 为所有锚点链接添加平滑滚动
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const targetId = this.getAttribute('href');
|
||||
if (targetId === '#') return;
|
||||
|
||||
const target = document.querySelector(targetId);
|
||||
if (target) {
|
||||
target.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 更新统计数据 - PLC机器人系统数据
|
||||
function updateStats() {
|
||||
// 动画数字增长效果 - PLC与机器人联调系统相关数据
|
||||
const stats = [
|
||||
{ selector: '.robot-payload', value: 20, suffix: 'kg' },
|
||||
{ selector: '.work-radius', value: 1.65, suffix: 'm' },
|
||||
{ selector: '.io-points', value: 32, suffix: '点' },
|
||||
{ selector: '.plc-networks', value: 7, suffix: '个' },
|
||||
{ selector: '.robot-positions', value: 3, suffix: '个' },
|
||||
{ selector: '.handshake-signals', value: 6, suffix: '个' }
|
||||
];
|
||||
|
||||
stats.forEach(stat => {
|
||||
const element = document.querySelector(stat.selector);
|
||||
if (element) {
|
||||
animateValue(element, 0, stat.value, 2000, stat.suffix);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 数字动画函数
|
||||
function animateValue(element, start, end, duration, suffix = '') {
|
||||
const startTime = performance.now();
|
||||
|
||||
function update(currentTime) {
|
||||
const elapsed = currentTime - startTime;
|
||||
const progress = Math.min(elapsed / duration, 1);
|
||||
|
||||
// 使用缓动函数
|
||||
const easeOutQuad = progress * (2 - progress);
|
||||
let current;
|
||||
|
||||
// 处理小数值(如1.65)
|
||||
if (end < 10 && end % 1 !== 0) {
|
||||
current = (start + (end - start) * easeOutQuad).toFixed(2);
|
||||
} else {
|
||||
current = Math.floor(start + (end - start) * easeOutQuad);
|
||||
}
|
||||
|
||||
element.textContent = current + suffix;
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(update);
|
||||
}
|
||||
|
||||
// 错误处理
|
||||
window.addEventListener('error', function(e) {
|
||||
if (e.target.tagName === 'IMG') {
|
||||
console.warn('图片加载失败:', e.target.src);
|
||||
e.target.src = 'data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" width="400" height="300" viewBox="0 0 400 300"%3E%3Crect width="400" height="300" fill="%23f0f4f8"/%3E%3Ctext x="50%25" y="50%25" dominant-baseline="middle" text-anchor="middle" font-family="system-ui" font-size="20" fill="%233b82f6"%3E图片暂时无法显示%3C/text%3E%3C/svg%3E';
|
||||
e.target.classList.add('error');
|
||||
}
|
||||
}, true);
|
||||
|
||||
// 移动端优化
|
||||
if ('ontouchstart' in window) {
|
||||
document.body.classList.add('touch-device');
|
||||
|
||||
// 移动端点击优化
|
||||
let touchStartTime;
|
||||
document.addEventListener('touchstart', () => {
|
||||
touchStartTime = Date.now();
|
||||
});
|
||||
|
||||
document.addEventListener('touchend', (e) => {
|
||||
const touchEndTime = Date.now();
|
||||
if (touchEndTime - touchStartTime < 200) {
|
||||
// 快速点击
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 性能监控
|
||||
if (window.performance && window.performance.timing) {
|
||||
window.addEventListener('load', () => {
|
||||
setTimeout(() => {
|
||||
const timing = window.performance.timing;
|
||||
const loadTime = timing.loadEventEnd - timing.navigationStart;
|
||||
console.log(`页面加载时间: ${loadTime}ms`);
|
||||
|
||||
// 如果加载时间过长,提示用户
|
||||
if (loadTime > 3000) {
|
||||
console.warn('页面加载时间较长,可能需要优化');
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
// 主题切换功能
|
||||
function initThemeToggle() {
|
||||
const themeToggleBtn = document.getElementById('themeToggleBtn');
|
||||
|
||||
// 从localStorage读取用户的主题偏好
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
// 如果没有保存的偏好,默认使用暗色主题
|
||||
if (savedTheme === 'dark' || savedTheme === null) {
|
||||
document.body.classList.add('dark-theme');
|
||||
}
|
||||
|
||||
// 点击切换主题
|
||||
if (themeToggleBtn) {
|
||||
themeToggleBtn.addEventListener('click', () => {
|
||||
document.body.classList.toggle('dark-theme');
|
||||
|
||||
// 保存用户偏好
|
||||
if (document.body.classList.contains('dark-theme')) {
|
||||
localStorage.setItem('theme', 'dark');
|
||||
} else {
|
||||
localStorage.setItem('theme', 'light');
|
||||
}
|
||||
|
||||
// 重新初始化图标以确保正确显示
|
||||
if (typeof lucide !== 'undefined') {
|
||||
lucide.createIcons();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user