前端融球效果原理讲解+具体实现+模糊度,对比度基础教学
这是github链接,文末也有本人封装好的融球效果+讲解页面完整代码:
sq/UI/src/components/MetaballEffect at main · afigzb/sq (github.com)https://github.com/afigzb/sq/tree/main/UI/src/components/MetaballEffect讲解部分看这个静态页面截图即可:
融球组件代码:
/*** 融球效果 Web Component* 为容器内的元素提供融球效果,支持任意HTML内容*/
class MetaballContainer extends HTMLElement {constructor() {super();this.attachShadow({ mode: 'open' });this.blurIntensity = 10;this.contrastLevel = 20;this.init();}init() {this.shadowRoot.innerHTML = `<style>:host {display: block;position: relative;/* 核心:高对比度滤镜实现融球效果 */filter: contrast(${this.contrastLevel}) blur(0.5px);background: inherit;}::slotted(*) {/* 核心:为所有插槽内容添加模糊效果 */filter: blur(${this.blurIntensity}px) !important;}.container {width: 100%;height: 100%;position: relative;}</style><div class="container"><slot></slot></div>`;}/*** 设置模糊强度* @param {number} intensity - 模糊强度 (2-15)*/setBlur(intensity) {this.blurIntensity = intensity;this.updateStyles();}/*** 设置对比度* @param {number} level - 对比度级别 (10-40)*/setContrast(level) {this.contrastLevel = level;this.updateStyles();}/*** 更新样式* @private*/updateStyles() {const style = this.shadowRoot.querySelector('style');style.textContent = `:host {display: block;position: relative;filter: contrast(${this.contrastLevel}) blur(0.5px);background: inherit;}::slotted(*) {filter: blur(${this.blurIntensity}px) !important;}.container {width: 100%;height: 100%;position: relative;}`;}/*** 获取所有子元素* @returns {Array} 子元素数组*/getItems() {return Array.from(this.children);}/*** 获取当前模糊强度* @returns {number} 当前模糊强度*/getBlur() {return this.blurIntensity;}/*** 获取当前对比度* @returns {number} 当前对比度*/getContrast() {return this.contrastLevel;}
}// 注册Web Component
customElements.define('metaball-container', MetaballContainer);// 导出组件
export default MetaballContainer;
融球组件示例页面代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>融球控件 - Web Component</title><style>body {margin: 0;padding: 20px;background: #1a1a1a;font-family: Arial, sans-serif;color: white;}.demo-container {position: relative;width: 100vw;height: 80vh;background: #000;border-radius: 10px;overflow: hidden;}.demo-item {position: absolute;transition: all 0.1s ease;}.ball {width: 80px;height: 80px;border-radius: 50%;background: #ff6b6b;}.square {width: 60px;height: 60px;background: #4ecdc4;}.triangle {width: 0;height: 0;border-left: 30px solid transparent;border-right: 30px solid transparent;border-bottom: 52px solid #ffe66d;}.text-item {font-size: 24px;font-weight: bold;color: #a8e6cf;padding: 10px 20px;background: #a8e6cf;border-radius: 20px;}.controls {margin-bottom: 20px;display: flex;gap: 10px;align-items: center;}button {padding: 8px 16px;background: #4ecdc4;color: white;border: none;border-radius: 5px;cursor: pointer;}button:hover {background: #45b7aa;}.info {margin-bottom: 20px;padding: 15px;background: rgba(255, 255, 255, 0.1);border-radius: 8px;}</style>
</head>
<body><div class="info"><h2>融球控件 (Metaball Component)</h2><p>这是一个Web Component封装的融球控件,可以为任何插入的元素提供融球效果。</p><p>控件只负责融球效果,元素的移动由外部控制。</p></div><div class="controls"><button onclick="toggleAnimation()">开始/停止动画</button><button onclick="resetPositions()">重置位置</button><label>模糊强度: <input type="range" id="blurSlider" min="2" max="15" value="8" onchange="updateBlur(this.value)"><span id="blurValue">8</span>px</label><label>对比度: <input type="range" id="contrastSlider" min="10" max="40" value="20" onchange="updateContrast(this.value)"><span id="contrastValue">20</span></label></div><!-- 使用融球控件 --><metaball-container class="demo-container"><div class="demo-item ball" style="left: 100px; top: 100px;"></div><div class="demo-item square" style="left: 300px; top: 200px;"></div><div class="demo-item triangle" style="left: 500px; top: 150px;"></div><div class="demo-item text-item" style="left: 200px; top: 300px;">TEXT</div></metaball-container><script type="module">// 导入融球控件import MetaballContainer from './MetaballEffect.js';// 演示动画控制let animationId = null;let isAnimating = false;const items = [];// 初始化演示项目function initDemo() {const container = document.querySelector('metaball-container');const demoItems = container.querySelectorAll('.demo-item');demoItems.forEach((item, index) => {const rect = item.getBoundingClientRect();const containerRect = container.getBoundingClientRect();items.push({element: item,x: parseFloat(item.style.left) || 0,y: parseFloat(item.style.top) || 0,vx: (Math.random() - 0.5) * 2,vy: (Math.random() - 0.5) * 2,width: item.offsetWidth,height: item.offsetHeight});});}// 动画循环function animate() {if (!isAnimating) return;const container = document.querySelector('metaball-container');const containerRect = container.getBoundingClientRect();items.forEach(item => {// 更新位置item.x += item.vx;item.y += item.vy;// 边界检测if (item.x <= 0 || item.x >= containerRect.width - item.width) {item.vx *= -1;item.x = Math.max(0, Math.min(containerRect.width - item.width, item.x));}if (item.y <= 0 || item.y >= containerRect.height - item.height) {item.vy *= -1;item.y = Math.max(0, Math.min(containerRect.height - item.height, item.y));}// 应用位置item.element.style.left = `${item.x}px`;item.element.style.top = `${item.y}px`;});animationId = requestAnimationFrame(animate);}// 控制函数window.toggleAnimation = function() {isAnimating = !isAnimating;if (isAnimating) {animate();} else {cancelAnimationFrame(animationId);}};window.resetPositions = function() {items.forEach(item => {item.x = Math.random() * 400;item.y = Math.random() * 300;item.vx = (Math.random() - 0.5) * 2;item.vy = (Math.random() - 0.5) * 2;item.element.style.left = `${item.x}px`;item.element.style.top = `${item.y}px`;});};window.updateBlur = function(value) {const container = document.querySelector('metaball-container');container.setBlur(value);document.getElementById('blurValue').textContent = value;};window.updateContrast = function(value) {const container = document.querySelector('metaball-container');container.setContrast(value);document.getElementById('contrastValue').textContent = value;};// 初始化document.addEventListener('DOMContentLoaded', () => {// 等待Web Component注册完成setTimeout(() => {initDemo();}, 100);});// 鼠标交互演示document.addEventListener('mousemove', (e) => {if (!isAnimating) return;const container = document.querySelector('metaball-container');const rect = container.getBoundingClientRect();const mouseX = e.clientX - rect.left;const mouseY = e.clientY - rect.top;// 鼠标吸引效果items.forEach(item => {const dx = mouseX - (item.x + item.width / 2);const dy = mouseY - (item.y + item.height / 2);const distance = Math.sqrt(dx * dx + dy * dy);if (distance < 150) {const force = (150 - distance) / 150 * 0.01;item.vx += dx / distance * force;item.vy += dy / distance * force;}});});</script>
</body>
</html>
这是文首的讲解页面代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>融球效果原理讲解</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}body {font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;line-height: 1.6;color: #333;background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);min-height: 100vh;padding: 20px;}.container {max-width: 1200px;margin: 0 auto;background: white;border-radius: 20px;box-shadow: 0 20px 40px rgba(0,0,0,0.1);overflow: hidden;}.header {background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);color: white;padding: 40px;text-align: center;}.header h1 {font-size: 2.5em;margin-bottom: 10px;}.header p {font-size: 1.2em;opacity: 0.9;}.content {padding: 40px;}.section {margin-bottom: 50px;}.section h2 {color: #667eea;font-size: 1.8em;margin-bottom: 20px;border-bottom: 3px solid #667eea;padding-bottom: 10px;}.demo-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: 30px;margin: 30px 0;}.demo-box {background: #f8f9fa;border-radius: 15px;padding: 20px;border: 2px solid #e9ecef;transition: all 0.3s ease;}.demo-box:hover {transform: translateY(-5px);box-shadow: 0 10px 25px rgba(0,0,0,0.1);}.demo-box h3 {color: #495057;margin-bottom: 15px;font-size: 1.3em;}.demo-area {width: 100%;height: 200px;background: #000;border-radius: 10px;position: relative;overflow: hidden;margin: 15px 0;}.ball {position: absolute;width: 60px;height: 60px;background: #fff;border-radius: 50%;}.ball-1 { left: 50px; top: 70px; }.ball-2 { left: 100px; top: 70px; }/* 四种状态演示 */.state-1 .demo-area {/* 无模糊,无对比度 */}.state-2 .demo-area {/* 只有模糊,无对比度 */}.state-2 .ball {filter: blur(10px);}.state-3 .demo-area {/* 无模糊,只有对比度 */filter: contrast(20);}.state-4 .demo-area {/* 融球效果:容器对比度 + 元素模糊 */filter: contrast(20) blur(0.5px);}.state-4 .ball {filter: blur(10px);}.interactive-demo {background: #f8f9fa;border-radius: 15px;padding: 30px;margin: 30px 0;}.controls {display: flex;flex-wrap: wrap;gap: 20px;margin-bottom: 20px;align-items: center;}.control-group {display: flex;flex-direction: column;gap: 5px;}.control-group label {font-weight: 600;color: #495057;}.control-group input[type="range"] {width: 200px;height: 6px;border-radius: 3px;background: #ddd;outline: none;-webkit-appearance: none;}.control-group input[type="range"]::-webkit-slider-thumb {-webkit-appearance: none;appearance: none;width: 20px;height: 20px;border-radius: 50%;background: #667eea;cursor: pointer;}.value-display {font-weight: bold;color: #667eea;}.interactive-area {width: 100%;height: 300px;background: #000;border-radius: 10px;position: relative;overflow: hidden;}.movable-ball {position: absolute;width: 80px;height: 80px;background: #fff;border-radius: 50%;transition: all 0.1s ease;display: flex;align-items: center;justify-content: center;font-weight: bold;color: #333;}.ball-a { left: 100px; top: 110px; background: #ff6b6b; }.ball-b { left: 200px; top: 110px; background: #4ecdc4; }.explanation {background: #e3f2fd;border-left: 4px solid #2196f3;padding: 20px;margin: 20px 0;border-radius: 0 10px 10px 0;}.explanation h4 {color: #1976d2;margin-bottom: 10px;}.code-block {background: #2d3748;color: #e2e8f0;padding: 20px;border-radius: 10px;font-family: 'Courier New', monospace;margin: 20px 0;overflow-x: auto;font-size: 14px;line-height: 1.5;}.code-block .comment {color: #68d391;}.code-block .property {color: #63b3ed;}.code-block .value {color: #fbb6ce;}.highlight {background: #ffd54f;padding: 2px 4px;border-radius: 3px;color: #333;}.principle-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));gap: 20px;margin: 30px 0;}.principle-card {background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);color: white;padding: 25px;border-radius: 15px;text-align: center;}.principle-card h4 {font-size: 1.3em;margin-bottom: 15px;}.principle-card .icon {font-size: 3em;margin-bottom: 15px;opacity: 0.8;}.warning {background: #fff3cd;border: 1px solid #ffeaa7;border-radius: 8px;padding: 15px;margin: 20px 0;color: #856404;}.warning strong {color: #d63031;}</style>
</head>
<body><div class="container"><div class="header"><h1>🌊 融球效果原理讲解</h1><p>深入理解容器对比度 + 元素模糊如何创造神奇的融球效果</p></div><div class="content"><!-- 原理概述 --><div class="section"><h2>🎯 核心原理</h2><p>融球效果(Metaball Effect)的实现原理是:<span class="highlight">容器应用高对比度滤镜</span> + <span class="highlight">元素应用模糊滤镜</span>。当模糊的元素靠近时,它们的边缘会在高对比度的作用下自然融合。</p><div class="warning"><strong>重要:</strong>很多人误以为是同时对元素应用模糊和对比度,实际上正确的做法是分层应用 - 容器负责对比度,元素负责模糊!</div><div class="principle-grid"><div class="principle-card"><div class="icon">📦</div><h4>容器对比度</h4><p>容器应用高对比度滤镜,将灰色区域转换为黑白分明的边界</p></div><div class="principle-card"><div class="icon">🌫️</div><h4>元素模糊</h4><p>每个元素应用模糊滤镜,创造柔和的渐变边缘</p></div><div class="principle-card"><div class="icon">🔗</div><h4>融合效果</h4><p>模糊元素的重叠区域经过容器对比度处理后形成连接</p></div></div></div><!-- 四种状态对比 --><div class="section"><h2>📚 四种状态对比演示</h2><p>让我们通过四种不同的状态来理解融球效果的形成过程:</p><div class="demo-grid"><div class="demo-box state-1"><h3>状态 1: 无模糊 + 无对比度</h3><div class="demo-area"><div class="ball ball-1"></div><div class="ball ball-2"></div></div><div class="code-block">
<span class="comment">/* 容器 */</span>
.<span class="property">container</span> {<span class="comment">/* 无滤镜 */</span>
}<span class="comment">/* 元素 */</span>
.<span class="property">ball</span> {<span class="comment">/* 无滤镜 */</span>
}</div><p>两个清晰的圆球,边界分明,无任何效果。</p></div><div class="demo-box state-2"><h3>状态 2: 有模糊 + 无对比度</h3><div class="demo-area"><div class="ball ball-1"></div><div class="ball ball-2"></div></div><div class="code-block">
<span class="comment">/* 容器 */</span>
.<span class="property">container</span> {<span class="comment">/* 无滤镜 */</span>
}<span class="comment">/* 元素 */</span>
.<span class="property">ball</span> {<span class="property">filter</span>: <span class="value">blur(10px)</span>;
}</div><p>球体变模糊,但没有融合效果,只是单纯的模糊。</p></div><div class="demo-box state-3"><h3>状态 3: 无模糊 + 有对比度</h3><div class="demo-area"><div class="ball ball-1"></div><div class="ball ball-2"></div></div><div class="code-block">
<span class="comment">/* 容器 */</span>
.<span class="property">container</span> {<span class="property">filter</span>: <span class="value">contrast(20)</span>;
}<span class="comment">/* 元素 */</span>
.<span class="property">ball</span> {<span class="comment">/* 无滤镜 */</span>
}</div><p>边界更加锐利,但仍然没有融合效果。</p></div><div class="demo-box state-4"><h3>状态 4: 有模糊 + 有对比度</h3><div class="demo-area"><div class="ball ball-1"></div><div class="ball ball-2"></div></div><div class="code-block">
<span class="comment">/* 容器 */</span>
.<span class="property">container</span> {<span class="property">filter</span>: <span class="value">contrast(20) blur(0.5px)</span>;
}<span class="comment">/* 元素 */</span>
.<span class="property">ball</span> {<span class="property">filter</span>: <span class="value">blur(10px)</span>;
}</div><p>🎉 完美的融球效果!模糊的边缘在高对比度下形成自然连接。</p></div></div></div><!-- 技术原理详解 --><div class="section"><h2>🔬 技术原理详解</h2><!-- 基础概念讲解 --><div class="section"><h3>📖 基础概念:什么是模糊和对比度?</h3><div class="explanation"><h4>🌫️ 什么是"模糊"?</h4><p>想象一下你摘掉眼镜看东西,或者相机没有对焦时的效果 - 这就是模糊。在计算机图形学中,模糊就是让图像的边缘变得不清晰,从锐利的边界变成柔和的过渡。</p></div><div class="demo-grid"><div class="demo-box"><h4>模糊效果对比</h4><div style="display: flex; gap: 15px; align-items: center; margin: 15px 0;"><div style="width: 50px; height: 50px; background: #ff6b6b; border-radius: 50%;"></div><span>→</span><div style="width: 50px; height: 50px; background: #ff6b6b; border-radius: 50%; filter: blur(3px);"></div></div><p style="text-align: center; color: #666;">清晰的圆 → 模糊的圆</p><p><strong>看到了吗?</strong>右边的圆边缘变得柔和了,不再是硬邦邦的边界。</p></div><div class="demo-box"><h4>Web开发中的模糊应用</h4><ul style="margin-left: 20px;"><li>🖼️ 图片背景虚化效果</li><li>🎭 遮罩层后的内容模糊</li><li>🔍 搜索结果的渐进加载</li><li>🎨 毛玻璃效果 (backdrop-filter)</li><li>💫 悬停时的焦点突出</li></ul><p><strong>共同点:</strong>都是通过模糊来创造视觉层次和焦点!</p></div></div><div class="explanation"><h4>⚡ 什么是"对比度"?</h4><p>对比度就是黑白之间的差别程度。高对比度意味着黑的更黑,白的更白,中间的灰色会被"推向"黑色或白色。就像调节电视机的对比度旋钮一样。</p></div><div class="demo-grid"><div class="demo-box"><h4>对比度效果对比</h4><div style="background: linear-gradient(to right, #000, #333, #666, #999, #ccc, #fff); height: 40px; margin: 10px 0; border-radius: 5px; position: relative;"><span style="position: absolute; left: 5px; top: 10px; color: white; font-size: 12px; font-weight: bold;">正常对比度</span></div><div style="background: linear-gradient(to right, #000, #333, #666, #999, #ccc, #fff); height: 40px; margin: 10px 0; border-radius: 5px; filter: contrast(5); position: relative;"><span style="position: absolute; left: 5px; top: 10px; color: white; font-size: 12px; font-weight: bold;">高对比度</span></div><p><strong>看到了吗?</strong>下面的渐变中,灰色部分变少了,更多的是纯黑和纯白。</p></div><div class="demo-box"><h4>Web开发中的对比度应用</h4><ul style="margin-left: 20px;"><li>🎨 主题切换中的色彩增强</li><li>🖼️ 图像处理和滤镜效果</li><li>📱 无障碍设计的可读性提升</li><li>🎭 蒙版效果的边缘锐化</li><li>🔲 SVG图标的清晰度优化</li></ul><p><strong>共同点:</strong>都是通过对比度来增强视觉效果的清晰度!</p></div></div></div><!-- CSS中的模糊和对比度 --><div class="section"><h3>💻 CSS中如何实现模糊和对比度?</h3><div class="explanation"><h4>CSS滤镜 (filter) 是什么?</h4><p>CSS滤镜就像给图片加特效的工具,就像美图软件里的滤镜一样。我们可以用它来让元素变模糊、调整对比度等。</p></div><div class="code-block">
<span class="comment">/* 基础语法 - 就像给元素"戴眼镜" */</span>
.<span class="property">my-element</span> {<span class="property">filter</span>: <span class="value">blur(5px)</span>; <span class="comment">/* 让元素变模糊 */</span><span class="property">filter</span>: <span class="value">contrast(2)</span>; <span class="comment">/* 增加对比度 */</span><span class="property">filter</span>: <span class="value">blur(5px) contrast(2)</span>; <span class="comment">/* 同时应用多个效果 */</span>
}</div><div class="demo-grid"><div class="demo-box"><h4>模糊值的含义</h4><div class="code-block">
<span class="comment">/* 数字越大,越模糊 */</span>
<span class="property">filter</span>: <span class="value">blur(0px)</span>; <span class="comment">/* 不模糊 */</span>
<span class="property">filter</span>: <span class="value">blur(3px)</span>; <span class="comment">/* 轻微模糊 */</span>
<span class="property">filter</span>: <span class="value">blur(10px)</span>; <span class="comment">/* 很模糊 */</span>
<span class="property">filter</span>: <span class="value">blur(20px)</span>; <span class="comment">/* 非常模糊 */</span></div><p><strong>记住:</strong>数字越大,越看不清!</p></div><div class="demo-box"><h4>对比度值的含义</h4><div class="code-block">
<span class="comment">/* 数字越大,黑白越分明 */</span>
<span class="property">filter</span>: <span class="value">contrast(1)</span>; <span class="comment">/* 正常 */</span>
<span class="property">filter</span>: <span class="value">contrast(2)</span>; <span class="comment">/* 增强一点 */</span>
<span class="property">filter</span>: <span class="value">contrast(10)</span>; <span class="comment">/* 很强 */</span>
<span class="property">filter</span>: <span class="value">contrast(20)</span>; <span class="comment">/* 非常强 */</span></div><p><strong>记住:</strong>数字越大,黑白越分明!</p></div></div></div><!-- 融球效果中的应用 --><div class="section"><h3>🎯 它们在融球效果中的神奇作用</h3><div class="explanation"><h4>为什么模糊+对比度能产生融球效果?</h4><p>这就像一个魔术!让我们一步步揭秘:</p></div><div class="demo-grid"><div class="demo-box"><h4>第一步:模糊创造"过渡地带"</h4><div style="display: flex; gap: 10px; align-items: center; margin: 15px 0;"><div style="width: 40px; height: 40px; background: #fff; border: 2px solid #333; border-radius: 50%;"></div><span>+</span><div style="width: 40px; height: 40px; background: #fff; border: 2px solid #333; border-radius: 50%;"></div><span>=</span><span>两个分离的圆</span></div><div style="display: flex; gap: 10px; align-items: center; margin: 15px 0; background: #333; padding: 10px; border-radius: 5px;"><div style="width: 40px; height: 40px; background: #fff; border-radius: 50%; filter: blur(5px);"></div><span style="color: #fff;">+</span><div style="width: 40px; height: 40px; background: #fff; border-radius: 50%; filter: blur(5px);"></div><span style="color: #fff;">=</span><span style="color: #fff;">边缘变柔和了</span></div><p><strong>关键:</strong>模糊让硬边界变成了柔和的"过渡地带"</p></div><div class="demo-box"><h4>第二步:对比度"决定"黑白</h4><p>当两个模糊的圆靠近时,它们的"过渡地带"会重叠,产生灰色区域。</p><p><strong>这时对比度出场了!</strong></p><ul style="margin-left: 20px; margin-top: 10px;"><li>🔍 对比度说:"灰色?不行!"</li><li>⚫ "要么变成黑色(背景)"</li><li>⚪ "要么变成白色(连接)"</li><li>🎉 结果:两个圆"融合"了!</li></ul></div></div><div class="explanation"><h4>具体在代码中是怎么做的?</h4><p>我们需要分工合作:</p></div><div class="code-block">
<span class="comment">/* 容器负责"决定黑白" */</span>
.<span class="property">container</span> {<span class="property">filter</span>: <span class="value">contrast(20)</span>; <span class="comment">/* 我来决定什么是黑,什么是白! */</span>
}<span class="comment">/* 元素负责"变模糊" */</span>
.<span class="property">ball</span> {<span class="property">filter</span>: <span class="value">blur(10px)</span>; <span class="comment">/* 我来创造柔和的边缘! */</span>
}<span class="comment">/* 结果:当模糊的球靠近时,重叠的灰色区域被对比度"判决"为白色连接! */</span></div></div><div class="explanation"><h4>总结:融球效果的"魔法公式"</h4><p><strong>模糊</strong>(创造柔和边缘)+ <strong>对比度</strong>(决定黑白)= <strong>融球效果</strong>(液体般的融合)</p><p>关键在于分层应用:容器负责对比度处理,元素负责模糊效果,两者协同工作创造出自然的融合效果。</p></div></div><!-- 交互式演示 --><div class="section"><h2>🎮 交互式演示</h2><p>观看下面的自动演示,体验融球效果的形成过程:</p><div class="interactive-demo"><div class="controls"><div class="control-group"><label>元素模糊强度: <span class="value-display" id="blurValue">10</span>px</label><input type="range" id="blurSlider" min="0" max="20" value="10"></div><div class="control-group"><label>容器对比度: <span class="value-display" id="contrastValue">20</span></label><input type="range" id="contrastSlider" min="1" max="50" value="20"></div><div class="control-group"><label>容器额外模糊: <span class="value-display" id="containerBlurValue">0.5</span>px</label><input type="range" id="containerBlurSlider" min="0" max="3" step="0.1" value="0.5"></div></div><div class="interactive-area" id="interactiveArea"><div class="movable-ball ball-a" id="ballA">A</div><div class="movable-ball ball-b" id="ballB">B</div></div><p style="margin-top: 15px; color: #666;">💡 <strong>提示:</strong>调整上方的参数,观察球体的自动运动和融合效果。试试将模糊或对比度调到0,看看会发生什么!</p></div></div><!-- 实际应用 --><div class="section"><h2>🚀 实际应用场景</h2><div class="demo-grid"><div class="demo-box"><h3>🎨 UI设计</h3><p>流体按钮、动态加载指示器、有机形状的界面元素</p></div><div class="demo-box"><h3>🎮 游戏开发</h3><p>液体物理效果、粒子系统、动态地形变化</p></div><div class="demo-box"><h3>📱 移动应用</h3><p>手势反馈效果、动态图标、流体导航</p></div><div class="demo-box"><h3>🎬 动画制作</h3><p>角色变形、液体模拟、有机过渡效果</p></div></div></div><!-- 总结 --><div class="section"><h2>📝 总结</h2><div class="explanation"><h4>融球效果的关键要素:</h4><ul style="margin-left: 20px; margin-top: 10px;"><li><strong>分层应用</strong>:容器应用对比度,元素应用模糊</li><li><strong>元素模糊</strong>:为形状创建柔和的边缘渐变</li><li><strong>容器对比度</strong>:将重叠的渐变区域转换为清晰的连接</li><li><strong>参数平衡</strong>:模糊强度和对比度需要合理搭配</li><li><strong>Web Component封装</strong>:使用Shadow DOM实现样式隔离和复用</li></ul></div><p>理解了这个分层滤镜的原理,你就掌握了融球效果的精髓。通过Web Component的封装,可以轻松地在任何项目中应用这种效果,创造出令人印象深刻的用户体验!</p></div></div></div><script type="module">// 导入融球控件(模拟导入,实际使用时需要正确的路径)// import MetaballContainer from './MetaballEffect.js';// 交互式演示控制const interactiveArea = document.getElementById('interactiveArea');const blurSlider = document.getElementById('blurSlider');const contrastSlider = document.getElementById('contrastSlider');const containerBlurSlider = document.getElementById('containerBlurSlider');const blurValue = document.getElementById('blurValue');const contrastValue = document.getElementById('contrastValue');const containerBlurValue = document.getElementById('containerBlurValue');// 更新滤镜效果function updateFilters() {const blur = blurSlider.value;const contrast = contrastSlider.value;const containerBlur = containerBlurSlider.value;// 更新显示值blurValue.textContent = blur;contrastValue.textContent = contrast;containerBlurValue.textContent = containerBlur;// 应用滤镜(按照正确的融球原理)interactiveArea.style.filter = `contrast(${contrast}) blur(${containerBlur}px)`;const balls = interactiveArea.querySelectorAll('.movable-ball');balls.forEach(ball => {ball.style.filter = `blur(${blur}px)`;});}// 绑定滑块事件blurSlider.addEventListener('input', updateFilters);contrastSlider.addEventListener('input', updateFilters);containerBlurSlider.addEventListener('input', updateFilters);// 初始化updateFilters();// 自动演示动画function autoDemo() {const ballA = document.getElementById('ballA');const ballB = document.getElementById('ballB');let time = 0;function animate() {time += 0.02;const centerX = interactiveArea.offsetWidth / 2 - 40;const centerY = interactiveArea.offsetHeight / 2 - 40;ballA.style.left = (centerX - 50 + Math.cos(time) * 40) + 'px';ballA.style.top = (centerY + Math.sin(time * 0.7) * 25) + 'px';ballB.style.left = (centerX + 50 + Math.cos(time + Math.PI) * 40) + 'px';ballB.style.top = (centerY + Math.sin(time * 0.7 + Math.PI) * 25) + 'px';requestAnimationFrame(animate);}// 立即开始自动演示animate();}autoDemo();</script>
</body>
</html>