使用 Css, js 创建带有透明三角形图像的自定义削皮器动画

Create a custom peeler animation with transparent triangle image with Css, js

我想创建一个带有透明三角形图像的自定义削皮器动画,如下所示

这个三角形悬停在三角形上时需要显示后面的图像。 我不使用现成的 js 脚本的原因是设计实际上是因为三角形从左侧是透明的,并且在所有库中三角形必须全部填充颜色或纯色背景。

我试图获得您在 fiddle 中看到的结构,但像这样我无法制作悬停动画,因为图像旋转以适合三角形并覆盖图像。

HTML
<div class="peel-banner-wrap">
   <div class="peel-banner-wrapper">  
     <a href="https://www.platinumcryptoacademy.com/cryptonaire-weekly/?utm_source=MBCS&amp;utm_medium=CW&amp;utm_campaign=Social" target="_blank"> 
        <img src="https://maltablockchainsummit.com/wp-content/themes/maltablockchain/images/cryptonaire-peel-thumb.jpg"> 
     </a> 
     <a href="https://www.platinumcryptoacademy.com/cryptonaire-weekly/?utm_source=MBCS&amp;utm_medium=CW&amp;utm_campaign=Social" target="_blank"> 
       <img src="https://maltablockchainsummit.com/wp-content/themes/maltablockchain/images/peel-bg-new.png"> 
    </a>
   </div>
</div>
CSS
.peel-banner-wrap{
    position: absolute;
    top:0;
    right:0;
    width:400px;
    height:340px;
    z-index: 14;
    transition: .5s;
}
.peel-banner-wrapper{
    overflow: hidden;
    position: relative;
    width: 100%;
    height: 100%;
}
.page-id-80436 .peel-banner-wrap{
    display:block;
}
.peel-banner-wrapper a{
    overflow: hidden;
    position: absolute;
    transform: skewX(55.98deg);
}
.peel-banner-wrapper a:first-child {
    left: -.25em;
    transform-origin: 100% 0;
}
.peel-banner-wrapper a {
    transition: .5s;
}
.peel-banner-wrapper a img {
    transform: skewX(-55.98deg);
    transform-origin: inherit;
}
.peel-banner-wrapper a:first-child:after {
    top: 0;
    left: 0;
}
.peel-banner-wrapper a:last-child {
    right: 0;
    top: -127px;
    transform: rotate(-12deg);
}
.peel-banner-wrapper a:last-child img{
    transform: none;
    margin-top: 15px;
}

非常重要的是,该解决方案可以在透明背景下工作,背景颜色不会覆盖后面的图像,并且还可以在边缘浏览器和大多数常见浏览器中工作。

请帮忙寻找解决办法。

这是一个想法,仅 CSS 考虑了 linear/radial-gradientmask 的多重背景。该形状是使用两个对称的伪元素构建的,其中的诀窍是考虑具有径向梯度的蒙版以创建具有透明度的曲线。

然后我们有两个动画。主容器将动画 linear-gradient 以在底部显示图像,形状元素将有一个平移动画以与渐变相同的方式移动以模拟削皮器动画

鼠标悬停查看效果。

.container {
  position:relative;
  height:100vh;
  background-image:
    linear-gradient(225deg,transparent 130px,pink 0),
    url(https://picsum.photos/id/1012/1000/800);
  background-size:
    calc(100% + 60px) calc(100% + 60px),
    cover; 
  background-position:
    bottom left,
    center;
  transition:1s all linear;
}

.box {
  width: 270px;
  height: 100px;
  border-top-left-radius: 35px 20px;
  position:fixed;
  top:-10px;
  right:0;
  transform:  translate(53px, -53px) translateX(33%) rotate(45deg);
  transition:1s all linear;
  transform-origin: top left;
  overflow:hidden;
}
.box:before,
.box:after{
  content:"";
  position:absolute;
  width:50.2%;
  top:0;
  bottom:0;
  border-top: 5px solid rgba(128, 128, 128, 0.5);
  background-image:
    radial-gradient(60% 50%,grey 99%,transparent 100%),
    linear-gradient(to right,blue,purple);
  background-size:200% 400%;
  background-clip:padding-box;
  -webkit-mask: radial-gradient(60% 48.5%,transparent 97%,rgba(255,255,255,0.5) 98% 99%,#fff 100%);
  mask: radial-gradient(60% 48.5%,transparent 97%,rgba(255,255,255,0.5) 98% 99%,#fff 100%);
  -webkit-mask-size:200% 400%;
  mask-size:200% 400%;
  transform:translateY(-40%);
  transition:1s all linear;
}
.box:before {
    right:0;
    border-top-right-radius: 35px 20px;
    background-position: left top,right;
    -webkit-mask-position:left top;
    mask-position:left top;
}
.box:after {
    left:0;
    border-top-left-radius: 35px 20px;
    background-position:right top,left;
    -webkit-mask-position:right top;
    mask-position:right top;
}

/* Hover effect*/
.container:hover{
  background-position:
    top right,
    center;
}
.container:hover .box {
  transform:  translate(0%, 0%) translateX(33%) rotate(45deg);
}

.container:hover .box:before,
.container:hover .box:after {
  transform:translateY(0);
}
body {
 margin:0;
}
<div class="container">
  <div class="box"></div>
</div>

如果透明度不是强制性的,我们可以移除遮罩并考虑使用与渐变内容器相同的颜色。我们将获得更好的支持,因为并非所有地方都支持掩码:

.container {
  position:relative;
  height:100vh;
  background-image:
    linear-gradient(225deg,transparent 130px,pink 0),
    url(https://picsum.photos/id/1012/1000/800);
  background-size:
    calc(100% + 60px) calc(100% + 60px),
    cover; 
  background-position:
    bottom left,
    center;
  transition:1s all linear;
}

.box {
  width: 270px;
  height: 100px;
  border-top-left-radius: 35px 20px;
  position:fixed;
  top:-10px;
  right:0;
  transform:  translate(53px, -53px) translateX(33%) rotate(45deg);
  transition:1s all linear;
  transform-origin: top left;
  overflow:hidden;
}
.box:before,
.box:after{
  content:"";
  position:absolute;
  width:50.2%;
  top:0;
  bottom:0;
  border-top: 5px solid rgba(128, 128, 128, 0.5);
  background-image:
    radial-gradient(60% 50%,pink 97%,rgba(255,255,255,0.5) 98%,rgba(255,255,255,0.5) 99%,transparent 100%),
    linear-gradient(to right,blue,purple);
  background-size:200% 400%,200% 98%;
  background-clip:padding-box;
  background-repeat:no-repeat;
  transform:translateY(-40%);
  transition:1s all linear;
}
.box:before {
    right:0;
    border-top-right-radius: 35px 20px;
    background-position: left top,right;
}
.box:after {
    left:0;
    border-top-left-radius: 35px 20px;
    background-position:right top,left;
}

/* Hover effect*/
.container:hover{
  background-position:
    top right,
    center;
}
.container:hover .box {
  transform:  translate(0%, 0%) translateX(33%) rotate(45deg);
}

.container:hover .box:before,
.container:hover .box:after {
  transform:translateY(0);
}
body {
 margin:0;
}
<div class="container">
  <div class="box"></div>
</div>

如果不需要渐变着色,您可以在不使用遮罩的情况下尝试以下透明效果

.container {
  position:relative;
  height:100vh;
  background-image:
    linear-gradient(225deg,transparent 130px,pink 0),
    url(https://picsum.photos/id/1012/1000/800);
  background-size:
    calc(100% + 60px) calc(100% + 60px),
    cover; 
  background-position:
    bottom left,
    center;
  transition:1s all linear;
}

.box {
  width: 270px;
  height: 100px;
  border-top-left-radius: 35px 20px;
  position:fixed;
  top:-10px;
  right:0;
  transform:  translate(54px, -54px) translateX(33%) rotate(45deg);
  transition:1s all linear;
  transform-origin: top left;
  overflow:hidden;
}
.box:before,
.box:after{
  content:"";
  position:absolute;
  width:50.2%;
  top:0;
  bottom:0;
  border-top: 5px solid rgba(128, 128, 128, 0.5);
  background-image:
    radial-gradient(60% 50%,transparent 97%,rgba(255,255,255,0.5) 98%,rgba(255,255,255,0.5) 99%,red 100%);
  background-size:200% 400%;
  background-clip:padding-box;
  background-repeat:no-repeat;
  transform:translateY(-40%);
  transition:1s all linear;
}
.box:before {
    right:0;
    border-top-right-radius: 35px 20px;
    background-position: left top;
}
.box:after {
    left:0;
    border-top-left-radius: 35px 20px;
    background-position:right top;
}

/* Hover effect*/
.container:hover{
  background-position:
    top right,
    center;
}
.container:hover .box {
  transform:  translate(0%, 0%) translateX(33%) rotate(45deg);
}

.container:hover .box:before,
.container:hover .box:after {
  transform:translateY(0);
}
body {
 margin:0;
}
<div class="container">
  <div class="box"></div>
</div>

更新

另一个想法,如果你想在你的容器中有一个随机内容:

.container {
  position:relative;
  height:100vh;
  background:
    url(https://picsum.photos/id/1012/1000/800) center/cover;
  overflow:hidden;
}
.image {
  width:270px;
  height:270px;
  position:absolute;
  top:-10px;
  right:0;
  overflow:hidden;
  transform: translate(72%,-72%) rotate(45deg);
  transition:1s all linear;
}
.image:before {
  content:"";
  position:absolute;
  width:141%;
  height:141%;
  top:50%;
  left:50%;
  background:
    url(https://picsum.photos/id/103/1000/800) center/cover;
  transform:translate(-50%,-28%) rotate(-45deg);
  transition:1s all linear;
}
.box {
  width: 270px;
  height: 100px;
  border-top-left-radius: 35px 20px;
  position:absolute;
  top:-10px;
  right:0;
  transform:  translate(54px, -54px) translateX(33%) rotate(45deg);
  transition:1s all linear;
  transform-origin: top left;
  overflow:hidden;
}
.box:before,
.box:after{
  content:"";
  position:absolute;
  width:50.2%;
  top:0;
  bottom:0;
  border-top: 5px solid rgba(128, 128, 128, 0.5);
  background-image:
    radial-gradient(60% 50%,transparent 97%,rgba(255,255,255,0.5) 98%,rgba(255,255,255,0.5) 99%,red 100%);
  background-size:200% 400%;
  background-clip:padding-box;
  background-repeat:no-repeat;
  transform:translateY(-40%);
  transition:1s all linear;
}
.box:before {
    right:0;
    border-top-right-radius: 35px 20px;
    background-position: left top;
}
.box:after {
    left:0;
    border-top-left-radius: 35px 20px;
    background-position:right top;
}

/* Hover effect*/

.container:hover .box {
  transform:  translate(0%, 0%) translateX(33%) rotate(45deg);
}

.container:hover .image {
  transform: translate(50%,-50%) rotate(45deg);
}
.container:hover .image:before {
  transform: translate(-50%,-50%) rotate(-45deg);
}

.container:hover .box:before,
.container:hover .box:after {
  transform:translateY(0);
}
body {
 margin:0;
}

h1,p {
 color:#fff;
 text-align:center;
 padding:0 20px;
}
<div class="container">
  <div class="box"></div>
  <div class="image"></div>
  <!-- your content here --->
  <h1>Some title</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dui neque, auctor nec lorem non, eleifend vulputate justo. Duis cursus purus ligula, nec congue ipsum dapibus ut. Etiam dictum, urna sit amet pulvinar maximus, nunc magna facilisis magna, id viverra massa metus et arcu. Cras ut metus sed quam blandit pellentesque. Nunc at maximus tellus. Morbi vulputate, orci vel condimentum malesuada, leo leo porttitor lorem, </p>
</div>


获取与梯度相关计算的模式详细信息的相关问题:

Using percentage values with background-position on a linear gradient