cilp-path study notes

Recently, I often see the cilp-path clipping path. I made an overview when I was doing the courseware before, but did not study it in depth.

Today, I saw that it was used in other methods when I was doing the slash effect, and I realized that it was infinitely useful, so I decided to study it in depth. The following is the learning transcript.

 

 【Summary】

clip-path can be considered a new property of CSS3, or more precisely the CSS version of SVG's <path>.

Using clip-path, we can define any clipping path we want

【Official Definition】

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 (source: MDN)

Roughly translated: The clip-path attribute can determine which area of ​​the target element is visible and which area is invisible by defining the clipping area, that is, only the part within the closed path is displayed, and the part outside the area is not displayed. You can import embedded or external SVG through the url, or you can directly specify the path for the clip-path attribute with the built-in shape. The Clip-path attribute is a replacement for the clip attribute, and it can also be said to be an upgraded version of the click attribute

【Principle of realization】

 The principle of clipping is also very simple. The clip-path property provides us with a series of coordinates to create a path, which is what we often call X, Y. When a closed path is created, the area inside the path is visible, and the area outside the path is invisible. This achieves the cropping effect. We can use this property to create various shapes such as circles, polygons, triangles, ellipses, etc.

【example】

 (1) Triangles and polygons

 

 ①Triangle

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>clip-path example - small triangle</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>

 In the above code we only need to focus on -webkit-clip-path: polygon(0px 10px, 20px 0px, 20px 20px);

grammar:

/* Geometry values ​​*/ Geometry values
clip-path: inset(100px 50px);------Inset
clip-path: circle(50px at 0 100px);-------circle
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);-----geometry

Let's take a look at the usage of this attribute value and what the parameters in it mean!

      The previous -webkit-clip-path: It should go without saying

      As for the polygon(); method is the legendary function of creating polygons. The parameters inside (take the above code as an example) are the coordinates of 3 points, 0px 10px, 20px 0px, 20px 20px, and the coordinates are separated by commas in the polygon method. That is, these three points form a closed triangle.

The line of code commented in the CSS style-webkit-clip-path: polygon(0 50%, 100% 0, 100% 100%); The effect is actually the same as the first line of code-webkit-clip-path: polygon(0px 10px , 20px 0px, 20px 20px); are the same, but the writing is different, one uses px, and the other uses percentage. Here is also an analysis of the usage of percentages.

Regardless of whether it is in pixels or in percentages, it is a code coordinate point. Coordinate 1: (0, 50%), Coordinate 2: (100%, 0), Coordinate 3: (100%, 100%), it is estimated that you are not interested here, you want to know why it is written like this, why write it like this This little triangle can be achieved. And it has the same effect as the above in pixels.

First of all, the percentage here is based on the parent element, so, as in this example, the width and height of the parent element are both 20px, so coordinate one: (0,50%) = (0,10), coordinate two : (100%, 0) = (20, 0), coordinate three: (100%, 100%) = (20, 20). Now you should understand the relationship between percentages and pixels!

 

 ② Triangle crop picture

  You can use this triangle to crop a picture. This kind of usage should be more interesting and realistic, and it will have the opportunity to be used in our projects, but it may take some time, but it doesn't matter, we still have to look forward to the future.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>clip-path example - triangle cropped image</title>
<style>
.path {
/*-webkit-clip-path: polygon(0px 10px, 20px 0px, 20px 20px);*/
-webkit-clip-path: polygon(50% 0, 0 100% ,100% 100%);
/*Reduce percentage directly based on the image*/
}
</style>
</head>
<body>
<img class="path" src="http://yunkus.com/wp-content/themes/zxx/images/T900-500.png" alt="">
</body>
</html>
 

 ③ Dialog window crop picture (polygon)

.path {
 -webkit-clip-path: polygon(0% 0%,30% 0%,30% 40%,23% 40%,25% 50%,15% 40%,0% 40%);
 }
 

 ④ Star crop image (polygon)

.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%);
 }
 

(2) Round

 grammar:

clip-path: circle(50px at 0 100px);
 example:
.path {
  -webkit-clip-path: circle(30% at 50% 50%);
  /*-webkit-clip-path: circle(80px at 150px 83px);*/
 }

 The three values ​​in circle() are composed of the radius and a coordinate point of the center of the circle (x, y). After defining the radius of the circle, we can use the at keyword to define the coordinates of the center of the circle as above. Likewise, not only percentages, but also pixels can be used.

 

(3) Ellipse

 grammar:

clip-path: ellipse(20% 20% at 50% 45%);
 The implementation code of the ellipse is similar to that of the circle, and the method is changed.

 

(4) Arch bridge

If we slightly change a value of the ellipse CSS style, then the arch bridge appears in front of us

/*modified code*/
-webkit-clip-path: ellipse(100% 20% at 50% 45%);
 

(5) Leaves

 grammar:

inset(<top> <right> <bottom> <left> round
      <top-radius> <right-radius> <bottom-radius> <left-radius>)

 The order is top, right, bottom, left, and the first four parameters of inset are similar to top, right, bottom, and left used in absolute positioning. That is, the distance of the clipping path from the four sides of the object element. The four parameters after inset are equivalent to border-radius 

 example:

.path {
 -webkit-clip-path: inset(35% 35% 35% 35% round 0 70% 0 70%);
}
 The above example can also be abbreviated as
-webkit-clip-path: inset(35% round 0 70%);

 

(6) Animation

Another powerful feature of clip-path is that it can perform CSS transitions and CSS animations, that is, transitions and animations

 ①Graphic transformation 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>

 

 

 

.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326139623&siteId=291194637