Home  >  Article  >  Web Front-end  >  如何通过 HTML5 实现 iOS 7 的实时毛玻璃模糊效果?

如何通过 HTML5 实现 iOS 7 的实时毛玻璃模糊效果?

WBOY
WBOYOriginal
2016-06-07 08:42:113725browse

回复内容:

所谓的毛玻璃效果其实是半透明+模糊,可以用CSS filter实现。
时间不多,就抛个砖,题主可以自己找一下文档和更多案例。
filter - CSS
<code class="language-css"><span class="nt">div</span> <span class="p">{</span>
    <span class="o">-</span><span class="n">moz</span><span class="o">-</span><span class="n">filter</span><span class="o">:</span> <span class="n">blur</span><span class="p">(</span><span class="m">5px</span><span class="p">);</span>
    <span class="o">-</span><span class="n">webkit</span><span class="o">-</span><span class="n">filter</span><span class="o">:</span> <span class="n">blur</span><span class="p">(</span><span class="m">5px</span><span class="p">);</span>
    <span class="o">-</span><span class="n">o</span><span class="o">-</span><span class="n">filter</span><span class="o">:</span> <span class="n">blur</span><span class="p">(</span><span class="m">5px</span><span class="p">);</span>
    <span class="o">-</span><span class="n">ms</span><span class="o">-</span><span class="n">filter</span><span class="o">:</span> <span class="n">blur</span><span class="p">(</span><span class="m">5px</span><span class="p">);</span>
    <span class="n">filter</span><span class="o">:</span> <span class="n">blur</span><span class="p">(</span><span class="m">5px</span><span class="p">);</span>
<span class="p">}</span>
</code>
推荐这篇博客小tip: 使用CSS将图片转换成模糊(毛玻璃)效果 « 张鑫旭介绍了三种方法。
分别是目前大多数人说的CSS3的filter,还有SVG的滤镜,和用Canvas实现高斯模糊StackBlur
我来补实际的效果图吧,方法是按 @孟爽paula 来的,弹出的时候底层加模糊,弹出层加透明。
初始状态:
如何通过 HTML5 实现 iOS 7 的实时毛玻璃模糊效果?
modal弹出后:
如何通过 HTML5 实现 iOS 7 的实时毛玻璃模糊效果?ios6+没问题,android得4.4。
所以更通用一点的得用Canvas来模拟,不过这个我还没试。 补充一个 Canvas 的方案:使用 Canvas 绘制网页快照,然后进行高斯模糊处理可以实现 Blur with Canvas
模糊掉的 B站(图片似乎不会被绘入 canvas):
如何通过 HTML5 实现 iOS 7 的实时毛玻璃模糊效果?
参考:
  1. html2canvas
  2. Using HTML5/Canvas/Javascript to take screenshots
  3. StackBlur
我想知道。支持CSS3的IE11 IE10反而不支持这种特效了。ie7-9还能支持。我已测试了很久。谷歌,火狐,ie7-9都能实现。实现的效果好坏,先不谈。至少IMG肯定都能搞定。只有IE10-11就是两个奇葩。filter:blur,svg引用,filter: progid:DXImageTransform.Microsoft.Blur全都没效果。 -webkit-backdrop-filter:blur(15px);
background:rgba(255,255,255,0.4);

不谢。backdrop-filter:blur会将上层部分模糊,用法类似filter:xxx!backdrop-filter只支持IOS9.1+,详情:Can I use... Support tables for HTML5, CSS3, etc

另详解:高级CSS filters_filter, backdrop-filter, filter() 教程_w3cplus 使用H5是可以实现iOS7风格毛玻璃效果的。但是不代表你可以随意使用这种效果。这里面需要一些前提条件。

从技术的角度分析这个事儿需要满足几个技术上的必备条件:
1、需要能将图片模糊的滤镜。
2、需要捕获到毛玻璃浮层下面所有内容的图像信息。就好像截屏。
3、需要让图片运动能与浏览器滚动同步。主要难点在于实时同步,尤其是处理滚动的惯性。

实现的思路就是对毛玻璃浮层之下的内容进行“捕屏”获取图片资源。然后以此图片进行模糊处理并作为毛玻璃浮层的背景层。之后需要一些js代码监视内容滚动,同步调整毛玻璃层背景图的position使其能与内容滚动保持同步。

以目前浏览器对H5的支持,第一条可以通过CSS Filter实现。如 @winter所述。第二条也能实现,需要神奇的html2canvas。第三条比较麻烦,需要自己处理。要想做到跨浏览器跨设备支持难度不小。

整个效果做出来大概就是 @姚冬给的这个例子。浏览器方面IE 10+,目前的Chrome、Firefox、Safari都能跑出效果来。但是这个方案还不够实战价值,主要问题有:
1、你必须保证浮层下面的内容没有Gif、Flash、视频、滚动播放的文字图片以及任何可能会动的东西。因为捕屏的开销还是比较大的。尤其是有大量图片资源的时候。
2、流畅度的问题。桌面浏览器中Chrome、IE、Firefox表现尚可。Safari因为设计上比别的浏览器有更多功耗方面的要求,所以必须强制开启GPU加速后才能流畅。移动版需要使用最新的iPhone 5s、iPad Air才能有接近流畅的表现。更不用提有的Android版Chrome对于Blur滤镜糟糕的表现效果。
3、同步滚动的问题。因为不同浏览器对于滚动的处理有所不同。尤其是滚动惯性的问题。例如在iOS上触摸滚动内容时当触摸事件停止后内容继续按原方向惯性运动一段时间。但是这时候的滚动浮层不一定能捕获到。 @姚冬给的例子就有这个问题。

最后:个人认为如果是想做for iOS 7的web app,那完全不必纠结毛玻璃这个效果。一方面这方面的投入对用户体验影响不大。另一方面随着iOS 7.1的推出iOS自身应用这个效果的场景也在淡化对半透明模糊的强调。所以大可不必为此投入太多精力。谁知道iOS 8又会是什么新样子呢。
========================================================================
Update 1
---------------------------------------------------------------------------------------------------------------
收到了 @孟爽paula的评论,提到不用“捕屏”也可以实现。

首先,我不是说css filter必须作用于图片。在这里郑重声明,本人绝无此意!!!

看了提供的例子。确实没有用捕屏。但是我认为这个例子在实际使用过程中可能会遇到一些问题。我个人不是特别倾向这种做法。
根据iOS 7 Blurred Header的源码,这里使用的方案是拷贝dom节点到浮层内然后对浮层进行blur。对于相对简单的内容确实很有效。但是如果被复制dom节点内带有使用id属性唯一标记的元素,以及被复制节点内包含了一些随js执行其状态不可预测的元素。又或者页面样式的css选择器依赖某种外层的容器。那就可能导致所复制的内容与原始内容渲染出来的效果不一致。
简单的来说我个人认为这个方案通用性要略逊一些。

刚才看了 @刘小乐提供的CSS Regions解决方案,感觉这才是终极解决方案。可惜浏览器支持还需要等两年。 要做到类似iOS7的毛玻璃遮罩效果,单纯css3 filter还不够,还需要用到CSS Regions定义内容流。CSS Regions允许开发者定义位置容器,然后指定实际的内容元素在一个或多个位置容器间流动,这就给毛玻璃遮罩提供了可能。

例如:要实现iOS7顶部和底部毛玻璃遮罩,具体思路可以是这样:
定义3个位置容器,分别对应顶部区域、中间区域、底部区域,在顶部和底部应用filter:blur。指定实际的页面内容元素依次"流入"这3个位置容器。

比起截屏+模糊处理,使用CSS Regions方案更加底层和高效。缺点是还处于试验阶段,优点是高效。

CSS Regions目前还处于实验阶段,chrome下打开chrome://flags/#enable-experimental-web-platform-features, 开启实验特性即可。

就目前,使用内容拷贝+同步滚动的方式模拟内容流不失为一种解决方案,参见 孟爽paula 的答案。

CSS Regions+filter实现毛玻璃 参见:Blurry Transparent Header Effect from iOS7 in CSS 哈哈,刚好前两天写过一个小demo:Color Not 滤镜是对图片有效果,但是如果背景是纯色不是图片呢,可以用滤镜实现吗
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn