0%

网页羽化效果

需求

点这里
先说需求, 如上图所示, 要实现内容区域在浏览器顶部与底部羽化效果.

便捷通道!

  1. 如果背景非图片与视频, 仅是纯色的话, 直接使用 css3 中的linear-gradient, 在上面盖个渐变色即可, 非常简单.

    1
    2
    3
    4
    5
    6
    7
    .feathering {
    background-image: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0) 84%,
    rgba(255, 255, 255, 1) 100%
    );
    }
  2. 如果背景色不固定, 比如是渐变, 随机或者是视频与图片 此时内容区域为文本,
    可以直接使用-webkit-background-clip实现(注意兼容)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .feathering {
    background-image: linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0) 84%,
    rgba(255, 255, 255, 1) 100%
    );
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    }

如果以上两种情况都不适合你的话, 那还是老老实实的跟着下面走吧!

思路

  1. 使用canvas渲染出背景图片(或者视频)
  2. 结合canvas中的globalCompositeOperationcreateLinearGradient处理背景图
  3. 将背景图悬浮到内容上层, 并且给个 css 样式pointer-events: none;

直接上 CodePen!

可以在上面codepen中的文本区域滚动, 看到效果已经实现了!

代码分析

这里主要分析JS代码为主

1
2
3
4
5
6
7
8
//    step 2 设置后面会用到的合成渐变
let gradient = ctx.createLinearGradient(0, 0, 0, height);
gradient.addColorStop(0, "rgba(0,0,0,1)");
gradient.addColorStop(0.22, "rgba(0,0,0,0)");
gradient.addColorStop(0.78, "rgba(0,0,0,0)");
gradient.addColorStop(1, "rgba(0,0,0,1)");
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);

这里设置渐变的主要目的是为了后续使用canvas中的, globalCompositeOperation 我们将其值设置为source-in,
该值的主要目的是只保留新、旧图形重叠的新图形区域,其余皆变为透明。, 也就意味着以内容高度为基准, 0~0.220.78~1 这个黑色渐变区域将会显示图片,
0.22~0.78这个区域将会呈现透明效果.

1
2
3
4
5
6
7
//    step 3 将图片渲染到canvas里面
let oImg = new Image();
oImg.onload = () => {
ctx.globalCompositeOperation = "source-in";
ctx.drawImage(oImg, 0, 0, width, height);
};
oImg.src = `https://i.imgur.com/9EjhC6W.jpg`;

这里需要注意的地方是ctx.drawImage必须要确保调用时图片已加载不然啥效果都没有, 所以我们把它放到了oImg.onload里面执行.
我们在drawImage之间设置了globalCompositeOperation来告诉canvas我们要以那种合成效果绘制图片.

总结

如果你考虑兼容与可控性, 那么使用canvas将是最好的方式.