feat: 增强版验证码全套实现 — 16种类型生成器/加密/风控/站点管理/平台后端/前端SDK/UI
- 核心新增: ICON_CLICK(PNG图标方案,预渲染资源)/SCRATCH/JIGSAW/CURVE_SLIDER(V1-V3)/ANGLE/CURVE_DRAW/WORD_ORDER_CLICK/PROOF_OF_WORK 等生成器 - 图标点选: classpath PNG 加载替代运行时字体渲染(Linux容器无emoji字体),提示条图作为 templateImage 返回前端 - 新增模块: crypto(AES+RSA)/obfuscator(背景乱序/噪声/扭曲)/risk(风控/IP黑名单/限流)/site(站点管理)/ml(轨迹规则引擎) - 平台后端: 站点管理/验证码API(generate/verify/secondary-verify)/统计/ML轨迹学习 - 前端SDK: TPCaptcha兼容,支持全部新型号渲染与交互 - 工具: tools/icon-render 图标预渲染工具
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>史诗质感 - 真·双剑与盾行为验证 (强效魔法脉冲版)</title>
|
||||
<style>
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background-color: #0f172a;
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.captcha-container {
|
||||
position: relative;
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.captcha-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* --- 1. 盾牌过渡 --- */
|
||||
.shield-shard {
|
||||
transform-origin: 50px 50px;
|
||||
transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1), fill 0.4s ease, opacity 0.5s ease;
|
||||
}
|
||||
|
||||
/* --- 2. 强效魔法结界脉冲 --- */
|
||||
.ward-group {
|
||||
transition: opacity 0.4s ease;
|
||||
}
|
||||
.ward-pulse {
|
||||
transform-origin: 50px 50px;
|
||||
/* 加快了一点点脉冲节奏,显得能量更活跃 */
|
||||
animation: pulse-ward 2s cubic-bezier(0.1, 0.7, 0.3, 1) infinite;
|
||||
}
|
||||
.ward-pulse.delay {
|
||||
/* 延迟时间调整,形成错落有致的双重波纹 */
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
/* 核心修改:大幅增加粗细、透明度和放大倍率 */
|
||||
@keyframes pulse-ward {
|
||||
0% { transform: scale(0.4); opacity: 1; stroke-width: 16px; }
|
||||
50% { opacity: 0.8; }
|
||||
100% { transform: scale(1.7); opacity: 0; stroke-width: 2px; }
|
||||
}
|
||||
|
||||
/* --- 3. 巨剑插入动画 --- */
|
||||
.sword-slide {
|
||||
transform: translateY(-85px);
|
||||
opacity: 0;
|
||||
transition: transform 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.4), opacity 0.4s ease;
|
||||
}
|
||||
|
||||
.sword-anchor-a { transform-origin: 50px 50px; transform: rotate(-45deg); }
|
||||
.sword-anchor-b { transform-origin: 50px 50px; transform: rotate(45deg); }
|
||||
|
||||
|
||||
/* --- 4. 状态控制 --- */
|
||||
.state-wait .ward-group { opacity: 1; }
|
||||
.state-wait .shield-shard {
|
||||
fill: url(#metalBlueGrad);
|
||||
transform: translate(0, 0) scale(1) rotate(0deg);
|
||||
opacity: 1;
|
||||
/* 盾牌本身也加上强力的魔法蓝光阴影 */
|
||||
filter: drop-shadow(0 0 20px rgba(56, 189, 248, 0.6));
|
||||
}
|
||||
|
||||
.state-success .ward-group { opacity: 0; }
|
||||
.state-success .shield-shard {
|
||||
fill: url(#metalGreenGrad);
|
||||
transform: translate(0, 0) scale(1) rotate(0deg);
|
||||
opacity: 1;
|
||||
filter: drop-shadow(0 6px 8px rgba(0,0,0,0.5));
|
||||
}
|
||||
.state-success .sword-slide { transform: translateY(-15px); opacity: 1; }
|
||||
|
||||
.state-fail .ward-group { opacity: 0; }
|
||||
.state-fail .shield-shard { fill: url(#metalRedGrad); opacity: 0.9; filter: none;}
|
||||
.state-fail .shard-tl { transform: translate(-25px, -30px) scale(0.9) rotateX(30deg) rotateY(-20deg) rotateZ(-15deg); opacity: 0.7; }
|
||||
.state-fail .shard-tr { transform: translate(25px, -30px) scale(0.9) rotateX(30deg) rotateY(20deg) rotateZ(15deg); opacity: 0.7; }
|
||||
.state-fail .shard-b { transform: translate(0, 35px) scale(0.8) rotateX(-20deg) rotateZ(5deg); opacity: 0.5; }
|
||||
|
||||
|
||||
.controls { display: flex; gap: 15px; }
|
||||
.controls button {
|
||||
padding: 12px 24px; font-size: 14px; font-weight: bold; cursor: pointer;
|
||||
border: 2px solid transparent; border-radius: 8px; background: #1e293b; color: #f1f5f9;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.controls button:hover { background: #334155; transform: translateY(-2px); }
|
||||
.controls button:active { transform: translateY(1px); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="captcha-container">
|
||||
<svg id="captcha-svg" class="captcha-icon state-wait" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="metalBlueGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#3B82F6" /><stop offset="50%" stop-color="#1E40AF" /><stop offset="100%" stop-color="#60A5FA" />
|
||||
</linearGradient>
|
||||
<linearGradient id="metalGreenGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#10B981" /><stop offset="50%" stop-color="#047857" /><stop offset="100%" stop-color="#34D399" />
|
||||
</linearGradient>
|
||||
<linearGradient id="metalRedGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#EF4444" /><stop offset="50%" stop-color="#B91C1C" /><stop offset="100%" stop-color="#F87171" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="bladeLight" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#f8fafc" /><stop offset="100%" stop-color="#94a3b8" />
|
||||
</linearGradient>
|
||||
<linearGradient id="bladeDark" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#64748b" /><stop offset="100%" stop-color="#334155" />
|
||||
</linearGradient>
|
||||
<linearGradient id="goldGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#FDE047" /><stop offset="50%" stop-color="#EAB308" /><stop offset="100%" stop-color="#A16207" />
|
||||
</linearGradient>
|
||||
|
||||
<filter id="swordShadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="3" dy="5" stdDeviation="2.5" flood-color="#000000" flood-opacity="0.7"/>
|
||||
</filter>
|
||||
|
||||
<filter id="epicMagicGlow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="2" result="blur1" />
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur2" />
|
||||
<feMerge>
|
||||
<feMergeNode in="blur2" />
|
||||
<feMergeNode in="blur1" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<g id="epic-sword" filter="url(#swordShadow)">
|
||||
<polygon points="43,26 50,26 50,115" fill="url(#bladeLight)" />
|
||||
<polygon points="50,26 57,26 50,115" fill="url(#bladeDark)" />
|
||||
<rect x="45" y="4" width="10" height="22" fill="#1e293b" />
|
||||
<path d="M 45 6 L 55 10 M 45 12 L 55 16 M 45 18 L 55 22 M 45 24 L 55 28" stroke="#475569" stroke-width="2" />
|
||||
<polygon points="20,22 50,26 80,22 80,27 50,32 20,27" fill="#713F12" />
|
||||
<polygon points="20,22 50,26 80,22 50,24" fill="url(#goldGrad)" />
|
||||
<polygon points="50,-6 57,0 50,6 43,0" fill="url(#goldGrad)" />
|
||||
<polygon points="50,-6 57,0 50,6" fill="rgba(0,0,0,0.25)" />
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<g class="ward-group" filter="url(#epicMagicGlow)">
|
||||
<circle class="ward-pulse" cx="50" cy="50" r="30" fill="rgba(56, 189, 248, 0.15)" stroke="#38BDF8" stroke-linecap="round" />
|
||||
<circle class="ward-pulse delay" cx="50" cy="50" r="30" fill="rgba(56, 189, 248, 0.15)" stroke="#38BDF8" stroke-linecap="round" />
|
||||
</g>
|
||||
|
||||
<g class="shield-main-group">
|
||||
<path class="shield-shard shard-tl" d="M 50 12 L 18 28 L 18 52 L 50 48 Z" fill="url(#metalBlueGrad)" />
|
||||
<path class="shield-shard shard-tr" d="M 50 12 L 82 28 L 82 52 L 50 48 Z" fill="url(#metalBlueGrad)" />
|
||||
<path class="shield-shard shard-b" d="M 18 52 C 18 78 50 92 50 92 C 50 92 82 78 82 52 L 50 48 Z" fill="url(#metalBlueGrad)" />
|
||||
</g>
|
||||
|
||||
<g class="sword-anchor-a">
|
||||
<g class="sword-slide">
|
||||
<use href="#epic-sword" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g class="sword-anchor-b">
|
||||
<g class="sword-slide">
|
||||
<use href="#epic-sword" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button onclick="changeState('state-wait')" style="border-color: #3B82F6;">🛡️ 结界维持中...</button>
|
||||
<button onclick="changeState('state-success')" style="border-color: #10B981; color: #10B981;">⚔️ 史诗验证成功</button>
|
||||
<button onclick="changeState('state-fail')" style="border-color: #EF4444; color: #EF4444;">💥 盾牌碎裂</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function changeState(newStateClass) {
|
||||
const svg = document.getElementById('captcha-svg');
|
||||
svg.classList.remove('state-wait', 'state-success', 'state-fail');
|
||||
svg.classList.add(newStateClass);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,50 @@
|
||||
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
|
||||
<defs>
|
||||
<!-- 渐变色定义 -->
|
||||
<linearGradient id="shieldGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#4F46E5" /> <!-- 科技靛蓝 -->
|
||||
<stop offset="100%" stop-color="#06B6D4" /> <!-- 灵动青色 -->
|
||||
</linearGradient>
|
||||
<linearGradient id="ringGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#10B981" /> <!-- 安全绿 -->
|
||||
<stop offset="100%" stop-color="#3B82F6" /> <!-- 信任蓝 -->
|
||||
</linearGradient>
|
||||
<!-- 发光滤镜 -->
|
||||
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feGaussianBlur stdDeviation="2" result="blur" />
|
||||
<feComposite in="SourceGraphic" in2="blur" operator="over" />
|
||||
</filter>
|
||||
</defs>
|
||||
|
||||
<!-- 外部盾牌形状 (象征安全防护) -->
|
||||
<path d="M 50 10 L 85 25 L 85 50 C 85 75 50 90 50 90 C 50 90 15 75 15 50 L 15 25 Z"
|
||||
fill="none"
|
||||
stroke="url(#shieldGrad)"
|
||||
stroke-width="4"
|
||||
stroke-linejoin="round" />
|
||||
|
||||
<!-- 内部动态扫描环 (象征行为分析与智能验证) -->
|
||||
<circle cx="50" cy="50" r="16"
|
||||
fill="none"
|
||||
stroke="url(#ringGrad)"
|
||||
stroke-width="4"
|
||||
stroke-dasharray="60 40"
|
||||
stroke-linecap="round"
|
||||
filter="url(#glow)">
|
||||
<animateTransform attributeName="transform" type="rotate" from="0 50 50" to="360 50 50" dur="1.5s" repeatCount="indefinite" />
|
||||
</circle>
|
||||
|
||||
<!-- 中心脉冲核心 (象征触控/鼠标焦点) -->
|
||||
<circle cx="50" cy="50" r="4" fill="#06B6D4">
|
||||
<animate attributeName="r" values="3; 6; 3" dur="1.5s" repeatCount="indefinite" />
|
||||
<animate attributeName="opacity" values="0.4; 1; 0.4" dur="1.5s" repeatCount="indefinite" />
|
||||
</circle>
|
||||
|
||||
<!-- 上下装饰轨迹线 (象征运动轨迹) -->
|
||||
<path d="M 35 38 Q 50 28 65 38" fill="none" stroke="#4F46E5" stroke-width="2" stroke-linecap="round" opacity="0.6">
|
||||
<animate attributeName="opacity" values="0.2; 0.8; 0.2" dur="2s" repeatCount="indefinite" />
|
||||
</path>
|
||||
<path d="M 35 62 Q 50 72 65 62" fill="none" stroke="#4F46E5" stroke-width="2" stroke-linecap="round" opacity="0.6">
|
||||
<animate attributeName="opacity" values="0.8; 0.2; 0.8" dur="2s" repeatCount="indefinite" />
|
||||
</path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -0,0 +1,191 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>史诗质感 - 真·双剑与盾行为验证 (锐利光环版)</title>
|
||||
<style>
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background-color: #0f172a;
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.captcha-container {
|
||||
position: relative;
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.captcha-icon {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* --- 1. 盾牌过渡 --- */
|
||||
.shield-shard {
|
||||
transform-origin: 50px 50px;
|
||||
transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1), fill 0.4s ease, opacity 0.5s ease;
|
||||
}
|
||||
|
||||
/* --- 2. 纯净空心脉冲 --- */
|
||||
.ward-group {
|
||||
transition: opacity 0.4s ease;
|
||||
}
|
||||
.ward-pulse {
|
||||
transform-origin: 50px 50px;
|
||||
animation: pulse-ward 2s cubic-bezier(0.1, 0.7, 0.3, 1) infinite;
|
||||
}
|
||||
.ward-pulse.delay {
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
/* 移除了夸张的缩放和粗细变化,改为更清爽的光圈扩散 */
|
||||
@keyframes pulse-ward {
|
||||
0% { transform: scale(0.6); opacity: 1; stroke-width: 6px; }
|
||||
100% { transform: scale(1.8); opacity: 0; stroke-width: 1px; }
|
||||
}
|
||||
|
||||
/* --- 3. 巨剑插入动画 --- */
|
||||
.sword-slide {
|
||||
transform: translateY(-85px);
|
||||
opacity: 0;
|
||||
transition: transform 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.4), opacity 0.4s ease;
|
||||
}
|
||||
|
||||
.sword-anchor-a { transform-origin: 50px 50px; transform: rotate(-45deg); }
|
||||
.sword-anchor-b { transform-origin: 50px 50px; transform: rotate(45deg); }
|
||||
|
||||
|
||||
/* --- 4. 状态控制 --- */
|
||||
.state-wait .ward-group { opacity: 1; }
|
||||
.state-wait .shield-shard {
|
||||
fill: url(#metalBlueGrad);
|
||||
transform: translate(0, 0) scale(1) rotate(0deg);
|
||||
opacity: 1;
|
||||
/* 【核心修复】:移除发光,改回黑色的物理实体阴影,保证盾牌边缘极其锐利 */
|
||||
filter: drop-shadow(0 6px 8px rgba(0,0,0,0.6));
|
||||
}
|
||||
|
||||
.state-success .ward-group { opacity: 0; }
|
||||
.state-success .shield-shard {
|
||||
fill: url(#metalGreenGrad);
|
||||
transform: translate(0, 0) scale(1) rotate(0deg);
|
||||
opacity: 1;
|
||||
filter: drop-shadow(0 6px 8px rgba(0,0,0,0.6));
|
||||
}
|
||||
.state-success .sword-slide { transform: translateY(-15px); opacity: 1; }
|
||||
|
||||
.state-fail .ward-group { opacity: 0; }
|
||||
.state-fail .shield-shard { fill: url(#metalRedGrad); opacity: 0.9; filter: none;}
|
||||
.state-fail .shard-tl { transform: translate(-25px, -30px) scale(0.9) rotateX(30deg) rotateY(-20deg) rotateZ(-15deg); opacity: 0.7; }
|
||||
.state-fail .shard-tr { transform: translate(25px, -30px) scale(0.9) rotateX(30deg) rotateY(20deg) rotateZ(15deg); opacity: 0.7; }
|
||||
.state-fail .shard-b { transform: translate(0, 35px) scale(0.8) rotateX(-20deg) rotateZ(5deg); opacity: 0.5; }
|
||||
|
||||
|
||||
.controls { display: flex; gap: 15px; }
|
||||
.controls button {
|
||||
padding: 12px 24px; font-size: 14px; font-weight: bold; cursor: pointer;
|
||||
border: 2px solid transparent; border-radius: 8px; background: #1e293b; color: #f1f5f9;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.controls button:hover { background: #334155; transform: translateY(-2px); }
|
||||
.controls button:active { transform: translateY(1px); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="captcha-container">
|
||||
<svg id="captcha-svg" class="captcha-icon state-wait" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="metalBlueGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#3B82F6" /><stop offset="50%" stop-color="#1E40AF" /><stop offset="100%" stop-color="#60A5FA" />
|
||||
</linearGradient>
|
||||
<linearGradient id="metalGreenGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#10B981" /><stop offset="50%" stop-color="#047857" /><stop offset="100%" stop-color="#34D399" />
|
||||
</linearGradient>
|
||||
<linearGradient id="metalRedGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#EF4444" /><stop offset="50%" stop-color="#B91C1C" /><stop offset="100%" stop-color="#F87171" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient id="bladeLight" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#f8fafc" /><stop offset="100%" stop-color="#94a3b8" />
|
||||
</linearGradient>
|
||||
<linearGradient id="bladeDark" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stop-color="#64748b" /><stop offset="100%" stop-color="#334155" />
|
||||
</linearGradient>
|
||||
<linearGradient id="goldGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#FDE047" /><stop offset="50%" stop-color="#EAB308" /><stop offset="100%" stop-color="#A16207" />
|
||||
</linearGradient>
|
||||
|
||||
<filter id="swordShadow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="3" dy="5" stdDeviation="2.5" flood-color="#000000" flood-opacity="0.7"/>
|
||||
</filter>
|
||||
|
||||
<filter id="cleanMagicGlow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="2" result="blur" />
|
||||
<feMerge>
|
||||
<feMergeNode in="blur" />
|
||||
<feMergeNode in="SourceGraphic" />
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<g id="epic-sword" filter="url(#swordShadow)">
|
||||
<polygon points="43,26 50,26 50,115" fill="url(#bladeLight)" />
|
||||
<polygon points="50,26 57,26 50,115" fill="url(#bladeDark)" />
|
||||
<rect x="45" y="4" width="10" height="22" fill="#1e293b" />
|
||||
<path d="M 45 6 L 55 10 M 45 12 L 55 16 M 45 18 L 55 22 M 45 24 L 55 28" stroke="#475569" stroke-width="2" />
|
||||
<polygon points="20,22 50,26 80,22 80,27 50,32 20,27" fill="#713F12" />
|
||||
<polygon points="20,22 50,26 80,22 50,24" fill="url(#goldGrad)" />
|
||||
<polygon points="50,-6 57,0 50,6 43,0" fill="url(#goldGrad)" />
|
||||
<polygon points="50,-6 57,0 50,6" fill="rgba(0,0,0,0.25)" />
|
||||
</g>
|
||||
</defs>
|
||||
|
||||
<g class="ward-group" filter="url(#cleanMagicGlow)">
|
||||
<circle class="ward-pulse" cx="50" cy="50" r="35" fill="none" stroke="#38BDF8" stroke-linecap="round" />
|
||||
<circle class="ward-pulse delay" cx="50" cy="50" r="35" fill="none" stroke="#38BDF8" stroke-linecap="round" />
|
||||
</g>
|
||||
|
||||
<g class="shield-main-group">
|
||||
<path class="shield-shard shard-tl" d="M 50 12 L 18 28 L 18 52 L 50 48 Z" fill="url(#metalBlueGrad)" />
|
||||
<path class="shield-shard shard-tr" d="M 50 12 L 82 28 L 82 52 L 50 48 Z" fill="url(#metalBlueGrad)" />
|
||||
<path class="shield-shard shard-b" d="M 18 52 C 18 78 50 92 50 92 C 50 92 82 78 82 52 L 50 48 Z" fill="url(#metalBlueGrad)" />
|
||||
</g>
|
||||
|
||||
<g class="sword-anchor-a">
|
||||
<g class="sword-slide">
|
||||
<use href="#epic-sword" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g class="sword-anchor-b">
|
||||
<g class="sword-slide">
|
||||
<use href="#epic-sword" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button onclick="changeState('state-wait')" style="border-color: #3B82F6;">🛡️ 结界维持中...</button>
|
||||
<button onclick="changeState('state-success')" style="border-color: #10B981; color: #10B981;">⚔️ 史诗验证成功</button>
|
||||
<button onclick="changeState('state-fail')" style="border-color: #EF4444; color: #EF4444;">💥 盾牌碎裂</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function changeState(newStateClass) {
|
||||
const svg = document.getElementById('captcha-svg');
|
||||
svg.classList.remove('state-wait', 'state-success', 'state-fail');
|
||||
svg.classList.add(newStateClass);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user