独立渲染引擎就绪引擎就绪
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>独立夹持与剪切解耦系统原理演示</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&display=swap');
:root {
--bg-color: #03070e;
--grid-color: rgba(0, 240, 255, 0.07);
--cyan-main: #00f0ff;
--cyan-dim: rgba(0, 240, 255, 0.3);
--red-alert: #ff2a4a;
--green-safe: #00ff66;
--mech-dark: #0b1120;
--mech-border: #1e293b;
--material-color: #f8fafc;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
user-select: none;
}
body {
background-color: var(--bg-color);
color: var(--cyan-main);
font-family: 'JetBrains Mono', monospace;
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
/* 工业蓝图网格背景 */
background-image:
linear-gradient(var(--grid-color) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
background-size: 40px 40px;
background-position: center center;
}
/* 极简 HUD - 严格遵守尺寸极小、位于边缘的规则,绝不遮挡中心 */
.hud {
position: absolute;
font-size: 11px;
line-height: 1.6;
pointer-events: none;
z-index: 100;
text-transform: uppercase;
letter-spacing: 1px;
}
.hud-top-left { top: 20px; left: 20px; }
.hud-top-right { top: 20px; right: 20px; text-align: right; }
.hud-bottom-left { bottom: 20px; left: 20px; }
.hud-bottom-right { bottom: 20px; right: 20px; text-align: right; }
.hud-title {
font-weight: 800;
font-size: 14px;
margin-bottom: 8px;
color: #fff;
text-shadow: 0 0 10px var(--cyan-dim);
}
.hud-value { color: #fff; font-weight: 700; }
.hud-highlight { color: var(--green-safe); }
.hud-warning { color: var(--red-alert); }
/* 中心动画容器 - 占据最大空间 */
.stage {
position: relative;
width: 800px;
height: 400px;
display: flex;
align-items: center;
justify-content: center;
}
/* 参考线 */
.axis-line {
position: absolute;
background: rgba(0, 240, 255, 0.15);
}
.axis-x { width: 100%; height: 1px; top: 50%; left: 0; }
.axis-y-1 { height: 100%; width: 1px; left: 30%; top: 0; border-left: 1px dashed var(--cyan-dim); background: transparent; }
.axis-y-2 { height: 100%; width: 1px; left: 70%; top: 0; border-left: 1px dashed rgba(255, 42, 74, 0.3); background: transparent; }
/* 被处理物料 */
.material-container {
position: absolute;
width: 600px;
height: 16px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
z-index: 10;
}
.material-core {
height: 100%;
background: linear-gradient(90deg, #94a3b8, #f8fafc, #94a3b8);
box-shadow: 0 0 15px rgba(255,255,255,0.2);
border-radius: 2px;
}
.material-left { width: 70%; transform-origin: left center; }
.material-right {
width: 30%;
transform-origin: left center;
/* 切断时的物理掉落过渡 */
transition: transform 0.6s cubic-bezier(0.5, 0, 1, 1), opacity 0.5s ease;
}
/* 独立系统 1: 夹持模块 (左侧) */
.module-clamp {
position: absolute;
left: calc(50% - 160px);
top: 50%;
width: 120px;
height: 200px;
transform: translateY(-50%);
z-index: 20;
}
.jaw {
position: absolute;
width: 100%;
height: 60px;
background: var(--mech-dark);
border: 2px solid var(--cyan-main);
box-shadow: inset 0 0 20px rgba(0, 240, 255, 0.1);
display: flex;
align-items: center;
justify-content: center;
/* 夹持动作转换干脆利落 */
transition: transform 0.15s cubic-bezier(0.1, 1, 0, 1);
}
.jaw::after {
content: '';
position: absolute;
width: 80%;
height: 6px;
background: repeating-linear-gradient(45deg, transparent, transparent 5px, var(--cyan-dim) 5px, var(--cyan-dim) 10px);
}
.jaw-top { top: -20px; transform: translateY(-80px); border-bottom: 4px solid var(--cyan-main); }
.jaw-bottom { bottom: -20px; transform: translateY(80px); border-top: 4px solid var(--cyan-main); }
.jaw-top::after { bottom: 0; }
.jaw-bottom::after { top: 0; }
/* 传感器扫描场 (夹持与剪切之间) */
.sensor-field {
position: absolute;
left: calc(50% - 20px);
top: 50%;
width: 140px;
height: 120px;
transform: translateY(-50%);
border: 1px solid transparent;
z-index: 15;
overflow: hidden;
opacity: 0;
transition: opacity 0.3s ease;
}
.laser-beam {
position: absolute;
top: 0;
left: 0;
width: 2px;
height: 100%;
background: var(--green-safe);
box-shadow: 0 0 15px var(--green-safe), 0 0 30px var(--green-safe);
transform: translateX(0);
}
.scan-grid {
position: absolute;
width: 100%;
height: 100%;
background-image: linear-gradient(var(--green-safe) 1px, transparent 1px);
background-size: 100% 10px;
opacity: 0.1;
}
/* 独立系统 2: 剪切模块 (右侧) */
.module-shear {
position: absolute;
left: calc(50% + 140px);
top: 50%;
width: 40px;
height: 300px;
transform: translateY(-50%);
z-index: 25;
}
.blade-housing {
position: absolute;
width: 100%;
height: 100%;
border-left: 2px solid var(--mech-border);
border-right: 2px solid var(--mech-border);
background: rgba(11, 17, 32, 0.5);
}
.blade {
position: absolute;
top: 0;
width: 60px;
left: -10px;
height: 80px;
background: var(--mech-dark);
border: 2px solid var(--red-alert);
border-bottom: 6px solid var(--red-alert);
box-shadow: 0 5px 20px rgba(255, 42, 74, 0.4);
/* 剪切动作极其干脆、暴力 */
transform: translateY(-100px);
transition: transform 0s;
}
.blade::before {
content: '';
position: absolute;
bottom: -15px;
left: -2px;
width: 0;
height: 0;
border-left: 30px solid transparent;
border-right: 30px solid transparent;
border-top: 15px solid var(--red-alert);
}
/* 状态控制类 */
.state-clamping .jaw-top { transform: translateY(12px); }
.state-clamping .jaw-bottom { transform: translateY(-12px); }
.state-sensing .sensor-field { opacity: 1; border-color: rgba(0, 255, 102, 0.2); }
/* 切割瞬间使用类来触发 CSS transition */
.state-shearing .blade {
transform: translateY(145px); /* 切断位置 */
transition: transform 0.05s cubic-bezier(1, 0, 1, 1); /* 极快落下 */
}
.state-retracting .blade {
transform: translateY(-100px);
transition: transform 0.4s cubic-bezier(0.1, 1, 0, 1); /* 快速回弹 */
}
.state-cut .material-right {
transform: translate(20px, 150px) rotate(15deg);
opacity: 0;
}
.state-feed .material-container {
transform: translate(-150%, -50%);
transition: none;
}
.state-feeding .material-container {
transform: translate(-50%, -50%);
transition: transform 0.8s cubic-bezier(0.1, 1, 0, 1);
}
/* 扫描动画通过 JS 控制或 CSS 动画 */
@keyframes scanMotion {
0% { transform: translateX(0); }
50% { transform: translateX(138px); }
100% { transform: translateX(0); }
}
.is-scanning .laser-beam {
animation: scanMotion 1.5s infinite ease-in-out;
}
</style>
</head>
<body>
<!-- 左上角 HUD -->
<div class="hud hud-top-left">
<div class="hud-title">DECOUPLED KINETICS SYS</div>
<div>Engine: <span class="hud-highlight">ONLINE</span></div>
<div>Mode: <span class="hud-value">Asynchronous</span></div>
<div style="margin-top: 10px; color: var(--cyan-dim);">
SYS.1: CLAMP_AND_HOLD<br>
SYS.2: INDEPENDENT_SHEAR
</div>
</div>
<!-- 右上角 HUD -->
<div class="hud hud-top-right">
<div>System Clock: <span id="clock" class="hud-value">00:00:00:000</span></div>
<div>Cycle Count: <span id="cycle-count" class="hud-value">0000</span></div>
<div style="margin-top: 10px;">
Action Transtion: <span class="hud-highlight">CRISP</span>
</div>
</div>
<!-- 左下角 HUD -->
<div class="hud hud-bottom-left">
<div>[ SENSOR TELEMETRY ]</div>
<div>Status: <span id="sensor-status">STANDBY</span></div>
<div>Detection Time: <span id="detect-time" class="hud-highlight">0.00s</span></div>
<div style="color: var(--cyan-dim); margin-top: 5px;">* Time infinitely extendable due to decoupling</div>
</div>
<!-- 右下角 HUD -->
<div class="hud hud-bottom-right">
<div>[ SEQUENCE LOG ]</div>
<div id="seq-log-3" style="color: var(--cyan-dim);">SYS INIT</div>
<div id="seq-log-2" style="color: rgba(0,240,255,0.6);">WAITING FOR MAT</div>
<div id="seq-log-1" class="hud-value">> ENGAGING LOOP</div>
</div>
<!-- 核心动画舞台 -->
<div class="stage" id="stage">
<!-- 装饰轴线 -->
<div class="axis-line axis-x"></div>
<div class="axis-line axis-y-1"></div>
<div class="axis-line axis-y-2"></div>
<!-- 物料 -->
<div class="material-container" id="material">
<div class="material-core material-left"></div>
<div class="material-core material-right" id="material-right"></div>
</div>
<!-- 系统1: 夹持模块 -->
<div class="module-clamp" id="module-clamp">
<div class="jaw jaw-top"></div>
<div class="jaw jaw-bottom"></div>
</div>
<!-- 传感器阵列 (位于夹持后部) -->
<div class="sensor-field" id="sensor-field">
<div class="scan-grid"></div>
<div class="laser-beam" id="laser"></div>
</div>
<!-- 系统2: 剪切模块 -->
<div class="module-shear" id="module-shear">
<div class="blade-housing"></div>
<div class="blade" id="blade"></div>
</div>
</div>
<script>
// DOM Elements
const stage = document.getElementById('stage');
const materialContainer = document.getElementById('material');
const materialRight = document.getElementById('material-right');
const sensorField = document.getElementById('sensor-field');
const clockEl = document.getElementById('clock');
const cycleEl = document.getElementById('cycle-count');
const sensorStatusEl = document.getElementById('sensor-status');
const detectTimeEl = document.getElementById('detect-time');
const logs = [
document.getElementById('seq-log-3'),
document.getElementById('seq-log-2'),
document.getElementById('seq-log-1')
];
let cycleCount = 0;
let detectionStartTime = 0;
let detectionTimer = null;
let globalTime = 0;
// HUD 运行时钟
setInterval(() => {
globalTime += 16;
const ms = globalTime % 1000;
const s = Math.floor(globalTime / 1000) % 60;
const m = Math.floor(globalTime / 60000);
clockEl.innerText = `${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}:${ms.toString().padStart(3,'0')}`;
}, 16);
// HUD 日志更新
function log(msg, type = 'normal') {
logs[0].innerText = logs[1].innerText;
logs[0].style.color = logs[1].style.color;
logs[1].innerText = logs[2].innerText;
logs[1].style.color = logs[2].style.color;
logs[2].innerText = `> ${msg}`;
if(type === 'alert') logs[2].style.color = 'var(--red-alert)';
else if(type === 'safe') logs[2].style.color = 'var(--green-safe)';
else logs[2].style.color = '#fff';
}
// 等待函数
const delay = ms => new Promise(res => setTimeout(res, ms));
// 核心解耦控制逻辑状态机
async function runEngineCycle() {
cycleCount++;
cycleEl.innerText = cycleCount.toString().padStart(4, '0');
// 1. 送料阶段
log("PHASE 1: MATERIAL FEEDING");
stage.className = 'stage state-feed';
materialRight.style.transition = 'none';
materialRight.style.opacity = '1';
materialRight.style.transform = 'translate(0, 0) rotate(0deg)';
await delay(50);
stage.className = 'stage state-feeding';
await delay(800);
// 2. 独立夹持阶段 (干脆锁定)
log("PHASE 2: CLAMP LOCK", "safe");
stage.classList.add('state-clamping');
await delay(300); // 物理锁定时间极其短促
// 3. 无限延长的检测阶段 (夹持与剪切解耦的核心体现)
// 此时物料被稳固夹持,剪切刀完全未介入
log("PHASE 3: SENSING (DECOUPLED)");
stage.classList.add('state-sensing');
sensorField.classList.add('is-scanning');
sensorStatusEl.innerText = "ANALYZING...";
sensorStatusEl.className = "hud-value";
// 模拟一个较长且随机的检测时间,证明时间的完全解耦
const sensingDuration = 2500 + Math.random() * 1500;
detectionStartTime = Date.now();
// 更新检测时间 UI
detectionTimer = setInterval(() => {
const elapsed = (Date.now() - detectionStartTime) / 1000;
detectTimeEl.innerText = elapsed.toFixed(2) + "s";
}, 50);
await delay(sensingDuration);
clearInterval(detectionTimer);
sensorStatusEl.innerText = "TARGET VERIFIED";
sensorStatusEl.className = "hud-highlight";
sensorField.classList.remove('is-scanning');
await delay(200);
stage.classList.remove('state-sensing');
// 4. 独立剪切阶段 (极度干脆的打击)
log("PHASE 4: SHEAR STRIKE", "alert");
stage.classList.add('state-shearing');
await delay(50); // 极短的剪切下落时间
// 剪切瞬间物料分离
stage.classList.add('state-cut');
await delay(100); // 刀片在底部停留极短时间
// 5. 刀片快速回弹与夹具释放
log("PHASE 5: RETRACT & RELEASE");
stage.classList.remove('state-shearing');
stage.classList.add('state-retracting');
await delay(200); // 刀片先回缩
// 夹具再松开
stage.classList.remove('state-clamping');
sensorStatusEl.innerText = "STANDBY";
sensorStatusEl.className = "";
detectTimeEl.innerText = "0.00s";
await delay(600); // 等待物料掉落和机构复位
// 移除回弹状态准备下一循环
stage.classList.remove('state-retracting');
stage.classList.remove('state-cut');
// 循环
runEngineCycle();
}
// 系统启动
setTimeout(() => {
log("ALL SYSTEMS GO", "safe");
runEngineCycle();
}, 1000);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>高精度解耦机械系统 - 动力学可视化</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;500;800&display=swap');
:root {
--bg-base: #060913;
--grid-line: rgba(56, 189, 248, 0.06);
--cyan-glow: #0ea5e9;
--neon-blue: #38bdf8;
--alert-red: #ef4444;
--safe-green: #10b981;
--metal-dark: #1e293b;
--metal-mid: #475569;
--metal-light: #94a3b8;
--copper: #b45309;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
user-select: none;
}
body {
background-color: var(--bg-base);
font-family: 'JetBrains Mono', monospace;
height: 100vh;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
/* 复杂工程蓝图背景 */
background-image:
linear-gradient(var(--grid-line) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-line) 1px, transparent 1px),
linear-gradient(rgba(56, 189, 248, 0.02) 2px, transparent 2px),
linear-gradient(90deg, rgba(56, 189, 248, 0.02) 2px, transparent 2px);
background-size: 20px 20px, 20px 20px, 100px 100px, 100px 100px;
background-position: center center;
}
/* 极简角落HUD系统 - 严格小字号、边缘定位 */
.hud {
position: absolute;
font-size: 10px;
line-height: 1.5;
color: rgba(255,255,255,0.6);
pointer-events: none;
z-index: 100;
text-transform: uppercase;
letter-spacing: 1px;
}
.hud-tl { top: 20px; left: 20px; }
.hud-tr { top: 20px; right: 20px; text-align: right; }
.hud-bl { bottom: 20px; left: 20px; }
.hud-br { bottom: 20px; right: 20px; text-align: right; }
.hud-title {
font-weight: 800;
font-size: 12px;
color: var(--neon-blue);
margin-bottom: 6px;
letter-spacing: 2px;
}
.hud-val { color: #fff; font-weight: 500; font-size: 11px; }
.hud-hl { color: var(--safe-green); font-weight: 800; }
.hud-warn { color: var(--alert-red); font-weight: 800; }
/* 核心动画区 - 最大化空间且无遮挡 */
.stage-container {
position: relative;
width: 1100px;
height: 600px;
display: flex;
justify-content: center;
align-items: center;
filter: drop-shadow(0 0 30px rgba(14, 165, 233, 0.05));
}
svg {
width: 100%;
height: 100%;
overflow: visible;
}
/* 机械部件的微光与质感 */
.glow-cyan { filter: drop-shadow(0 0 8px rgba(56,189,248,0.6)); }
.glow-red { filter: drop-shadow(0 0 12px rgba(239,68,68,0.8)); }
.glow-green { filter: drop-shadow(0 0 10px rgba(16,185,129,0.8)); }
.part-metal { fill: url(#grad-metal); stroke: #0f172a; stroke-width: 1.5; }
.part-metal-dark { fill: url(#grad-metal-dark); stroke: #020617; stroke-width: 2; }
.part-copper { fill: url(#grad-copper); stroke: #78350f; stroke-width: 1; }
.part-blade { fill: url(#grad-blade); stroke: var(--metal-light); stroke-width: 1; }
/* 装饰性UI线 */
.ui-line { stroke: var(--neon-blue); stroke-width: 1; opacity: 0.3; stroke-dasharray: 4 4; }
/* 激光扫描特效 */
#laser-beam {
transition: opacity 0.2s;
}
.scanning {
animation: scanAnim 1.2s ease-in-out infinite alternate;
}
@keyframes scanAnim {
0% { transform: translateX(-40px); }
100% { transform: translateX(40px); }
}
/* 动态粒子层 */
#particles {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
pointer-events: none;
}
.spark {
position: absolute;
width: 2px;
height: 8px;
background: #fff;
box-shadow: 0 0 6px #facc15, 0 0 12px #ef4444;
border-radius: 2px;
opacity: 0;
}
</style>
</head>
<body>
<!-- 极简边缘 HUD -->
<div class="hud hud-tl">
<div class="hud-title">KINEMATIC SYSTEM .V2</div>
<div>ARCH: <span class="hud-val">MOTOR-CAM-LINKAGE & RACK-PINION</span></div>
<div>OP_MODE: <span class="hud-val">FULLY DECOUPLED</span></div>
<div style="margin-top: 8px; opacity: 0.6; font-size: 9px;">
> SYS.01 : RACK-DRIVEN CLAMP<br>
> SYS.02 : SENSOR ARRAY (VARIABLE TIME)<br>
> SYS.03 : CAM-DRIVEN GUILLOTINE SHEAR
</div>
</div>
<div class="hud hud-tr">
<div>SYS CLOCK // <span id="clock" class="hud-val">00:00:00:000</span></div>
<div>CAM ANGLE // <span id="hud-angle" class="hud-val">270.0°</span></div>
<div>LINK STRESS // <span id="hud-stress" class="hud-val">0.0 MPa</span></div>
<div style="margin-top: 8px;">
BLADE VELOCITY: <span id="hud-vel" class="hud-val">0.0 m/s</span>
</div>
</div>
<div class="hud hud-bl">
<div class="hud-title">DECOUPLING TELEMETRY</div>
<div>CLAMP STATE: <span id="hud-clamp">OPEN</span></div>
<div>SENSOR LOCK: <span id="hud-sensor">WAITING</span></div>
<div>SCAN DUR: <span id="hud-time" class="hud-hl">0.00s</span></div>
<div style="margin-top: 8px; max-width: 220px; font-size: 9px; opacity: 0.5;">
* ACTION ISOLATED: CLAMP HOLDS SECURELY WHILE SENSOR EXECUTES UNLIMITED DURATION SCAN. MOTOR/CAM ACTUATES INDEPENDENTLY.
</div>
</div>
<div class="hud hud-br">
<div>[ SEQUENCE LOG ]</div>
<div id="log-3" style="opacity: 0.3;">SYS BOOT</div>
<div id="log-2" style="opacity: 0.6;">CALIBRATING KINEMATICS</div>
<div id="log-1" class="hud-val">> STANDBY FOR MATERIAL</div>
</div>
<!-- 中心纯动画区域 -->
<div class="stage-container">
<svg id="stage" viewBox="0 0 1100 600">
<defs>
<!-- 材质渐变定义 -->
<linearGradient id="grad-metal" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#64748b" />
<stop offset="50%" stop-color="#334155" />
<stop offset="100%" stop-color="#1e293b" />
</linearGradient>
<linearGradient id="grad-metal-dark" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#1e293b" />
<stop offset="100%" stop-color="#020617" />
</linearGradient>
<linearGradient id="grad-copper" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#d97706" />
<stop offset="50%" stop-color="#f59e0b" />
<stop offset="100%" stop-color="#92400e" />
</linearGradient>
<linearGradient id="grad-blade" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#e2e8f0" />
<stop offset="80%" stop-color="#94a3b8" />
<stop offset="100%" stop-color="#f8fafc" />
</linearGradient>
<linearGradient id="grad-mat" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#fcd34d" />
<stop offset="20%" stop-color="#fef3c7" />
<stop offset="80%" stop-color="#d97706" />
<stop offset="100%" stop-color="#78350f" />
</linearGradient>
<!-- 发光滤镜 -->
<filter id="neon-glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="4" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<!-- 条纹图样 (用于危险区域或抓手) -->
<pattern id="stripes" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
<rect width="5" height="10" fill="#0f172a" opacity="0.5"/>
</pattern>
</defs>
<!-- 背景导轨与机架 -->
<g id="bg-frame" opacity="0.6">
<!-- 送料轴线 -->
<line x1="0" y1="350" x2="1100" y2="350" class="ui-line" />
<!-- 剪切垂直轴线 -->
<line x1="850" y1="0" x2="850" y2="600" class="ui-line" stroke-dasharray="2 6" />
<!-- 夹持器导轨 -->
<rect x="250" y="150" width="40" height="300" class="part-metal-dark" rx="5" />
<line x1="270" y1="160" x2="270" y2="440" stroke="#0ea5e9" stroke-width="2" opacity="0.3" />
<!-- 剪刀机架背板 -->
<path d="M 780,80 h 140 v 420 h -140 z" fill="#0f172a" stroke="#1e293b" stroke-width="4" rx="10" />
<rect x="800" y="240" width="20" height="240" class="part-metal-dark" />
<rect x="880" y="240" width="20" height="240" class="part-metal-dark" />
</g>
<!-- 动态物料层 -->
<g id="material-layer">
<!-- 左侧被夹持部分 -->
<rect id="mat-left" x="-500" y="340" width="1350" height="20" fill="url(#grad-mat)" rx="2" filter="drop-shadow(0 5px 10px rgba(0,0,0,0.5))" />
<!-- 右侧被切断掉落部分 -->
<g id="mat-right-group">
<rect id="mat-right" x="850" y="340" width="250" height="20" fill="url(#grad-mat)" rx="2" display="none" />
</g>
</g>
<!-- 系统1: 夹持器组件 (齿轮齿条式抓手) -->
<g id="clamp-system">
<!-- 上抓手 -->
<g id="jaw-top" transform="translate(0, -60)">
<path d="M 230,220 h 80 v 100 h -80 z" class="part-metal" rx="4" />
<!-- 齿条 -->
<rect x="295" y="220" width="10" height="100" fill="url(#stripes)" />
<!-- 夹爪 -->
<path d="M 240,320 h 60 l -10,18 h -40 z" class="part-metal-dark" />
<rect x="245" y="338" width="50" height="4" fill="#ef4444" />
</g>
<!-- 下抓手 -->
<g id="jaw-bottom" transform="translate(0, 60)">
<path d="M 230,380 h 80 v 100 h -80 z" class="part-metal" rx="4" />
<!-- 齿条 -->
<rect x="295" y="380" width="10" height="100" fill="url(#stripes)" />
<!-- 夹爪 -->
<path d="M 240,380 h 60 l -10,-18 h -40 z" class="part-metal-dark" />
<rect x="245" y="358" width="50" height="4" fill="#ef4444" />
</g>
<!-- 驱动齿轮 (Pinion) -->
<g id="clamp-pinion" transform="translate(270, 350)">
<circle cx="0" cy="0" r="22" class="part-metal" />
<circle cx="0" cy="0" r="16" class="part-copper" />
<circle cx="0" cy="0" r="6" fill="#020617" />
<!-- 齿轮纹理示意 -->
<path d="M -16,0 L 16,0 M 0,-16 L 0,16 M -11,-11 L 11,11 M -11,11 L 11,-11" stroke="#1e293b" stroke-width="3" />
</g>
</g>
<!-- 系统2: 传感器阵列 (解耦等待区) -->
<g id="sensor-system" transform="translate(550, 350)">
<!-- 扫描仪外壳 -->
<path d="M -40,-60 h 80 v 20 h -80 z M -40,40 h 80 v 20 h -80 z" class="part-metal-dark" rx="3" />
<path d="M -30,-40 v 80 M 30,-40 v 80" stroke="#334155" stroke-width="4" stroke-dasharray="4 4" />
<!-- 激光发射器与光束 -->
<g id="laser-assembly" opacity="0">
<rect x="-40" y="-45" width="80" height="90" fill="rgba(16, 185, 129, 0.05)" />
<line id="laser-beam" x1="0" y1="-40" x2="0" y2="40" stroke="#10b981" stroke-width="3" filter="url(#neon-glow)" class="" />
<circle id="laser-dot" cx="0" cy="-40" r="4" fill="#10b981" filter="url(#neon-glow)" />
</g>
</g>
<!-- 系统3: 凸轮连杆剪切机 (核心动力学可视化) -->
<g id="shear-system">
<!-- 1. 驱动电机定子 (Motor Stator) -->
<g transform="translate(850, 150)">
<circle cx="0" cy="0" r="70" class="part-metal-dark" />
<!-- 铜线圈示意 -->
<circle cx="0" cy="0" r="55" class="part-copper" stroke-dasharray="10 4" stroke-width="12" fill="none" />
<circle cx="0" cy="0" r="45" class="part-metal" />
</g>
<!-- 2. 旋转凸轮/转子 (Cam/Rotor) - 动态旋转 -->
<g id="shear-cam" transform="translate(850, 150) rotate(-90)">
<circle cx="0" cy="0" r="40" class="part-metal" />
<!-- 偏心销轴心 (Crank Pin) -->
<circle cx="28" cy="0" r="8" fill="#e2e8f0" stroke="#0f172a" stroke-width="2" />
<line x1="0" y1="0" x2="28" y2="0" stroke="#0f172a" stroke-width="4" />
<circle cx="0" cy="0" r="6" fill="#0f172a" />
</g>
<!-- 3. 传动连杆 (Linkage) - 动态计算坐标 -->
<!-- x1,y1接偏心销, x2,y2接刀具块 -->
<line id="shear-linkage" x1="850" y1="122" x2="850" y2="242" stroke="url(#grad-metal)" stroke-width="16" stroke-linecap="round" />
<circle id="link-pin-top" cx="850" cy="122" r="5" fill="#0f172a" />
<circle id="link-pin-bot" cx="850" cy="242" r="5" fill="#0f172a" />
<!-- 4. 剪切刀具滑块组 (Blade Assembly) - 动态Y轴平移 -->
<g id="blade-assembly" transform="translate(0, 242)">
<!-- 承重滑块 -->
<path d="M 810,-10 h 80 v 60 h -80 z" class="part-metal-dark" rx="5" />
<circle cx="850" cy="0" r="10" class="part-metal" /> <!-- 下连接销底座 -->
<!-- 剪刀刃 (Scissor/Guillotine Blade) - 带有倾斜剪切角,保证干脆利落 -->
<path d="M 815,50 h 70 v 40 l -70, 20 z" class="part-blade" />
<!-- 刀锋高光 -->
<line x1="815" y1="110" x2="885" y2="90" stroke="#fff" stroke-width="2" opacity="0.8" />
<!-- 危险警示条纹 -->
<rect x="815" y="45" width="70" height="10" fill="url(#stripes)" />
</g>
</g>
<!-- 前景遮挡/导轨压板 -->
<rect x="800" y="240" width="10" height="240" fill="#0f172a" opacity="0.8" />
<rect x="890" y="240" width="10" height="240" fill="#0f172a" opacity="0.8" />
</svg>
<!-- 粒子容器用于火花特效 -->
<div id="particles"></div>
</div>
<script>
/**
* 核心运动学常量与状态
*/
const KINEMATICS = {
motorX: 850,
motorY: 150,
camRadius: 28, // 偏心距 R
linkLength: 140, // 连杆长度 L
bladeBaseY: 0, // 刀具相对滑块销的偏移
matCutX: 850, // 剪切位置
matSurfaceY: 340 // 物料上表面Y
};
const STATE = {
phase: 'INIT', // FEED, CLAMP, SENSE, SHEAR, RELEASE
feedX: -500, // -500 to 0 (0 means tip is at 850)
clampY: 60, // 60 (open) to 0 (closed)
motorAngle: -Math.PI / 2, // Starts at top (-90 deg)
isCut: false,
cutMatY: 340,
cutMatVy: 0,
cutMatRot: 0,
cutMatVx: 0,
globalTime: 0
};
// DOM 元素绑定
const els = {
jawTop: document.getElementById('jaw-top'),
jawBot: document.getElementById('jaw-bottom'),
pinion: document.getElementById('clamp-pinion'),
matLeft: document.getElementById('mat-left'),
matRightGrp: document.getElementById('mat-right-group'),
matRight: document.getElementById('mat-right'),
cam: document.getElementById('shear-cam'),
linkage: document.getElementById('shear-linkage'),
linkPinTop: document.getElementById('link-pin-top'),
linkPinBot: document.getElementById('link-pin-bot'),
bladeAssy: document.getElementById('blade-assembly'),
laserAssy: document.getElementById('laser-assembly'),
laserBeam: document.getElementById('laser-beam'),
particles: document.getElementById('particles'),
// HUD
clock: document.getElementById('clock'),
hudAngle: document.getElementById('hud-angle'),
hudStress: document.getElementById('hud-stress'),
hudVel: document.getElementById('hud-vel'),
hudClamp: document.getElementById('hud-clamp'),
hudSensor: document.getElementById('hud-sensor'),
hudTime: document.getElementById('hud-time'),
logs: [document.getElementById('log-3'), document.getElementById('log-2'), document.getElementById('log-1')]
};
// 工具函数
const delay = ms => new Promise(res => setTimeout(res, ms));
function log(msg, type = 'normal') {
els.logs[0].innerText = els.logs[1].innerText;
els.logs[0].style.color = els.logs[1].style.color;
els.logs[1].innerText = els.logs[2].innerText;
els.logs[1].style.color = els.logs[2].style.color;
els.logs[2].innerText = `> ${msg}`;
if(type === 'alert') els.logs[2].style.color = 'var(--alert-red)';
else if(type === 'safe') els.logs[2].style.color = 'var(--safe-green)';
else els.logs[2].style.color = '#fff';
}
function createSparks() {
for(let i=0; i<8; i++) {
let spark = document.createElement('div');
spark.className = 'spark';
spark.style.left = (KINEMATICS.matCutX - 10 + Math.random()*20) + 'px';
spark.style.top = KINEMATICS.matSurfaceY + 'px';
els.particles.appendChild(spark);
let angle = Math.random() * Math.PI - Math.PI; // -180 to 0
let speed = 5 + Math.random() * 10;
let vx = Math.cos(angle) * speed;
let vy = Math.sin(angle) * speed;
let x = 0, y = 0;
let life = 0;
function animSpark() {
life++;
x += vx;
y += vy;
vy += 0.5; // gravity
spark.style.transform = `translate(${x}px, ${y}px) rotate(${Math.atan2(vy, vx)}rad)`;
spark.style.opacity = 1 - (life/30);
if(life < 30) requestAnimationFrame(animSpark);
else spark.remove();
}
requestAnimationFrame(animSpark);
}
}
/**
* 核心运动学渲染循环
* 实时计算连杆与滑块的精确几何位置
*/
let lastBladeY = 0;
function renderKinematics() {
STATE.globalTime += 16;
// HUD 时钟
const ms = STATE.globalTime % 1000;
const s = Math.floor(STATE.globalTime / 1000) % 60;
const m = Math.floor(STATE.globalTime / 60000);
els.clock.innerText = `${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}:${ms.toString().padStart(3,'0')}`;
// --- 1. 送料与夹持系统渲染 ---
els.matLeft.setAttribute('x', STATE.feedX);
els.jawTop.setAttribute('transform', `translate(0, ${-STATE.clampY})`);
els.jawBot.setAttribute('transform', `translate(0, ${STATE.clampY})`);
// 齿轮联动旋转 (位移 / 半径 = 弧度)
let pinionAngle = ((60 - STATE.clampY) / 22) * (180/Math.PI);
els.pinion.setAttribute('transform', `translate(270, 350) rotate(${pinionAngle})`);
// --- 2. 剪切系统运动学解算 ---
// 偏心销坐标 (Pin Top)
let px = KINEMATICS.motorX + KINEMATICS.camRadius * Math.cos(STATE.motorAngle);
let py = KINEMATICS.motorY + KINEMATICS.camRadius * Math.sin(STATE.motorAngle);
// 连杆与垂直导轨的交点 (Pin Bottom = Blade Assembly Y)
// L^2 = (px - bx)^2 + (py - by)^2. Here bx is fixed at motorX.
let dx = KINEMATICS.motorX - px;
let dy = Math.sqrt(KINEMATICS.linkLength**2 - dx**2);
let by = py + dy; // 滑块销钉 Y 坐标
// 应用到 SVG
let deg = STATE.motorAngle * (180/Math.PI);
els.cam.setAttribute('transform', `translate(${KINEMATICS.motorX}, ${KINEMATICS.motorY}) rotate(${deg})`);
els.linkage.setAttribute('x1', px);
els.linkage.setAttribute('y1', py);
els.linkage.setAttribute('x2', KINEMATICS.motorX);
els.linkage.setAttribute('y2', by);
els.linkPinTop.setAttribute('cx', px);
els.linkPinTop.setAttribute('cy', py);
els.linkPinBot.setAttribute('cy', by);
els.bladeAssy.setAttribute('transform', `translate(0, ${by})`);
// 计算物理量 HUD
let degDisplay = ((deg + 360 + 90) % 360).toFixed(1);
els.hudAngle.innerText = `${degDisplay}°`;
let vel = (by - lastBladeY) / 16 * 1000; // px/s
els.hudVel.innerText = (vel/100).toFixed(2) + " m/s";
lastBladeY = by;
// 模拟连杆应力 (当切削瞬间应力激增)
let stress = Math.abs(Math.cos(STATE.motorAngle)) * 15;
if(STATE.phase === 'SHEAR' && by > KINEMATICS.matSurfaceY - 80 && by < KINEMATICS.matSurfaceY - 40) {
stress += 250; // 切割瞬间应力极大
els.hudStress.style.color = "var(--alert-red)";
} else {
els.hudStress.style.color = "#fff";
}
els.hudStress.innerText = stress.toFixed(1) + " MPa";
// --- 3. 切断物料物理模拟 ---
if (STATE.isCut) {
STATE.cutMatVy += 0.8; // 重力
STATE.cutMatY += STATE.cutMatVy;
STATE.cutMatX += STATE.cutMatVx;
STATE.cutMatRot += 3;
els.matRightGrp.setAttribute('transform', `translate(${STATE.cutMatX - 850}, ${STATE.cutMatY - 340}) rotate(${STATE.cutMatRot}, 850, 340)`);
if(STATE.cutMatY > 800) els.matRight.style.display = 'none'; // 掉出屏幕外
}
requestAnimationFrame(renderKinematics);
}
// 启动渲染引擎
requestAnimationFrame(renderKinematics);
/**
* 状态机控制序列
*/
async function runCycle() {
// --- 阶段 1: 送料 ---
STATE.phase = 'FEED';
log("PHASE 1: MATERIAL FEED", "normal");
STATE.isCut = false;
els.matRight.style.display = 'none';
els.matLeft.setAttribute('width', 1350);
// 缓动送料
await new Promise(res => {
let start = performance.now();
function step(t) {
let p = (t - start) / 600;
if(p > 1) p = 1;
let ease = 1 - Math.pow(1 - p, 3);
STATE.feedX = -500 + ease * 500;
if(p < 1) requestAnimationFrame(step);
else res();
}
requestAnimationFrame(step);
});
await delay(100);
// --- 阶段 2: 夹持 (Rack & Pinion 动作) ---
STATE.phase = 'CLAMP';
log("PHASE 2: RACK CLAMP LOCK", "safe");
els.hudClamp.innerText = "LOCKED";
els.hudClamp.className = "hud-hl";
await new Promise(res => {
let start = performance.now();
function step(t) {
let p = (t - start) / 150; // 150ms 快速夹紧
if(p > 1) p = 1;
STATE.clampY = 60 - (p * 60); // 降到0
if(p < 1) requestAnimationFrame(step);
else res();
}
requestAnimationFrame(step);
});
await delay(100);
// --- 阶段 3: 无限延长检测 (体现解耦核心) ---
// 夹持器锁死,剪切刀未动,时间完全由传感器决定
STATE.phase = 'SENSE';
log("PHASE 3: SENSOR ARRAY ACTIVE", "normal");
els.hudSensor.innerText = "SCANNING...";
els.hudSensor.className = "hud-hl";
els.laserAssy.style.opacity = 1;
els.laserBeam.classList.add('scanning');
let scanStartTime = Date.now();
let scanDuration = 2000 + Math.random() * 2000; // 随机 2-4 秒的检测时间
let timeInterval = setInterval(() => {
els.hudTime.innerText = ((Date.now() - scanStartTime)/1000).toFixed(2) + "s";
}, 50);
await delay(scanDuration);
clearInterval(timeInterval);
els.laserBeam.classList.remove('scanning');
els.laserAssy.style.opacity = 0;
els.hudSensor.innerText = "VERIFIED";
await delay(100);
// --- 阶段 4: 独立剪切 (凸轮连杆暴力打击) ---
STATE.phase = 'SHEAR';
log("PHASE 4: KINEMATIC SHEAR STRIKE", "alert");
await new Promise(res => {
let start = performance.now();
let dur = 350; // 极快的一击
let startAngle = -Math.PI / 2;
function step(t) {
let p = (t - start) / dur;
if(p > 1) p = 1;
// 自定义动力学缓动:加速下落,减速回抽
let ease;
if (p < 0.4) {
ease = 2.5 * p * p; // 加速下落
} else {
let pp = (p - 0.4) / 0.6;
ease = 0.4 + 0.6 * (1 - Math.pow(1 - pp, 3)); // 减速回升
}
STATE.motorAngle = startAngle + ease * (Math.PI * 2);
// 触发物理切断点 (当刀刃经过物料表面)
if(p > 0.15 && !STATE.isCut) {
STATE.isCut = true;
createSparks();
els.matLeft.setAttribute('width', 1350 - 250); // 左侧缩短
els.matRight.style.display = 'block'; // 右侧显示并掉落
STATE.cutMatY = 340;
STATE.cutMatX = 850;
STATE.cutMatVy = 2; // 初速度
STATE.cutMatVx = 1 + Math.random();
STATE.cutMatRot = 0;
}
if(p < 1) requestAnimationFrame(step);
else {
STATE.motorAngle = startAngle; // 精确复位
res();
}
}
requestAnimationFrame(step);
});
// --- 阶段 5: 复位释放 ---
STATE.phase = 'RELEASE';
log("PHASE 5: SYSTEM RESET", "normal");
await new Promise(res => {
let start = performance.now();
function step(t) {
let p = (t - start) / 200;
if(p > 1) p = 1;
STATE.clampY = p * 60; // 回到60
if(p < 1) requestAnimationFrame(step);
else res();
}
requestAnimationFrame(step);
});
els.hudClamp.innerText = "OPEN";
els.hudClamp.className = "";
els.hudSensor.innerText = "WAITING";
els.hudSensor.className = "";
els.hudTime.innerText = "0.00s";
await delay(400); // 等待下一次循环
runCycle();
}
// 系统启动延迟
setTimeout(() => {
log("INIT KINEMATICS ENGINE...", "safe");
setTimeout(runCycle, 800);
}, 500);
</script>
</body>
</html>
积分规则:第一轮对话扣减8分,后续每轮扣6分
等待动画代码生成...
