How can I animate a bar charts clip-path? - html

I have a bar chart that uses a gradient background on the bars.
The gradient height is constant and I´m using clip path to show only a portion of the bar. This way, the darkest part is always at 100% height.
The problem I´m having is to animate each bar from 0px height to its given height.
First I tried animating the clip-path using animation, transition and transform. But no luck. Then I tried animating the bar itself using animations - and it kind of works. Only, it goes from top down rather than bottom up. See my fiddle here.
How can I make the bars expand from bottom?
.barChart { clear: both; height: 70px; width: 170px; border-bottom: solid 2px #eee; }
.bar {
float: left;
margin: 4px;
width: 6px;
background: linear-gradient(to top, #8BC2CA 0%, #2E92A0 100%);
animation: expandBar 2s ease;
animation-fill-mode: forwards;
}
.bar1 { clip-path: inset(80% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar2 { clip-path: inset(20% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar3 { clip-path: inset(60% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar4 { clip-path: inset(80% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar5 { clip-path: inset(20% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar6 { clip-path: inset(60% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar7 { clip-path: inset(80% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar8 { clip-path: inset(20% 0 0 0 round 1.5px 1.5px 0px 0px); }
.bar9 { clip-path: inset(60% 0 0 0 round 1.5px 1.5px 0px 0px); }
#keyframes expandBar{
0% {
height: 0;
}
100%{
height: 60px;
}
}
<div class="barChart">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
<div class="bar bar3"></div>
<div class="bar bar4"></div>
<div class="bar bar5"></div>
<div class="bar bar6"></div>
<div class="bar bar7"></div>
<div class="bar bar8"></div>
<div class="bar bar9"></div>
</div>

Instead of clip-path you can consider height on your element and a fixed size for your gradient. Then you can easily animate that height.
The trick for the animation is to make the elements inline-block (instead of float) and have a hidden one (set with pseudo-element) that will be height:100% in order to define the baseline at the bottom making your element to animate from bottom and not top.
.barChart {
height: 70px;
width: 170px;
border-bottom: solid 2px #eee;
}
.barChart:before {
content:"";
display:inline-block;
height:100%;
}
.bar {
display:inline-block;
margin: 4px;
width: 6px;
background: linear-gradient(to top, #8BC2CA 0, #2E92A0 70px); /*same as height:100%*/
animation: expandBar 2s ease;
}
.bar1 {height: 80%;}
.bar2 {height: 20%;}
.bar3 {height: 60%;}
.bar4 {height: 70%;}
.bar5 {height: 50%;}
#keyframes expandBar {
0% {
height: 0%;
}
}
<div class="barChart">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
<div class="bar bar3"></div>
<div class="bar bar4"></div>
<div class="bar bar5"></div>
</div>
In case you are intrested you can do this with only one element and multiple background:
.barChart {
height: 70px;
width: 170px;
border-bottom: solid 2px #eee;
--grad:linear-gradient(to top, #8BC2CA 0, #2E92A0 70px);
background-image:var(--grad), var(--grad), var(--grad), var(--grad), var(--grad);
background-size:6px 60%,6px 80%,6px 20%,6px 70%,6px 50%;
background-position:4px 100%, 14px 100%, 26px 100%, 38px 100%,48px 100%;
background-repeat:no-repeat;
animation: expandBar 2s ease;
}
#keyframes expandBar {
0% {
background-size: 6px 0%;
}
}
<div class="barChart">
</div>

Related

How can I make my logo responsive at the top of my website?

Basically, I have created a loader and logo for my website. However, I have an issue with my logo, which is at the top of the website. The logo is not responsive. I would like my logo to be at the top middle of my website, but, when someone goes to view it on their window screen, the logo moves to somewhere other than the middle. I have tried adding a display: flex; and justify content; on my load class, but it does not work and the 3D effect goes away. How can I prevent the logo from moving and let it stay in the top middle regardless of someone's window size? Any help would be appreciated. Thanks. Here is my code.
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Hind&display=swap" rel="stylesheet">
<title>Document</title>
</head>
<body>
<div class="load">
<p id = "spinner">M</p>
<div class="container">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
CSS
body{
background: #21312F;
}
.container{
position: absolute;
height: 400px;
width: 200px;
top: 20%;
left: 43%;
}
.loader{
height: 95%;
width: 95%;
margin: 2.5%;
border-top: 3px solid #49D49F;
border-bottom: 3px solid #FF6542;
border-radius: 50%;
animation: 30s rotate linear infinite;
}
.load {
width: 100%;
position: fixed;
height: 100vh;
z-index: 99;
overflow: hidden;
background: #21312F;
}
#keyframes rotate{
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(810deg);
}
}
#spinner{
font-size: 50px;
text-align: center;
animation-name: spin, depth;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 3s;
transform-style: preserve-3d;
position: relative;
top: 20px;
left: -40px;
color: #49D49F;
font-family: 'Hind', sans-serif;
margin: 0 auto;
}
#spinner::before, #spinner::after{
content: "M";
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
transform: rotateY(0.5deg);
transform-origin: 0 50%;
color: #FF6542;
}
#spinner::after{
transform: rotateY(-0.5deg);
transform-origin: 100% 50%;
}
#keyframes spin{
from{
transform: rotateY(0deg);
}
to{
transform: rotateY(-360deg)
}
}
#keyframes depth {
0% { text-shadow: 0 0 black; }
25% { text-shadow: 1px 0 black, 2px 0 black, 3px 0 black, 4px 0 black, 5px 0 black, 6px 0 black; }
50% { text-shadow: 0 0 black; }
75% { text-shadow: -1px 0 black, -2px 0 black, -3px 0 black, -4px 0 black, -5px 0 black, -6px 0 black; }
100% { text-shadow: 0 0 black; }
}
I am not sure but do you want like this? :
body{
margin: 0;
padding: 0;
background: #21312F;
}
.container{
position: absolute;
height: 400px;
width: 200px;
top: 20%;
left: 50%;
transform: translateX(-50%);
}
.loader{
height: 95%;
width: 95%;
margin: 2.5%;
border-top: 3px solid #49D49F;
border-bottom: 3px solid #FF6542;
border-radius: 50%;
animation: 30s rotate linear infinite;
}
.load {
width: 100%;
position: fixed;
height: 100vh;
z-index: 99;
overflow: hidden;
background: #21312F;
}
#keyframes rotate{
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(810deg);
}
}
#spinner{
font-size: 50px;
text-align: center;
animation-name: spin, depth;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-duration: 3s;
transform-style: preserve-3d;
position: relative;
top: 20px;
color: #49D49F;
font-family: 'Hind', sans-serif;
margin: 0 auto;
}
#spinner::before, #spinner::after{
content: "M";
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
transform: rotateY(0.5deg);
transform-origin: 0 50%;
color: #FF6542;
}
#spinner::after{
transform: rotateY(-0.5deg);
transform-origin: 100% 50%;
}
#keyframes spin{
from{
transform: rotateY(0deg);
}
to{
transform: rotateY(-360deg)
}
}
#keyframes depth {
0% { text-shadow: 0 0 black; }
25% { text-shadow: 1px 0 black, 2px 0 black, 3px 0 black, 4px 0 black, 5px 0 black, 6px 0 black; }
50% { text-shadow: 0 0 black; }
75% { text-shadow: -1px 0 black, -2px 0 black, -3px 0 black, -4px 0 black, -5px 0 black, -6px 0 black; }
100% { text-shadow: 0 0 black; }
}
<body>
<div class="load">
<p id = "spinner">M</p>
<div class="container">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
<div class="loader">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>

How to fix clip-path cutting off a small part of a wrapped image?

I'm trying to have an image inside a clip-path'd container display correctly. I wanted to add a slight zoom effect on hover as well.
A small part at the bottom is being cut off when not hovered.
However, once you hover the image and it zooms in, everything looks fine.
I cannot set a fixed height, which would solve the problem more easily since I want to add the image to a responsive flex container later.
I reduced the problem to its core in this jsfiddle: https://jsfiddle.net/pzf459cd/1/
.Image-Wrapper {
width: 50%;
}
.Image-Zoom-Wrapper {
clip-path: polygon(100% 0, 100% 91%, 62% 100%, 0 91%, 0 0, 62% 9%);
object-fit: contain;
}
.Image {
transition: all 0.5s linear;
}
.Image-Wrapper:hover .Image {
transform: scale(1.05, 1.05);
transition: all 0.5s linear;
}
body {
background-color: #000;
}
<div class="Image-Wrapper">
<div class="Image-Zoom-Wrapper">
<img class="Image" src="https://picsum.photos/id/304/500/300">
</div>
</div>
See my solution for a similiar task below. It works, but there might be an easier/better one.
jsfiddle: https://jsfiddle.net/fj5z7bue/
.wrap{
position: relative;
width: 50%;
filter: drop-shadow(3px 4px 8px rgba(38, 50, 56, 0.4));
}
.clip{
position: relative;
display: block;
overflow: hidden;
clip-path: polygon(60% 5%, 100% 0, 100% 95%, 60% 100%, 0 95%, 0 0);
height: 100%;
width: 100%;
background-color: rgb(240, 240, 240);
}
.pseudoimg{
width: 100%;
opacity: 0;
}
.img{
position: absolute;
top: 0;
left: 0;
z-index: 2;
background-image: url('https://picsum.photos/id/304/500/300');
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
min-height: 100%;
min-width: 100%;
transform: scale(1);
transition: all 0.4s ease-out;
}
.wrap:hover{
cursor: pointer;
}
.wrap:hover .img{
transform: scale(1.4);
transition: all 12s ease-out;
}
.button{
position: absolute;
height: 60px;
width: 60px;
border-radius: 30px;
background-color: rgb(255, 255, 255);
z-index: 3;
right: -15px;
bottom: -5px;
filter: drop-shadow(3px 4px 8px rgba(38, 50, 56, 0.4));
}
<div class="wrap">
<div class="button"></div>
<div class="clip">
<img class="pseudoimg" src="https://picsum.photos/id/304/500/300"/>
<div class="img"></div>
</div>
</div>

Strange behaviour in CSS3 transition with linear gradient

I am trying to make a progress bar and using css3 transition to give it a fill effect.
jsfiddle here
When I give it a fixed size, it works as usual, but Problem is when I set the background-size:100% the fill becomes stretch.
How can I create fill effect using background-size:100%?
Progressbar1 is with fixed width and background-size
Progressbar2 is with 100% width and background-size
/* PROGRESS */
.progress {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 24em;
}
.progress-bar {
animation-duration: 3s;
animation-name: width;
background-image: repeating-linear-gradient(to right, transparent, #000 50px, #fff 100px, transparent 150px);
background-size: 24em 0.25em;
height: 100%;
position: relative;
width:100%
}
.progress2 {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 100%;
}
.progress-bar2 {
animation-duration: 3s;
animation-name: width;
background-image: repeating-linear-gradient(to right, transparent, #000 50px, #fff 100px, transparent 150px);
background-size: 100% 0.25em;
height: 100%;
position: relative;
width:100%
}
/* ANIMATIONS */
#keyframes width {
0%, 100% {
transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
}
0% {
width: 0%;
}
100% {
width: 100%;
}
}
<div class="progress">
<div class="progress-bar">
</div>
</div>
<br>
<div class="progress2">
<div class="progress-bar2">
</div>
</div>

How to create a circle-shaped image that emits a color light effect that runs in all browsers?

I was working on this website, which uses bootstrap. On it there are circle-shaped images and when the mouse hovers I want to create an effect of that picture as creating a color light. For that, I used box-shadow because shadows wouldn't interfere within the image. The code looks like this:
HTML:
<div class="col-sm-3" id="af">
<br/><br/><br/>
<center>
<img src="OnePicture.jpg" class="img-circle smallpic"/>
</center>
<!-- The div continues with text -->
</div>
CSS:
.smallpic{
max-width:100px;
max-height: 100px;
border: 3px solid transparent;
/*Trying to force GPU Acceleration*/
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
-webkit-transition: all 1s;
-webkit-transition-timing-function: ease;
transition: all 1s;
transition-timing-function: ease;
}
#af:hover .smallpic{
border: 3px solid #E3000E;
-webkit-transform: translate3d(0,0,0);
-moz-box-shadow: 0 0 500px 100px #E3000E;
-webkit-box-shadow: 0 0 500px 100px #E3000E;
box-shadow: 0 0 500px 100px #E3000E;
}
This code did exactly what I want, but due to a Webkit bug, it won't work properly on any Webkit based browser, which includes the popular Google Chrome.
Here is the result in Google Chrome: link
In my tests, the code worked really well in Mozilla Firefox, Microsoft Edge and also Internet Explorer. But Google Chrome, Vivaldi and other webkit based browsers tested got the same buggy look. Is there another way to make that effect work in all browsers besides box-shadow usage?
But it is still possible to have the same behaviour in all browsers. You need just to modify your HTML and CSS.
Here the example HTML
<div class="wrapper red">
<div class="image"></div>
<h2>Red</h2>
</div>
<div class="wrapper blue">
<div class="image"></div>
<h2>Blue</h2>
</div>
<div class="wrapper green">
<div class="image"></div>
<h2>Green</h2>
</div>
Here the example CSS:
.wrapper {
display: inline-block;
position: relative;
width: 300px;
height: 300px;
}
.wrapper:before {
position: absolute;
content: ' ';
z-index: -1;
top: 0;
left: 0;
bottom: 0;
right: 0;
transition: all 2s;
}
.blue:before {
background: radial-gradient(ellipse at center, rgba(0, 0, 255, .7) 10%, rgba(0, 0, 255, 0) 70%);
opacity: 0;
}
.red:before {
background: radial-gradient(ellipse at center, rgba(255, 0, 0, .7) 10%, rgba(255, 0, 0, 0) 70%);
opacity: 0;
}
.green:before {
background: radial-gradient(ellipse at center, rgba(0, 255, 0, .7) 10%, rgba(0, 255, 0, 0) 70%);
opacity: 0;
}
.wrapper:hover:before {
opacity: 1;
}
.image {
margin: 100px auto 0;
border: 4px solid red;
border-radius: 50%;
width: 100px;
height: 100px;
}
.green .image {
border-color: rgb(0, 255, 0);
background-color: rgba(0, 255, 0, .3);
}
.red .image {
border-color: rgb(255, 0, 0);
background-color: rgba(255, 0, 0, .3);
}
.blue .image {
border-color: rgb(0, 0, 255);
background-color: rgba(0, 0, 255, .3);
}
h2 {
text-align: center;
}
Here a live demo

HTML5 Animation working on Chrome but not Firefox

The following is an earth globe that's rotating. Though this animation is working fine on Chrome, it doesn't work at all on Firefox, and it just stands still. Any help on how to solve this?
JSFiddle.
<div id="page-wrapper">
<div class="row">
<div class="center-block img-responsive" id="earth"></div>
</div>
</div>
#earth {
width: 100px;
height: 100px;
background: url('../images/Earth-Color.jpg');
border-radius: 50%;
background-size: 210px;
box-shadow: inset 16px 0 40px 6px rgb(0, 0, 0),
inset -3px 0 6px 2px rgba(255, 255, 255, 0.2);
animation-name: rotate;
animation-duration: 4s;
animation-iteration-count: infinite;
animation-timing-function: linear;
margin-top:200px;
}
#keyframes rotate {
from { background-position-x: 0px; }
to { background-position-x: 210px; }
}
You need to set the background-position property as a whole in #keyframes
#keyframes rotate {
from { background-position: 0px 0; }
to { background-position: 210px 0; }
}
jsFiddle
background-position-x and background-position-y are not yet implemented in FireFox. But it seems like they will be added in future.
Another SO question on this