已实现三种CSS3滤镜,如何用CSS3/JavaScript实现Duotone等四种效果?
嘿,你已经搞定了Greyscale、Sepia和Invert这三个基础滤镜,很棒!针对剩下的Duotone、Warm、Cool和Dramatic这四个效果,我整理了CSS3和JavaScript的实用实现方案,都是实际项目里常用的,你可以直接参考调整:
Duotone(双色调)
双色调的核心是用两种颜色替换原图的灰度层次,保留明暗信息。这里有两种常用方法:
CSS3 实现(无需JS)
利用伪元素叠加渐变层,配合混合模式实现,兼容性很好:
.duotone-image { position: relative; /* 先转灰度让双色调效果更纯粹,也可以去掉保留原图色彩基础 */ filter: grayscale(100%); } .duotone-image::after { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; /* 自定义双色调颜色,这里用深橙+浅黄,可随意替换 */ background: linear-gradient(#ff7f50, #ffffcc); /* 混合模式保留原图亮度,只替换颜色 */ mix-blend-mode: color; pointer-events: none; /* 不干扰图片上的交互操作 */ }
JavaScript Canvas 实现
如果需要动态调整颜色或更精确控制,用Canvas操作像素:
// 给Canvas应用双色调 function addDuotone(canvas, primaryColor, secondaryColor) { const ctx = canvas.getContext('2d'); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); const pixels = imgData.data; for (let i = 0; i < pixels.length; i += 4) { // 计算当前像素的亮度(灰度值) const brightness = 0.299 * pixels[i] + 0.587 * pixels[i+1] + 0.114 * pixels[i+2]; // 根据亮度比例混合两种颜色 const ratio = brightness / 255; pixels[i] = primaryColor.r + (secondaryColor.r - primaryColor.r) * ratio; pixels[i+1] = primaryColor.g + (secondaryColor.g - primaryColor.g) * ratio; pixels[i+2] = primaryColor.b + (secondaryColor.b - primaryColor.b) * ratio; // Alpha通道保持不变 } ctx.putImageData(imgData, 0, 0); } // 使用示例:给id为"my-canvas"的Canvas应用蓝紫双色调 const canvas = document.getElementById('my-canvas'); addDuotone(canvas, {r: 30, g: 30, b: 100}, {r: 150, g: 80, b: 200});
Warm(暖色调)
暖色调本质是让图像偏向黄、红系,增强温暖感,用CSS3滤镜组合就能轻松实现:
.warm-filter { /* sepia加暖黄底色,saturate增强色彩,hue-rotate往红偏,brightness提亮 */ filter: sepia(35%) saturate(150%) hue-rotate(-15deg) brightness(105%); }
你可以微调参数:比如增加sepia值会更黄,提高saturate让暖色调更浓郁,hue-rotate的度数可以调整偏红或偏黄的程度。
Cool(冷色调)
冷色调偏向蓝、青系,营造清冷感,同样用CSS滤镜组合:
.cool-filter { /* hue-rotate转到蓝绿系,saturate增强冷色,brightness压暗一点,contrast增强细节 */ filter: hue-rotate(190deg) saturate(130%) brightness(95%) contrast(105%); }
想要更冷的效果,可以把hue-rotate调到200-220deg,或者降低brightness的值。
Dramatic(戏剧性)
戏剧性效果核心是拉大明暗对比,让亮部更亮、暗部更暗,同时增强色彩饱和度,突出视觉冲击力:
CSS3 实现
.dramatic-filter { /* 高对比度+压暗整体+增强饱和度+轻微灰度弱化杂色 */ filter: contrast(160%) brightness(85%) saturate(120%) grayscale(10%); }
想要更强烈的戏剧感,可以尝试把contrast加到180%,或者加上sepia(10%)暖化暗部。
JavaScript Canvas 实现(自定义明暗曲线)
如果需要精细控制明暗阈值,用Canvas调整像素:
function addDramaticEffect(canvas) { const ctx = canvas.getContext('2d'); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); const pixels = imgData.data; for (let i = 0; i < pixels.length; i += 4) { // 计算灰度值 const gray = 0.299 * pixels[i] + 0.587 * pixels[i+1] + 0.114 * pixels[i+2]; // 戏剧性调整:暗部更暗,亮部更亮 let adjusted = gray < 128 ? gray * 0.7 : gray * 1.4; // 确保像素值在0-255范围内 adjusted = Math.min(255, Math.max(0, adjusted)); // 应用到RGB通道,保留Alpha pixels[i] = pixels[i+1] = pixels[i+2] = adjusted; } ctx.putImageData(imgData, 0, 0); }
这些参数都可以根据你的具体需求微调,比如调整滤镜百分比、颜色值,直到达到你想要的效果。
内容的提问来源于stack exchange,提问作者Shibbir
相关产品推荐
相关产品推荐

