最近经常看到cilp-path剪裁路径,之前做课件的时候做过概括,但未深入研究。
今天做斜线效果时看到别的方法里用到,才知道原来妙用无穷,所以决定深入研究下,以下为学习笔录。
【概括】
clip-path可以算是 CSS3 的新增属性,或者准确来说是 SVG 的 <path> 的 CSS 版本。
使用 clip-path,我们可以定义任意想要的剪裁路径
【 官方定义】
The clip-path CSS property prevents a portion of an element from getting displayed by
defining a clipping region to be displayed i.e, only a specific region of the element
is displayed. The clipping region is a path specified as a URL referencing an inline
or external SVG, or shape method such as circle(). The clip-path property replaces the
now deprecated clip property(来源:MDN)
大概翻译为:clip-path 属性可以通过定义裁剪区域来决定目标元素哪个区域可见,哪个区域不可见,也就是只有在闭合路径内的部分才显示,区域以外的部分就不显示。可以通过url 引入内嵌的或者外置的SVG,又或者是直接用自带的形状为clip-path 属性指定路径。 Clip-path 属性是clip属性的替代者,也可以说是click 属性的升级版
【实现原理】
实现裁剪的原理也非常简单,clip-path 属性为我们提供了一系列的坐标来创建路径也就是我们常常说的X,Y。当创建完一个闭合的路径时,位于路径内部的区域就可见,而路径外的区域就不可见。这样就实现了裁剪效果。我们可以用这个属性来创建各种图形,如圆形,多边形,三角形,椭圆形等等
【例子】
(1)三角形与多边形
①三角形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>clip-path 例子-小三角</title>
<style>
.path {
background: #33363b;
width: 20px;height: 20px;
-webkit-clip-path: polygon(0px 10px, 20px 0px, 20px 20px);
/*-webkit-clip-path: polygon(0 50%, 100% 0, 100% 100%);*/
}
</style>
</head>
<body>
<div class="path"></div>
</body>
</html>
上面的代码我们只需要关注 -webkit-clip-path: polygon(0px 10px, 20px 0px, 20px 20px); 就可以了
语法:
/* Geometry values */几何值
clip-path: inset(100px 50px);------插页
clip-path: circle(50px at 0 100px);-------圆形
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);-----几何
下面我们就来看看这个属性值的用法以及里面的几个参数都是什么意思吧!
前面的-webkit-clip-path: 应该就不用说了
至于polygon(); 方法就是传说中的创建多边形的函数。而里面的参数(以上面的代码为例)就是3个点的坐标,0px 10px、 20px 0px、20px 20px ,在polygon 方法中坐标之间用逗号隔开。也就是这三个点就组成了一个闭合的三角形。
css 样式中注释的那行代码 -webkit-clip-path: polygon(0 50%, 100% 0, 100% 100%); 效果其实是跟第一行代码 -webkit-clip-path: polygon(0px 10px, 20px 0px, 20px 20px); 是一样的,只是写法不一样,一个用px,一相用百分比。在这里也给大家分析下百分比的用法。
不管是以像素作为单位,还是百分比作为单位,都是代码坐坐标点。坐标一:(0,50%),坐标二:(100%,0),坐标三:(100%,100%),估计你对这里不感兴趣,你更想知道为什么要这么写,为什么这样写能实现这个小三角。并且跟上面的以像素作为单位的效果一样。
首先这里的百分比是以父元素为参考的,于是乎,就像本例子中的父元素的宽、高都为20px,所以坐标一:(0,50%) = (0,10),坐标二:(100%,0) = (20,0),坐标三:(100%,100%) = (20,20) 。这下子你应该明白了百分比与像素之间的关系了吧!
② 三角裁剪图片
可以用这个三角形来裁剪一张图片,这样的用法应该会更有意思,更实在,也有机会用到我们的项目当中去,不过这可能还需要点时间,不过没关系,我们还是得对未来有所期待
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>clip-path 例子-三角裁剪图片</title>
<style>
.path {
/*-webkit-clip-path: polygon(0px 10px, 20px 0px, 20px 20px);*/
-webkit-clip-path: polygon(50% 0, 0 100% ,100% 100%);
/*直接以图片为基准进行百分比裁减*/
}
</style>
</head>
<body>
<img class="path" src="http://yunkus.com/wp-content/themes/zxx/images/T900-500.png" alt="">
</body>
</html>
③ 对话窗裁剪图片(多边形)
.path {
-webkit-clip-path: polygon(0% 0%,30% 0%,30% 40%,23% 40%,25% 50%,15% 40%,0% 40%);
}
④ 星形裁剪图片(多边形)
.path {
-webkit-clip-path: polygon(50% 0%, 65% 33%, 100% 33%, 80% 60%, 90% 100%, 50% 75%,
10% 100%,20% 60%,0 33%,35% 33%);
}
(二)圆形
语法:
clip-path: circle(50px at 0 100px);
例子:
.path {
-webkit-clip-path: circle(30% at 50% 50%);
/*-webkit-clip-path: circle(80px at 150px 83px);*/
}
circle() 中三个值分别由半径,一个圆心坐标点(x,y)组成,定义了圆的半径后,我们可以用 at 关键字来定义圆心坐标就像上面那样。同样的,不仅可以用百分比,也可以用像素来表示。
(三)椭圆
语法:
clip-path: ellipse(20% 20% at 50% 45%);
椭圆的实现代码跟圆的差不多,换了个方法而已
(四)拱桥
如果我们把椭圆CSS样式的一个值稍作修改,那么拱桥就出现在我们的面前了
/*修改后的代码*/
-webkit-clip-path: ellipse(100% 20% at 50% 45%);
(五)叶子
语法:
inset(<top> <right> <bottom> <left> round
<top-radius> <right-radius> <bottom-radius> <left-radius>)
顺序为上右下左,inset前面四个参数就类似于绝对定位中用到的top、right、bottom、left。也就是裁剪的路径距离对象元素四个边的距离。inset后面四个参数就相当于 border-radius
例子:
.path {
-webkit-clip-path: inset(35% 35% 35% 35% round 0 70% 0 70%);
}
上边的例子还可以简写成
-webkit-clip-path: inset(35% round 0 70%);
(六)动画
clip-path 另外一个强大之处在于可以进行 CSS transtion 与 CSS animation,也就是过渡和动画
①图形变换动画
<div class="polygon-animate"></div>
<--几何图形变换 polygon 坐标位置可以去 http://bennettfeely.com/clippy/ 获取 -->
.polygon-animate {
position: absolute;
width: 200px;
height: 200px;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: crimson;
-webkit-transition: .3s;
transition: .3s;
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%);
-webkit-animation: polygon-ani 5s linear infinite;
animation: polygon-ani 5s linear infinite;
}
@-webkit-keyframes polygon-ani {
10% {
background-color: darkorange;
-webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%);
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%);
}
14% {
-webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%);
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%);
}
24% {
background-color: lemonchiffon;
-webkit-clip-path: polygon(100% 38%, 82% 100%, 82% 100%, 18% 100%, 0% 38%, 0% 38%, 0% 38%, 0% 38%, 50% 0%);
clip-path: polygon(100% 38%, 82% 100%, 82% 100%, 18% 100%, 0% 38%, 0% 38%, 0% 38%, 0% 38%, 50% 0%);
}
28% {
-webkit-clip-path: polygon(100% 38%, 82% 100%, 82% 100%, 18% 100%, 0% 38%, 0% 38%, 0% 38%, 0% 38%, 50% 0%);
clip-path: polygon(100% 38%, 82% 100%, 82% 100%, 18% 100%, 0% 38%, 0% 38%, 0% 38%, 0% 38%, 50% 0%);
}
38% {
background-color: darkturquoise;
-webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 100% 75%, 50% 100%, 0% 75%, 0% 75%, 0% 25%, 0% 25%);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 100% 75%, 50% 100%, 0% 75%, 0% 75%, 0% 25%, 0% 25%);
}
42% {
-webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 100% 75%, 50% 100%, 0% 75%, 0% 75%, 0% 25%, 0% 25%);
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 100% 75%, 50% 100%, 0% 75%, 0% 75%, 0% 25%, 0% 25%);
}
52% {
background-color: darkcyan;
-webkit-clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 25% 100%, 0% 60%, 10% 20%, 50% 0%);
clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 25% 100%, 0% 60%, 10% 20%, 50% 0%);
}
56% {
-webkit-clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 25% 100%, 0% 60%, 10% 20%, 50% 0%);
clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 25% 100%, 0% 60%, 10% 20%, 50% 0%);
}
66% {
background-color: deepskyblue;
-webkit-clip-path: polygon(30% 0%, 70% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
clip-path: polygon(30% 0%, 70% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
70% {
-webkit-clip-path: polygon(30% 0%, 70% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
clip-path: polygon(30% 0%, 70% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
}
80% {
background-color: indigo;
-webkit-clip-path: polygon(83% 12%, 100% 43%, 94% 78%, 68% 100%, 32% 100%, 6% 78%, 0% 43%, 17% 12%, 50% 0%);
clip-path: polygon(83% 12%, 100% 43%, 94% 78%, 68% 100%, 32% 100%, 6% 78%, 0% 43%, 17% 12%, 50% 0%);
}
84% {
-webkit-clip-path: polygon(83% 12%, 100% 43%, 94% 78%, 68% 100%, 32% 100%, 6% 78%, 0% 43%, 17% 12%, 50% 0%);
clip-path: polygon(83% 12%, 100% 43%, 94% 78%, 68% 100%, 32% 100%, 6% 78%, 0% 43%, 17% 12%, 50% 0%);
}
94% {
background-color: crimson;
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%);
}
}
②除此之外,我们还可以尝试,将一个完整的图形,分割成多个小图形(类似爆炸特效)
<hgroup class="triangle2rect">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<div class="d"></div>
</hgroup>
.triangle2rect {
position: absolute;
width: 100px;
height: 100px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: aniContainer 2s infinite alternate;
}
.triangle2rect div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.a {
background: deeppink;
clip-path: polygon(0% 0%, 0% 100%, 50% 50%);
animation: a 2s infinite alternate;
}
.b {
background: deeppink;
clip-path: polygon(0% 0%, 100% 0%, 50% 50%);
animation: b 2s infinite alternate;
}
.c {
background: deeppink;
clip-path: polygon(100% 0%, 100% 100%, 50% 50%);
animation: c 2s infinite alternate;
}
.d {
background: deeppink;
clip-path: polygon(100% 100%, 0% 100%, 50% 50%);
animation: d 2s infinite alternate;
}
@keyframes a {
0%, 10% {
background: deeppink;
clip-path: polygon(0% 0%, 0% 100%, 50% 50%);
}
90%, 100% {
background: #000;
clip-path: polygon(0% 100%, 25% 100%, 12.5% 0%);
}
}
@keyframes b {
0%, 10% {
background: deeppink;
clip-path: polygon(0% 0%, 100% 0%, 50% 50%);
}
90%, 100% {
background: #000;
clip-path: polygon(25% 0%, 50% 0%, 37.5% 100%);
}
}
@keyframes c {
0%, 10% {
background: deeppink;
clip-path: polygon(100% 0%, 100% 100%, 50% 50%);
}
90%, 100% {
background: #000;
clip-path: polygon(62.5% 0%, 75% 100%, 50% 100%);
}
}
@keyframes d {
0%, 10% {
background: deeppink;
clip-path: polygon(100% 100%, 0% 100%, 50% 50%);
}
90%, 100% {
background: #000;
clip-path: polygon(100% 0%, 87.5% 100%, 75% 0%);
}
}
@keyframes aniContainer {
0%, 10% {
width: 100px;
height: 100px;
}
90%, 100% {
width: 250px;
height: 60px;
}
}
【clip-path 动画的局限】
clip-path 动画虽然美好,但是存在一定的局限性,那就是进行过渡的两个状态,坐标顶点的数量必须一致。
也就是如果我希望从三角形过渡到矩形。假设三角形和矩形的 clip-path 分别为:
三角形:clip-path: polygon(50% 0, 0 100%, 100% 0)
矩形: clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%)
进行过渡动画时候,直接从 polygon(50% 0, 0 100%, 100% 0) --> polygon(0 0, 100% 0, 100% 100%, 0 100%) 是不行的,因为是从 3 个坐标点变换到 4 个坐标点。
因此这里需要这用一个讨巧的办法,在三角形的表示方法中,使用四个坐标点表示,其中两个坐标点进行重合即可。也就是:
三角形:clip-path: polygon(50% 0, 0 100%, 100% 0) -> clip-path: polygon(50% 0, 50% 0, 0 100%, 100% 0)
【N边形过渡动画】
如果脑洞够大,随机生成 N(N>=1000)边形 //只是随机生成了 2000 个坐标点,然后使用 clip-path 将这些坐标点连接起来,并不是符合要求的多边形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>随机变换</title>
<style type="text/css">
div {
width: 300px;
height: 300px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: all .5s;
transition-timing-function: cubic-bezier(.92,-0.5,1,.12);
border-radius: 50%;
}
</style>
</head>
<body>
<div></div>
<script>
setInterval(function() {
const length = 2000;
let el = document.querySelectorAll("div")[0];
let coordinate = "";
for (let i = 0; i < length; i++) {
coordinate +=
parseInt(Math.random() * 10000) / 100 +
"% " +
parseInt(Math.random() * 10000) / 100 +
"%, ";
}
coordinate = "polygon(" + coordinate.slice(0, -2) + ")";
el.style.clipPath = coordinate;
el.style.backgroundColor =
"#" + (~~(Math.random() * (1 << 24))).toString(16);
}, 500);
</script>
</body>
</html>
.
相关推荐
这是原始C-IL2P神经符号系统CILP ++的扩展项目,用于从命题和一阶逻辑进行推理,知识提取和理论修订。 *** 注意力! SVN已终止CILP ++项目! 它已通过https://github.com/manoelfranca/cilppp迁移到Github!
多模态大模型应用_将CILP与行人重识别ReID相结合实现无具体文本标签的图像重识别算法_附项目源码+流程教程_优质项目实战
CILP通过引入约束逻辑程序(CLP)的概念,将约束求解与归纳学习相结合,以克服这一限制。 #### CILP的发展背景与挑战 传统的ILP方法以Prolog语言为基础,虽然在模式识别、概念学习和规则归纳方面表现出色,但其对...
### 正则表达式在Python中的应用与详解 #### 一、正则表达式的概述 正则表达式是一种强大的文本处理工具,它提供了一种简便且灵活的方法来识别、匹配和处理文本中的字符串。在Python中,正则表达式主要通过`re`...
人工辅助学习功能意味着用户可以纠正系统的错误判断,帮助系统不断优化和学习。例如,如果系统错误地将一只猫识别为狗,用户可以提供正确的信息,系统会更新其规则库,以便在未来更好地识别此类动物。 总的来说,这...
通过学习和使用CLIPS,开发者能够构建具有智能行为的系统,解决那些需要专家知识和推理能力的问题。 总结一下,CLIPS是一个强大的规则引擎,适合构建专家系统和人工智能应用。"animal代码"作为示例,展示了如何在...
将空间非局部导数算子引入曲率驱动扩散方程,建立了一个基于非局部曲率驱动扩散的图像修复模型。与原模型的主要差别在于,原模型利用待修复像素的空间局部信息来估计丢失像素, 而新模型利用和待修复像素相似的所有像素...
Garcez等在KBANN的基础上提出了CILP系统,该系统将逻辑规则应用到初始化网络过程中,使网络可以更好地学习数据和知识。Fernando等在KBANN的基础上提出了INSS系统,成功利用包含实数的分类规则初始化人工神经网络。...
- **Constraint Inductive Logic Programming (CILP)**: CILP is an extension of Inductive Logic Programming (ILP) that incorporates constraints into the learning process. This technique can be ...
夹子几天后,该存储库将为CLIP:神经元网络的廉价Lipschitz培训[1]中提出的,用于Lipschitz正则化神经网络的CLIP算法提供一种实现。 ![公式]( {i \ pi} = -1) 随时使用它,这样做时请参考我们的论文。...