Making a css animation using a transparent gradient mask - javascript

I am currently making an animation that will apply a gradient mask on an image. The mask is a transparent mask and it will transform from right to left of the image. Here is my code.
<!DOCTYPE html>
<html>
<head>
<style>
.container {
height: 100vh;
width: 100vw;
background-color: white;
position: relative;
}
.first {
background-image: url('https://i.ibb.co/17zzm7P/flower.jpg');
background-size:cover;
position: absolute;
height: 100%;
width: 100%;
-webkit-mask-image: linear-gradient(to left, transparent 0px, black 20rem, black);
-webkit-animation: rightToLeft 5s forwards;
}
#keyframes rightToLeft {
0% {
-webkit-mask-position: 100vw 0%;
mask-position: 100vw 0%;
}
100% {
-webkit-mask-position: 0vw 0vw;
mask-position: 0vw 0vw;
}
}
</style>
</head>
<body>
<div class="container">
<div id="first" class="first"> </div>
</div>
</body>
</html>
Basically, the animation works well. However, the mask image is only applied to a specific area when it moves from right to left. Because the mask is transparent, I expect when it moves to the new area, the previous area it passed through is also transparent. How can I do to make the previous area transparent too?
Thank you so much for your time.

You are almost good, you only need to disable the repetition by using mask-repeat: no-repeat
.container {
height: 100vh;
background-color: white;
position: relative;
}
.first {
background-image: url('https://i.ibb.co/17zzm7P/flower.jpg');
background-size: cover;
position: absolute;
height: 100%;
width: 100%;
-webkit-mask-image: linear-gradient(to left, transparent, black 20rem);
-webkit-mask-repeat: no-repeat;
-webkit-animation: rightToLeft 5s forwards;
}
#keyframes rightToLeft {
0% {
-webkit-mask-position: 100vw 0%;
mask-position: 100vw 0%;
}
100% {
-webkit-mask-position: 0vw 0vw;
mask-position: 0vw 0vw;
}
}
body {
margin:0;
}
<div class="container">
<div id="first" class="first"> </div>
</div>

Related

Navigation bar hover effect - CSS

I am working on a navigation bar. I have uploaded an image in which I have made a red circle. I have to make that shape. How can I make it? How can I create this kind of shape in a single div
Here is my code :
<!DOCTYPE html>
<html>
<head>
<title>CSS Shape</title>
<style>
.triangletwo {
width:100px;
height:100px;
display:inherit;
opacity:0;
transition:all 1s ease-in-out;
-webkit-transition:all 1s ease-in-out;
clip-path: polygon(100% 0, 0 0%, 50% 80%);
}
</style>
</head>
<body>
<div style="width: 200px; height: 200px; overflow: hidden; margin: 0px; display: inline-block; clip-path: polygon(100% 0, 0 0%, 50% 80%);">
</div>
<div style="width: 100px; height: 100px; overflow: hidden; background: #6d74a3; margin-left:-100px; display: inline-block;clip-path: polygon(50% 0, 0 80%, 100% 80%);">
</div>
<div style="width: 100px; height: 100px; overflow: hidden; background: #6d74a3; margin-left:-42px; margin-bottom: -20px; display: inline-block; clip-path: polygon(100% 0, 0 0%, 50% 80%);">
<div class="triangletwo" style="display: inline-block;"></div>
</div>
</body>
</html>
Yes, you can create it using a div with text inside. Hope this help
.single-div {
background-color: #a224a2;
color: white;
font-size: 25px;
width: 150px;
height: 100px;
position: relative;
clip-path: polygon(30% 0, 40% 25%, 100% 25%, 70% 99%, 60% 76%, 0 75%);
display: flex;
}
.text {
margin: auto;
}
<div class="single-div">
<span class="text">Home</span>
</div>

css clip-path hover only on shape

as seen in my codepen, there are two greyscaled shapes. Now its only possible to hover one of both, because the original size is a box and overlaps both images.
But is there a way to like recognize the shape when hovering it? Z-index does not lead to a result...
Hope you can help me out a bit!
would be great without JS but its not a k.o.
html:
<div id="one">
<img src="https://cdn.pixabay.com/photo/2019/01/19/15/53/ice-
3941906_1280.jpg">
</div>
<div id="two">
<img src="https://cdn.pixabay.com/photo/2016/04/20/17/02/tuscany-
1341536_1280.jpg">
</div>
css:
img{
width: 700px;
height: 400px;
object-fit: cover;
}
#one img{
-webkit-clip-path: polygon(0 0, 0% 100%, 100% 0);
clip-path: polygon(0 0, 0% 100%, 100% 0);
}
#two img{
-webkit-clip-path: polygon(100% 100%, 0% 100%, 100% 0);
clip-path: polygon(100% 100%, 0% 100%, 100% 0);
}
#one{
position: absolute;
z-index: 0;
top: 0 ;
left: 0;
}
#two{
position:absolute;
top: 0px;
left: 0;
z-index: 0;
}
#one,
#two{
filter:grayscale(100%);
}
#one:hover,
#two:hover{
filter:grayscale(0%);
}
https://codepen.io/robwe30/pen/eXBvzp?editors=1100
Cheers
For that simple shape, You may play with pointer-events to remove it and a pseudo element rotated to switch it back on only on one part of the image.
about pointer-events https://css-tricks.com/almanac/properties/p/pointer-events/
example
/* CSS switch of pointer-events on/off */
#two {
position: relative;
overflow: hidden;/* hide pseudo overflowing */
pointer-events: none;
}
#two:before {
pointer-events: auto;
content: '';
position: absolute;
top: 100%;
left: 0;
z-index: 2;
width: 150%;
height: 100%;
/* set transform according to ratio image */
transform-origin: top left;
transform: rotate(-30deg);
/* if you want to see where it stands , add borders or background */
}
/* end CSS switch */
img {
width: 700px;
height: 400px;
object-fit: cover;
display: block;/* avoids gap underneath */
}
#one img {
-webkit-clip-path: polygon(0 0, 0% 100%, 100% 0);
clip-path: polygon(0 0, 0% 100%, 100% 0);
}
#two img {
-webkit-clip-path: polygon(100% 100%, 0% 100%, 100% 0);
clip-path: polygon(100% 100%, 0% 100%, 100% 0);
}
#one {
position: absolute;
z-index: 0;
top: 0;
left: 0;
}
#two {
position: absolute;
top: 0px;
left: 0;
z-index: 0;
}
#one,
#two {
filter: sepia(100%);/* demo purpose */
}
#one:hover,
#two:hover {
filter: grayscale(0%);
}
<div id="one">
<img src="https://picsum.photos/800/600?image=1060">
</div>
<div id="two">
<img src="https://picsum.photos/800/600?image=1065">
</div>
https://codepen.io/gc-nomade/pen/aMBwYz
Here is another idea to create the same using less of code and without clip-path
.container {
width: 300px;
height: 200px;
position: relative;
overflow: hidden;
}
.container img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.container div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: skewX(-56.3deg); /* tan(angle) = Width/height --> angle = arctan(width/height) */
transform-origin: top;
overflow: hidden;
}
.container div img {
transform: skewX(56.3deg);
transform-origin: top;
}
.container img:hover{
filter:grayscale(100%);
}
<div class="container">
<img src="https://picsum.photos/800/600?image=1069">
<div>
<img src="https://picsum.photos/800/600?image=1051">
</div>
</div>

how do animation without keyframes but with transition

div {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
}
#keyframes example {
0% {}
35% {background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");}
36% {background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");}
100% {background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");transform: rotateY(160deg);}
}
div:hover {
animation-fill-mode: forwards;
animation-name: example;
animation-duration: 1s;
}
<div></div>
I don't use keyframes because i need set unique url for every animation. If i do this then need creator more 100 keyframes.
And i want to do this because with transition can set different url method js. But this not look how i want.
div {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
transition:
/* step 1 */
transform 1s,
/* step 2 */
background 0.0s 0.5s;
}
div:hover {
transform: rotateY(160deg);
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
}
<div></div>
My solution, you can create two elements front and back that lies inside card-container element and animate accordingly:
$(document).ready(function () {
$('.card-container').click(function () {
$(this).toggleClass('clicked');
});
});
.card-container {
position: relative;
overflow: hidden;
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
}
.card-container > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 1.3vmin;
transition: transform 1s, background 0.0s 0.5s;
transform-style: preserve-3d;
}
.card-container .front {
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
background-color: black;
transform: rotateY(0deg);
}
.card-container .back {
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
background-size: contain;
transform: rotateY(180deg);
}
.card-container.clicked .front {
transform: rotateY(180deg);
}
.card-container.clicked .back {
transform: rotateY(0deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card-container">
<div class="front"></div>
<div class="back"></div>
</div>
<div class="card-container">
<div class="front"></div>
<div class="back"></div>
</div>
Move the transition to the hover state and adjust the delay and you will have exactly the same thing:
div.card {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
}
div.card:hover {
transform: rotateY(160deg);
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
transition: transform 1s linear, background 0s 0.5s linear;
}
<div class="card"></div>
Why do you need 100 URL's to do this? You only need the front of the card image and the back of the card image.
img {
width:100%;
border:1px solid #e0e0e0;
border-radius:1vw;
}
.container {
/* Position and Size the Container */
position: absolute;
top: 17%;
bottom:0; /* Needed to keep the overall height larger than the card. */
left: 20%;
width: 25%;
/* Will inherit to children only (not all descendants) */
perspective: 900px;
}
#card .front {
/* Flip the front side of the card by rotating it around the y-axis. */
transform: rotateY(180deg);
}
#card:hover {
/* Rotate the card as a whole: */
transform: rotateY(180deg);
}
#card div {
/* Forces both elements to come out of the normal flow and occupy the same space on the page. */
position: absolute;
/*
The backface-visibility CSS property determines whether or not the back
face of the element is visible when facing the user. The back face of
an element is always a transparent background, letting, when visible,
a mirror image of the front face be displayed. If your foreground element
is opaque, this property may not need to be set.
*/
backface-visibility: hidden;
}
#card {
/*
Indicates that the children of the element should be positioned in the 3D-space.
And, pass any inherited perspective along to children.
*/
transform-style: preserve-3d;
/*
Changes to the transform property should take 1 second to
change from their current value to their new value.
*/
transition: transform 1s cubic-bezier(.75,1.25,.5,1.25);
}
<!-- The "container" will be the 3D space for us to work in. -->
<div class="container">
<!-- The "card" is the single entity that we will manipulate. -->
<div id="card">
<!-- The child elements make up pieces of the overall object.-->
<div class="front"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Ace_of_spades.svg/2000px-Ace_of_spades.svg.png"></div>
<div class="back"><img src="https://thumb1.shutterstock.com/display_pic_with_logo/3172829/620603528/stock-vector-ace-of-spades-with-eyel-vintage-design-t-shirts-620603528.jpg"></div>
</div>
</div>
You'll need to use a transition-timing-function with palindromic timing, so the card image changeover can always be in the middle. Examples of this include linear or ease-in-out (incorporated below).
Note that some browsers don't support transition on background-image though, so you may need to approach this effect differently for it to work in IE, for example.
div {
height: 41.4vmin;
width: 30vmin;
margin: 0.7vmin;
border-radius: 1.3vmin;
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/60933/tkZK7aYQUjM.jpg");
background-size: contain;
transition: transform 1s ease-in-out, background 0s .5s;
}
div:hover {
transform: rotateY(160deg);
background-image: url("https://sun9-8.userapi.com/c840530/v840530203/6092c/fR8eCsT009k.jpg");
}
<div></div>

How to make gradient border with mouse hover 360 degree rotation

.clients-img::after {
content: '';
position: relative;
background-image: url('https://i.stack.imgur.com/Y2vyB.png');
background-repeat: no-repeat;
float: left;
margin-left: 15px;
transition: all 1.8s ease;
width: 135px;
height: 135px;
}
.clients-slider-inside img {
border-radius: 50%;
position: absolute;
padding: 14px;
left: 0px;
top: 0px;
width: 135px;
height: 135px;
}
.clients-img:hover::after {
transform: rotate(360deg) translate(0px);
}
<div class="clients-slider-inside">
<div class="clients-img"> <img src="https://i.stack.imgur.com/tz2aw.png" alt="clients img"> </div>
</div>
On Mouse hover rotate 360 degree and On Mouse out no any effect.
This type gradient border. So can you please help me for perfect rotation in circle.
You can avoid using an image and recreate the gradient using multiple linear-gradient on the background of the container. Then the idea is to rotate the whole container and rotate the image in the opposite direction so you create the effect of background rotation.
.clients-img {
display: inline-block;
position: relative;
border-radius: 50%;
background: linear-gradient(to right, #fff 50%, transparent 50%), linear-gradient(-15deg,#6fda44 25%, #fff 80%);
transition:1s all;
}
.clients-img img {
border-radius: 50%;
width: 135px;
height: 135px;
padding: 15px;
vertical-align: top;
transition:1s all;
}
.clients-img:hover {
transform: rotate(360deg);
}
.clients-img:hover img{
transform: rotate(-360deg);
}
<div class="clients-img"> <img src="https://i.stack.imgur.com/tz2aw.png" alt="clients img"> </div>

Animated offset border css? javascript?

Attached you'll find an image explaining what i'd like to accomplish.
I would like to have my background set, over that I would like to have a border that's a bit offset from the background. In some way I need to find a way to animate every single side of the border by it's own.
I would like the top border to animate in from the right, the bottom one from the left. The left one from the bottom and the right one from the top.
This is giving me a big headache. Anybody have any ideas?
What I've done is:
<div id="#mainsection"></div>
The border is created in CSS:
#mainsection:after {
content: '';
position: absolute;
top: 40px;
right: 40px;
bottom: 40px;
left: 40px;
border: 4px solid #96896C;
}
What I've realised is that this is not going to work as I need every border-part as separate items.
You could perhaps use linear gradients and a couple of ::before and ::after pseudo elements. This wont give you entirely separate animations but the horizontal and vertical borders can be animated separately.
body, html {
height: 100%;
}
#mainsection {
height: 100%;
position: relative;
background: url(https://placehold.it/1000x1000) center center;
}
#mainsection:after {
content: '';
position: absolute;
top: 40px;
right: 40px;
bottom: 40px;
left: 40px;
background-image: linear-gradient(black, black), linear-gradient(transparent, transparent), linear-gradient(black, black);
background-repeat: no-repeat;
background-size: 2px 0%, calc(100% - 4px) 100%, 2px 0%;
background-position: left bottom, 0 0, right top;
transition: background-size 1.5s ease;
}
#mainsection:before {
content: '';
position: absolute;
top: 40px;
right: 40px;
bottom: 40px;
left: 40px;
background-image: linear-gradient(black, black), linear-gradient(transparent, transparent), linear-gradient(black, black);
background-repeat: no-repeat;
background-size: 0% 2px, calc(100% - 4px) 100%, 0% 2px;
background-position: left bottom, 0 0, right top;
transition: background-size 2s ease .5s; /* .5s delay */
}
#mainsection:hover:after {
background-size: 2px 100%, calc(100% - 4px) 100%, 2px 100%;
}
#mainsection:hover:before {
background-size: 100% 2px, calc(100% - 4px) 100%, 100% 2px;
}
<div id="mainsection"></div>
A similar solution to #Turnip but by simply using multiple gradient on the same div. And you can control the animation of each one by playing with initial and final values of background-size and background-position:
body {
margin:0;
}
.container {
height: 100vh;
padding:40px;
background:
linear-gradient(#000,#000) top right content-box,
linear-gradient(#000,#000) top right content-box,
linear-gradient(#000,#000) bottom left content-box,
linear-gradient(#000,#000) bottom left content-box,
url(https://placehold.it/1000x1000) center center;
background-size:0 3px,3px 0,0 3px,3px 0,auto;
background-repeat:no-repeat;
transition:2s;
box-sizing:border-box;
}
.container:hover {
background-size:
100% 3px,
3px 100%,
100% 3px,
3px 100%,
auto; /* This is for image */
}
<div class="container"></div>
Then simply adjust the position to control the animation:
body{
margin:0;
}
.container {
height: 100vh;
padding:40px;
background:
linear-gradient(#000,#000) top left content-box,
linear-gradient(#000,#000) top right content-box,
linear-gradient(#000,#000) bottom right content-box,
linear-gradient(#000,#000) bottom left content-box,
url(https://placehold.it/1000x1000) center center;
background-size:0 3px,3px 0,0 3px,3px 0,auto;
background-repeat:no-repeat;
transition:2s;
box-sizing:border-box;
}
.container:hover {
background-size:
100% 3px,
3px 100%,
100% 3px,
3px 100%,
auto; /* This is for image */
}
<div class="container"></div>
Another one:
body {
margin:0
}
.container {
height: 100vh;
padding:40px;
background:
linear-gradient(#000,#000) top content-box,
linear-gradient(#000,#000) right content-box,
linear-gradient(#000,#000) bottom content-box,
linear-gradient(#000,#000) left content-box,
url(https://placehold.it/1000x1000) center center;
background-size:0 3px,3px 0,0 3px,3px 0,auto;
background-repeat:no-repeat;
transition:2s;
box-sizing:border-box;
}
.container:hover {
background-size:
100% 3px,
3px 100%,
100% 3px,
3px 100%,
auto; /* This is for image */
}
<div class="container"></div>

Categories