一行代码实现多边形蒙板

每个挑战,都是突破自我的一次机遇。

最近在活动中接到一个需求,如图:

一般情况下,这应该是个静态图(页面仔最喜欢这样轻松的工作~),but,美丽的射鸡湿却要求,右边的立方体需要有从下往上升的动画,来体现真的是往上升。

emmm….来想一下,似乎团队小伙伴有弄过这么一个东东用CSS实现立体图,而且会“长大”(使用3D变形),直接拿来用吧。

只是没想到,射鸡湿已经为我想好节省体力的办法,她说,这个图它是用三个层来实现的,右边的立方体本身就更长,只是位移到了下面,看不到而已。

哦吼,简直不要太舒服,那我不是直接来个容器把它装进去,起始状态把它位移到下面,隐藏掉,需要动的时候加个类让它回到原位不就好了?perfect!!

可是…

现实总比理想骨感,它成了这个样子…

WTF!~

我想当然地忽略了伟大的盒子模型是四四方方的,所以,这似乎预示着这种方案的失败,敢问路在何方?

你的第一反应应该是SVG,当常规CSS无法搞定一些图形或者动画的时候,我们会不自觉地想到诸如Canvas,或者SVG,这么想是对的。比如这样一段代码:

<svg>
<circle cx="60" cy="60" r="50" fill="#34538b"  />
</svg>

会是这样

如果加上这样一段

<svg>
        <clipPath id="clipPath">
                <rect x="0" y="0" width="80" height="80" />
        </clipPath>
        <circle cx="60" cy="60" r="50" fill="#34538b"  clip-path="url(#clipPath)"/>
</svg>

就成这样

对,它被一个rect(矩形)裁剪了。

显然,我们需要的不是矩形,但这样一个功能告诉我们,它可以做到,只要我们把图形形状改变一下即可。

SVG用实现多边形,加上如下代码:

<clipPath id="clipPath">
<polygon points="40 20, 50 40, 50 50, 20 60"></polygon>
</clipPath>

就会被裁剪成这样:

有点丑…

无所谓了,这次的主角不是它,而是CSS的——clip-path

它看起来效果和SVG类似,但似乎更简单。

回到需求

想要有这样的效果,不说上边缘,起码下边缘要是个三角形,才能做到轮廓和立方体贴合,那索性就做成六边形的轮廓,让它刚好贴合:

html:

<div class="chart-wrap">
    <i class="chart"></i>        
</div>

css:

-webkit-clip-path: polygon(50% 0%, 100% 8%, 100% 90%, 50% 100%, 0% 90%, 0% 8%);
clip-path: polygon(50% 0%, 100% 8%, 100% 90%, 50% 100%, 0% 90%, 0% 8%);

代码中的数值是根据这个图形具体调整的,可以看出,是六个坐标点,设置完后,容器的轮廓即是这些点按照顺序相连出来的图形。

如果你的图形宽度和角度不同,需要重新进行调整。

这样就突破了正常盒子的局限,做到了贴合边缘的包裹。

似乎看着不明显,来张动图就好啦!

是不是解了燃眉之急?

你肯定关心它的兼容性怎样

看起来好像没那么好,但考虑到不同产品在平台上需要适配的浏览器范围(移动端为主),以及部分浏览器可加前缀进行兼容,还是可以试用的。这里只是个例,如果你想,可以把形状做成“任何”你想要的!~

当然,类似这种代码,纯靠手写计算是痛苦的,推荐个工具:https://bennettfeely.com/clippy

小结

这里的多边形蒙版只是不规则图形在网页中应用的一种,也并不是刚出的新东西,但往往一个新东西出来之后我们很长时间都找不到它跟实际需求的结合点在哪里,似乎都只存在于花里胡哨的demo里,恰巧,这就是个实际的例子,当然还有很多其他图形存在的可能。

网页元素的多样化,一直在反推技术不断向前发展,新属性/技能的出现,也为开发者提供了很多便利,还是要保持学习、保持思考,才能解锁更多技能~