如何实现每次交互使方形加深10%的渐进式变暗效果?
解决渐进式变暗/提亮的问题
问题分析
你用filter: brightness()的思路存在几个明显问题:
- 直接从
elem.style.filter截取数值不可靠——初始时元素内联样式无filter属性的话,slice(11, -2)会得到空字符串,导致后续数值计算出错; brightness()的百分比逻辑:100%是元素原始亮度,低于100%变暗,高于100%提亮,但并非1000%就能让所有颜色变白——它是在原始颜色基础上乘以亮度系数,原始颜色本身非纯白的话,再高的亮度也无法变成纯白;- 代码里
lightenMode每次加100%,和你“每次调整10%”的需求不符,边界判断逻辑也有漏洞。
优化后的实现
方案1:修正brightness值管理逻辑(基于你的原始思路)
用元素自定义属性存储当前亮度值,避免解析样式字符串的麻烦:
// 初始化亮度值,避免首次操作出错 const initBrightness = (elem) => { if (!elem.dataset.brightness) { elem.dataset.brightness = '100'; // 初始为原始亮度(100%) elem.style.filter = 'brightness(100%)'; } }; const shadingMode = (elem) => { initBrightness(elem); let current = parseInt(elem.dataset.brightness); if (current > 0) { current -= 10; elem.dataset.brightness = current.toString(); elem.style.filter = `brightness(${current}%)`; } }; const lightenMode = (elem) => { initBrightness(elem); let current = parseInt(elem.dataset.brightness); // 无需设到1000%,200%已足够明显提亮,且避免性能浪费 if (current < 200) { current += 10; elem.dataset.brightness = current.toString(); elem.style.filter = `brightness(${current}%)`; } };
方案2:叠加黑色实现精准“加深”(更贴合“增加10%黑色”需求)
如果方形是纯色背景,直接叠加黑色层的方式效果更可控:
<!-- 给方形套容器,内部放内容层和黑色叠加层 --> <div class="square-container"> <div class="square-content">你的内容</div> </div>
.square-container { position: relative; width: 200px; height: 200px; background: #your-original-color; /* 替换为你的方形底色 */ } .square-content { width: 100%; height: 100%; position: relative; z-index: 1; } .square-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: #000; opacity: 0; z-index: 0; }
// 初始化黑色叠加层 const initOverlay = (elem) => { if (!elem.querySelector('.square-overlay')) { const overlay = document.createElement('div'); overlay.className = 'square-overlay'; elem.appendChild(overlay); elem.dataset.darkness = '0'; // 初始暗度0% } }; const shadingMode = (elem) => { initOverlay(elem); const overlay = elem.querySelector('.square-overlay'); let current = parseInt(elem.dataset.darkness); if (current < 100) { current += 10; elem.dataset.darkness = current.toString(); overlay.style.opacity = current / 100; } }; const lightenMode = (elem) => { initOverlay(elem); const overlay = elem.querySelector('.square-overlay'); let current = parseInt(elem.dataset.darkness); if (current > 0) { current -= 10; elem.dataset.darkness = current.toString(); overlay.style.opacity = current / 100; } };
关键说明
- 方案1适合保留元素原有纹理、渐变的场景,但提亮无法让非白色元素变成纯白;
- 方案2通过叠加黑色实现“增加10%黑色”的效果,暗度到100%时完全变黑,效果精准可控;
- 用
dataset存储数值比解析内联样式更可靠,避免样式字符串解析出错的问题。
内容的提问来源于stack exchange,提问作者Stepa Frolov
相关产品推荐
相关产品推荐

