How to make leading edge of CSS circle spinner half moon shaped - javascript

Image: Circular spinner rotating along the border rim of other solid circle
Please visit: https://codepen.io/sadashivjp/pen/oqqzwg
I have create a UI codepen here. You are free to make any changes in this, and post the solution here.
The same code is as follows:
.outer-circle{
width:330px;
height:330px;
border:30px solid #001b33;
position:absolute;
top:0; bottom:0; left:0;right:0;
margin:auto;
border-radius:50%;
}
.spinner {
animation: rotate 5s linear infinite;
border-radius: 50%;
height: 360px;
width: 360px;
position: relative;
left: -15px;
top: -15px;
}
.spinner:before,
.spinner:after {
content: '';
position: absolute;
}
.spinner:before {
border-radius: 50%;
background:
linear-gradient(0deg, hsla(0, 0%, 100%, 0) 50%, hsla(0, 0%, 100%, 0.1) 100%) 0% 0%,
linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 0%, hsla(0, 0%, 100%, 0.5) 100%) 100% 0%,
linear-gradient(180deg, hsla(0, 0%, 100%, 0.5) 0%, hsla(0, 0%, 100%, 0.60) 100%) 100% 100%,
linear-gradient(360deg, hsla(0, 0%, 100%, 0.60) 0%, hsla(0, 0%, 100%, 0.70 ) 100%) 0% 100%
;
background-repeat: no-repeat;
background-size: 50% 50%;
top: -1px;
bottom: -1px;
left: -1px;
right: -1px;
}
.spinner:after {
background: black;
border: 15px solid #001b33;
border-radius: 50%;
top: 3%;
bottom: 3%;
left: 3%;
right: 3%;
}
#keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
<div class="outer-circle">
<div class="spinner"></div>
</div>
There are two problems in this code:
1) It is causing wobbling(shaking) effect of spinner circle in IE11 browser. But, works perfect in Google chrome browser.
2) As in attached image, need the similar effect of half moon shaped(cylindrical bottom shaped) at the leading edge at the front of the inner white spinner circle.
How to solve these two issues?
Modification of my existing code or providing solution with SVG or Canvas on any other would be fine.

Add a div inside your spinner.
.outer-circle{
width:330px;
height:330px;
border:30px solid #001b33;
position:absolute;
top:0; bottom:0; left:0;right:0;
margin:auto;
border-radius:50%;
}
.spinner {
animation: rotate 5s linear infinite;
border-radius: 50%;
height: 360px;
width: 360px;
position: relative;
left: -15px;
top: -15px;
}
.spinner:before,
.spinner:after {
content: '';
position: absolute;
}
.spinner:before {
border-radius: 50%;
background:
linear-gradient(0deg, hsla(0, 0%, 100%, 0) 50%, hsla(0, 0%, 100%, 0.1) 100%) 0% 0%,
linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 0%, hsla(0, 0%, 100%, 0.5) 100%) 100% 0%,
linear-gradient(180deg, hsla(0, 0%, 100%, 0.5) 0%, hsla(0, 0%, 100%, 0.60) 100%) 100% 100%,
linear-gradient(360deg, hsla(0, 0%, 100%, 0.60) 0%, hsla(0, 0%, 100%, 0.70 ) 100%) 0% 100%
;
background-repeat: no-repeat;
background-size: 50% 50%;
top: -1px;
bottom: -1px;
left: -1px;
right: -1px;
}
.spinner:after {
background: black;
border: 15px solid #001b33;
border-radius: 50%;
top: 3%;
bottom: 3%;
left: 3%;
right: 3%;
}
#keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.circle{
background: #b1bac1;
width: 10px;
height: 10px;
position: absolute;
top: 177px;
bottom: 0;
left: 0;
right: 0;
border-radius: 50% 50%;
}
<div class="outer-circle">
<div class="spinner">
<div class="circle">
</div>
</div>
</div>

.outer-circle{
width:330px;
height:330px;
border:30px solid #001b33;
position:absolute;
top:0; bottom:0; left:0;right:0;
margin:auto;
border-radius:50%;
}
.spinner {
animation: rotate 5s linear infinite;
border-radius: 50%;
height: 360px;
width: 360px;
position: relative;
left: -15px;
top: -15px;
}
.spinner:before,.spinner:after,
.outer-circle:after {
content: '';
position: absolute;
}
.spinner:before {
border-radius: 50%;
background:
linear-gradient(0deg, hsla(0, 0%, 100%, 0) 50%, hsla(0, 0%, 100%, 0.1) 100%) 0% 0%,
linear-gradient(90deg, hsla(0, 0%, 100%, 0.1) 0%, hsla(0, 0%, 100%, 0.5) 100%) 100% 0%,
linear-gradient(180deg, hsla(0, 0%, 100%, 0.5) 0%, hsla(0, 0%, 100%, 0.60) 100%) 100% 100%,
linear-gradient(360deg, hsla(0, 0%, 100%, 0.60) 0%, hsla(0, 0%, 100%, 0.70 ) 100%) 0% 100%
;
background-repeat: no-repeat;
background-size: 50% 50%;
top: -1px;
bottom: -1px;
left: -1px;
right: -1px;
}
.spinner:after{
background: #afb7bf;
height: 15px; width:15px;
border-radius: 50%;
top: 175px;
left: -1px;
right: -100px;
bottom: 0px;
}
.outer-circle:after {
background: black;
border: 15px solid #001b33;
border-radius: 50%;
top: -1px;
bottom: -1px;
left: -1px;
right: -1px;
}
#keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
<div class="outer-circle">
<div class="spinner"></div>
</div>
I hope this is the solution you are looking for!

Related

How can I make pseudo-element background align with parent's background?

I have this simple container, and generated some vertical stripes to use as background.
export default function App() {
return <div className="container"></div>;
}
.container {
height: 200px;
width: 100%;
background-image: linear-gradient(
45deg,
#000000 12.5%,
#ffffff 12.5%,
#ffffff 50%,
#000000 50%,
#000000 62.5%,
#ffffff 62.5%,
#ffffff 100%
);
background-size: 11.31px 11.31px;
position: relative;
}
I want to create a pointer (arrow), that is positioned at the top, or bottom, but that has the same background as the parent. And no matter which value I give to left or right, it should have the stripes aligned with the parent's.
Right now, I have this code for the pseudo-element.
.container::after {
content: "";
position: absolute;
bottom: 100%;
background-image: inherit;
background-size: inherit;
width: 25px;
height: 25px;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
left: 27px;
}
But as you can see in the Sandbox below, the stripes are not aligned correctly of the .container, I mean, they do not come as "continuation" of the said background. Is there a possible trick I can make it part of the same background?
Sandbox link: https://codesandbox.io/s/hopeful-browser-tnt8zq
Here's also a picture for reference.
https://i.imgur.com/D3VbYAa.png
The stripes should blend like this, no matter where the arrow is positioned horizontally.
https://i.imgur.com/kb0uQTK.png
Use This code
.container {
height: 200px;
width: 100%;
background-image: linear-gradient(
45deg,
#000000 12.5%,
#ffffff 12.5%,
#ffffff 50%,
#000000 50%,
#000000 62.5%,
#ffffff 62.5%,
#ffffff 100%
);
background-size: 11.31px 11.31px;
position: relative;
}
.container::after {
content: "";
position: absolute;
bottom: 100%;
background-image: inherit;
background-size: inherit;
width: 25px;
height: 25px;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
left: 48%;
top:50%;
}
You can make things quite flexible, easy to change, by using CSS variables.
This snippet scraps the pseudo element, makes the container a bit bigger and cuts out the shape required. The way you are assured of getting the correctly aligned background.
Set the width, height and distance along the left of the pointy bit as you require in those CSS variables.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
padding: 50px;
}
.container {
--aH: 25px;
/* height of the arrow */
--aW: 25px;
/* width of the arrow */
--aL: 27px;
/* distance along the top of the start of the arrow */
--h: 200px;
/* height of container */
height: calc(var(--h) + var(--aH));
width: 100%;
background-image: linear-gradient( 45deg, #000000 12.5%, #ffffff 12.5%, #ffffff 50%, #000000 50%, #000000 62.5%, #ffffff 62.5%, #ffffff 100%);
background-size: 11.31px 11.31px;
position: relative;
clip-path: polygon(0 var(--aH), var(--aL) var(--aH), calc(var(--aL) + (var(--aW) / 2)) 0, calc(var(--aL) + var(--aH)) var(--aH), 100% var(--aH), 100% 100%, 0 100%);
}
<div class="container"></div>
UPDATE: there is a requirement to have the container height fixed by its content, not a px value. This snippet is as above except the background image and its associated clip path is put onto the container's before pseudo element. That way it can pick up the height of the container and add further height to accommodate the arrow.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
padding: 50px;
}
.container {
--aH: 25px;
/* height of the arrow */
--aW: 25px;
/* width of the arrow */
--aL: 27px;
/* distance along the top of the start of the arrow */
position: relative;
}
.container::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
--h: 100%;
/* height of container */
height: calc(var(--h) + var(--aH));
width: 100%;
transform: translateY(calc(-1 * var(--aH)));
background-color: pink;
background-image: linear-gradient( 45deg, #000000 12.5%, #ffffff 12.5%, #ffffff 50%, #000000 50%, #000000 62.5%, #ffffff 62.5%, #ffffff 100%);
background-size: 11.31px 11.31px;
clip-path: polygon(0 var(--aH), var(--aL) var(--aH), calc(var(--aL) + (var(--aW) / 2)) 0, calc(var(--aL) + var(--aH)) var(--aH), 100% var(--aH), 100% 100%, 0 100%);
z-index: -1;
}
<div class="container">some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br>some stuff<br></div>
We can play with clip-path values and position left values to get the desire outcome.
please try with below code.
.container::after {
content: "";
position: absolute;
bottom: 100%;
background-image: inherit;
background-size: inherit;
width: 25px;
height: 25px;
clip-path: polygon(40% 0%, 0% 100%, 100% 95%);
left: 20px;
}

How to reverse a #keyframe animation on mouse off?

I need to reverse the wipe animation when the mouse moves off the button. Is there a way to do this in only CSS?
I know I can reverse the animation, but I'm not sure where to put in the CSS file in order to get the right animation. If I put it in .get-started, it wipes the border and I'm unable to interact with the button completely.
HTML:
<div class="get-started" id="button">
<h4 class="part1">Get <span class="part2">Started</span></h4>
</div>
CSS:
body {
background:black;
}
#button {
display: flex;
font-size: 2.5rem;
color: white;
align-items: center;
justify-content: center;
width: 250px;
height: 75px;
position: relative;
top: -30%;
left: calc(50% - 125px);
}
.get-started {
--borderWidth: 5px;
position: relative;
border-radius: var(--borderWidth);
background-color: #8551FF;
box-shadow: inset 0 0 0 5px white;
z-index:1;
}
.get-started h4.part1 {
color: #FFFFFF;
font-family: 'Coves Light';
font-weight: normal;
}
.get-started span.part2 {
color: #5EFF00;
font-family: 'Coves';
font-weight: bold;
}
.get-started:after {
content: '';
position: absolute;
}
.get-started:hover:after {
background: linear-gradient(60deg, #f79533, #f37055, #ef4e7b, #a166ab, #5073b8, #1098ad, #07b39b, #6fba82);
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 2px;
background-size: 300% 300%;
animation: frame-enter 1s forwards ease-in-out reverse, gradient-animation 4s ease-in-out infinite;
}
/* motion */
#keyframes gradient-animation {
0% {
background-position: 15% 0%;
}
50% {
background-position: 85% 100%;
}
100% {
background-position: 15% 0%;
}
}
#keyframes frame-enter {
0% {
clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), 5px calc(100% - 5px), 5px 100%, 100% 100%, 100% 0%, 0% 0%);
}
25% {
clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) calc(100% - 5px), calc(100% - 5px) 100%, 100% 100%, 100% 0%, 0% 0%);
}
50% {
clip-path: polygon(0% 100%, 5px 100%, 5px 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 5px, 100% 0%, 0% 0%);
}
75% {
-webkit-clip-path: polygon(0% 100%, 5px 100%, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 5px, 5px 0%, 0% 0%);
}
100% {
-webkit-clip-path: polygon(0% 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 5px 100%, 0% 100%);
}
}
Runnable Snippet
You could try
.get-started:not(:hover):after {}
with an inversed animation. But it can have unwanted behaviour on initial pageload, it always starts with this animation I guess. Sometimes you can't avoid javascript. Adding a class on mouseout and removing it again on mouseenter might work, so you can assign a reverse animation to this class.
var els = document.querySelectorAll('.get-started');
for (var i = 0; i < els.length; i++) {
els[i].addEventListener('mouseleave', function(e) {
e.target.classList.add('mouseleaveAnimationClass');
});
els[i].addEventListener('mouseenter', function(e) {
e.target.classList.remove('mouseleaveAnimationClass');
});
}

CSS circle rotate animation causing wobbling(shaking) in IE11 browser

Image: Spinner rotating along the border rim of other solid circle
Visit https://codepen.io/bygrace1986/pen/wmyarb
HTML:
<div class="outer-circle">
<div class="spinner"></div>
</div>
CSS:
.outer-circle{
width:330px;
height:330px;
border:30px solid #001b33;
position:absolute;
top:0; bottom:0; left:0;right:0;
margin:auto;
border-radius:50%;
}
.spinner {
animation: rotate 4s linear infinite;
border-radius: 50%;
height: 360px;
width: 360px;
position: relative;
left: -15px;
top: -15px;
}
.spinner:before,
.spinner:after {
content: '';
position: absolute;
}
.spinner:before {
border-radius: 50%;
background:
linear-gradient(0deg, hsla(0, 0%, 100%, 1) 50%, hsla(0, 0%, 100%, 0.9) 100%) 0% 0%,
linear-gradient(90deg, hsla(0, 0%, 100%, 0.9) 0%, hsla(0, 0%, 100%, 0.6) 100%) 100% 0%,
linear-gradient(180deg, hsla(0, 0%, 100%, 0.6) 0%, hsla(0, 0%, 100%, 0.3) 100%) 100% 100%,
linear-gradient(360deg, hsla(0, 0%, 100%, 0.3) 0%, hsla(0, 0%, 100%, 0 ) 100%) 0% 100%
;
background-repeat: no-repeat;
background-size: 50% 50%;
top: -1px;
bottom: -1px;
left: -1px;
right: -1px;
}
.spinner:after {
background: white;
border: 15px solid #001b33;
border-radius: 50%;
top: 3%;
bottom: 3%;
left: 3%;
right: 3%;
}
#keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
The inner spinner circle is wobbling(shaking) in IE 11 browser. It works perfectly in Google chrome. Have to test in IE browser only to look at the issue. Appreciate any suggestion/help here...........................................................................................................................................................

Display an image wrapped around a sphere with CSS/Javascript

I am aware that this is possible with three.js but it seems that three.js maxes a mesh sphere and the image gets a bit distorted. I'd also rather just use CSS if possible.
Is this something that can be done with CSS transforms? Ideally I'd like to animate it going from a flat image to a sphere so something that can easily be animated with CSS transitions would be great.
I found a nice example of how to do this with CSS on codepen: http://codepen.io/donovanh/pen/GBIiv. It doesn't actually wrap the image in 3d but it looks nice enough for my purposes.
Here is the relevant html/css:
<section class="stage">
<figure class="ball"><span class="shadow"></span></figure>
</section>
.ball {
display: inline-block;
width: 100%;
height: 100%;
margin: 0;
border-radius: 50%;
position: relative;
-webkit-transform-style: preserve-3d;
background: url('https://alxgroup.net/gto-range-builder/images/treeSS.png') repeat-x;
background-size: auto 100%;
-webkit-animation: move-map 30s infinite linear;
-moz-animation: move-map 30s infinite linear;
-o-animation: move-map 30s infinite linear;
-ms-animation: move-map 30s infinite linear;
animation: move-map 30s infinite linear;
}
.ball:before {
content: "";
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
border-radius: 50%;
box-shadow: -40px 10px 70px 10px rgba(0,0,0,0.5) inset;
z-index: 2;
}
.ball:after {
content: "";
position: absolute;
border-radius: 50%;
width: 100%;
height: 100%;
top: 0;
left: 0;
-webkit-filter: blur(0);
opacity: 0.3;
background: radial-gradient(circle at 50% 80%, #81e8f6, #76deef 10%, #055194 66%, #062745 100%);
}
.ball .shadow {
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.1) 40%, rgba(0, 0, 0, 0) 50%);
-webkit-transform: rotateX(90deg) translateZ(-150px);
-moz-transform: rotateX(90deg) translateZ(-150px);
-ms-transform: rotateX(90deg) translateZ(-150px);
-o-transform: rotateX(90deg) translateZ(-150px);
transform: rotateX(90deg) translateZ(-150px);
z-index: -1;
}
body {
width: 300px;
margin: 20px auto;
background: linear-gradient(to bottom, rgba(100, 100, 100, 0.2) 0%, rgba(255, 255, 255, 0.5) 40%, #ffffff 100%);
background-repeat: no-repeat;
}
.stage {
width: 300px;
height: 300px;
display: inline-block;
margin: 20px;
-webkit-perspective: 1200px;
-moz-perspective: 1200px;
-ms-perspective: 1200px;
-o-perspective: 1200px;
perspective: 1200px;
-webkit-perspective-origin: 50% 50%;
-moz-perspective-origin: 50% 50%;
-ms-perspective-origin: 50% 50%;
-o-perspective-origin: 50% 50%;
perspective-origin: 50% 50%;
}
#-moz-keyframes move-map {
0% {
background-position: -849px 0; }
100% {
background-position: 0 0; } }
#-webkit-keyframes move-map {
0% {
background-position: 0 0; }
100% {
background-position: -849px 0; }
}
#-o-keyframes move-map {
0% {
background-position: -849px 0; }
100% {
background-position: 0 0; } }
#-ms-keyframes move-map {
0% {
background-position: -849px 0; }
100% {
background-position: 0 0; } }
#keyframes move-map {
0% {
background-position: -849px 0; }
100% {
background-position: 0 0; } }

How to make the slider move right and left alternatively

The slider i have is moving from to left side automatically and once it reaches it moves the first slider and then it repeats.
All i wanted to do is to make the slider right to left and then to left to right alternatively.
How can i do this ?
Here is my Fiddle.
Here is the css
#slideshow {
position: relative;
width: 640px;
height: 310px;
padding: 15px;
border: 1px solid #ddd;
margin: 0 auto 2em;
background: #FFF;
background: -webkit-linear-gradient(#FFF, #FFF 20%, #EEE 80%, #DDD);
background: -moz-linear-gradient(#FFF, #FFF 20%, #EEE 80%, #DDD);
background: -ms-linear-gradient(#FFF, #FFF 20%, #EEE 80%, #DDD);
background: -o-linear-gradient(#FFF, #FFF 20%, #EEE 80%, #DDD);
background: linear-gradient(#FFF, #FFF 20%, #EEE 80%, #DDD);
-webkit-border-radius: 2px 2px 2px 2px;
-moz-border-radius: 2px 2px 2px 2px;
border-radius: 2px 2px 2px 2px;
-webkit-box-shadow: 0 0 3px rgba(0,0,0, 0.2);
-moz-box-shadow: 0 0 3px rgba(0,0,0, 0.2);
box-shadow: 0 0 3px rgba(0,0,0, 0.2);
}
As i don't have any idea in javascript i am not able to have any steps.
Your current animation keyframes:
#-webkit-keyframes slider {
0%, 20%, 100% { left: 0 }
25%, 45% { left: -100% }
50%, 70% { left: -200% }
75%, 95% { left: -300% }
}
it goes from 0 to -100% to -200% .. -300% and than back to 0.
you can change it to something like this:
#-webkit-keyframes slider {
0%, 20%, 100% { left: 0 }
25%, 45% { left: -100% }
50%, 70% { left: 0 }
75%, 95% { left: -100% }
}
here it will just got back and forth between 0 and -100%.
Show more than 2 slides:
Add classes to your slides to be able to hide and show them and created these keyframes to do so:
#-webkit-keyframes slider1 {
0%, 20%, 100% { opacity: 1; display: block; visibility: visible; }
25%, 45% { opacity: 0; display: none; visibility: hidden; }
50%, 70% { opacity: 0; display: none; visibility: hidden; }
75%, 95% { opacity: 0; display: none; visibility: hidden; }
}
#-webkit-keyframes slider2 {
0%, 20%, 100% { opacity: 0; display: none; visibility: hidden; }
25%, 45% { opacity: 1; display: block; visibility: visible; }
50%, 70% { opacity: 0; display: none; visibility: hidden; }
75%, 95% { opacity: 0; display: none; visibility: hidden; }
}
#-webkit-keyframes slider3 {
0%, 20%, 100% { opacity: 0; display: none; visibility: hidden; }
25%, 45% { opacity: 0; display: none; visibility: hidden; }
50%, 70% { opacity: 1; display: block; visibility: visible; }
75%, 95% { opacity: 0; display: none; visibility: hidden; }
}
#-webkit-keyframes slider4 {
0%, 20%, 100% { opacity: 0; display: none; visibility: hidden; }
25%, 45% { opacity: 0; display: none; visibility: hidden; }
50%, 70% { opacity: 0; display: none; visibility: hidden; }
75%, 95% { opacity: 1; display: block; visibility: visible; }
}
now you just need to position slide 3 where 1 is and 4 where 2 is, since you have a fixed width i just used position: relative; and add the animation keyframes (don't forget the other prefixes)
#slideshow .slide_1 {
-webkit-animation: slider1 32s infinite;
}
#slideshow .slide_2 {
-webkit-animation: slider2 32s infinite;
}
#slideshow .slide_3 {
position: relative;
left: -1280px;
-webkit-animation: slider3 32s infinite;
}
#slideshow .slide_4 {
position: relative;
left: -1280px;
-webkit-animation: slider4 32s infinite;
}
the finished Fiddle

Categories

Resources