I wanna create a custom peeler animation with a transparent triangle image as you see below
This triangle need to reveal the image behind when hovering over the triangle. The reason why am not using a ready made js script is the design actually as triangle is transparent from the left side and in all libraries triangle must be all filled with color or solid background.
I tried to get the structure as you see in the fiddle but like this i am unable to make the hover animation as the image is rotated to fit the triangle shape and to cover the image.
HTML
<div class="peel-banner-wrap">
<div class="peel-banner-wrapper">
<a href="https://www.platinumcryptoacademy.com/cryptonaire-weekly/?utm_source=MBCS&utm_medium=CW&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&utm_medium=CW&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;
}
It is very important that the solution work with transparent background, without having a background color covering the image behind and also work in edge browser and in most common browsers.
Please help to find solutions.
Here is an idea with only CSS consider multiple background with linear/radial-gradient
and mask
. The shape is built using two symetric pseudo elements where the trick is to consider mask with a radial-graident in order to create the curve with transparency.
Then we have two animations. The main container where will animate a linear-gradient
to reveal the image at the bottom and the shape element will have a translation animation moving the same way as the gradient to simulate the peeler animation
Hover to see the effect.
.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>
If transparency isn't mandatory we can remove the mask and consider the same color as the container inside the gradient. We will have better support since mask isn't supported everywhere:
.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>
If the gradient coloration is not needed you can try the following with transparency and without the use of mask
.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>
Update
Another idea in case you want to have a random content inside your container:
.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>
Related questions to get mode details about the calculation related to the gradients:
Using percentage values with background-position on a linear gradient