Just like the above image or an idea or reference to achieve this design, I appreciate the help or suggestion given by community thank you
I have got reference of progress bar which is circular but not able find an approach to solve it.
const boxes = document.querySelectorAll(".box");
const colors = ['red', 'blue', 'green', 'yellow', 'orange', 'violet']
boxes.forEach((box) => {
const insideContent = box.innerText;
box.style.border = `6px solid ${colors[insideContent]}`
})
#app {
display: flex;
}
.box {
width: 50px;
height: 50px;
margin: 10px;
background-color: cyan;
display: flex;
justify-content: center;
align-items: center;
}
<div id="app">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
</div>
As per your question I think this is what you are trying to achieve.
First define a pseudo class root
:root {
--color-val: blue;
}
Note: In order to use the --color-val you need to write it as color: var(--color-var) in CSS
Second use JavaScript to update the variable --color-val
let colors =
var root = document.querySelector(':root');
const delay = ms => new Promise(res => setTimeout(res, ms));
const colorChange = async () => {
await delay(1000);
color = colors[Math.floor(Math.random() * colors.length)]
console.log(color)
root.style.setProperty('--color-val', color);
};
colorChange()
Note:
Add the color list you want to select from or go to CodePen for a list of 1000+ hex codes.
Promise are used for asynchronous function and can be skipped by using setTimeOut for a delayed loop or if used with another eventlistener.
I apologize if I misunderstood the question. Wrote in a hurry and without beautyful visualisation, if you disassemble the principle, you can customize it.
h1 {
display: block;
margin:0 auto;
text-align: center;
padding-top:20%;
}
.container {
display:flex;
width: 150px;
height: 150px;
border: 1px solid black;
z-index: 110;
margin:0;
margin: -10px;
}
.top {
display:block;
background-color: green;
height: 24px;
width: 150px; /* gorizontal top */
animation: top 1s linear;
animation-fill-mode: forwards;
}
#keyframes top {
0% {
width: 0px;
}
100% {
width: 150px;
}
}
.right {
background-color: green;
height: 0%;/* right */
width: 32px;
animation: right 1s linear;
animation-fill-mode: forwards;
animation-delay: 1s;
z-index: 10;
}
#keyframes right {
0% {
height: 0%;
}
100% {
height: 100%;
}
}
.box {
position: fixed;
top: 32.5px;
left: 32.5px;
width: 100px;
height: 100px;
border: 1px solid black;
margin: auto;
z-index: 120;
margin: -10px -10px;
}
.bottom {
position: absolute;
top: 123px;
left: 150px;
background-color: green;
width: 0px;
height: 27px;
z-index: 10;
animation: bottom 1s linear;
animation-fill-mode: forwards;
animation-delay: 2s;
/* animation-direction: reverse; */
}
#keyframes bottom {
0% {
transform: translate(0,0);
}
100% {
transform: translate(-250px,0);
-webkit-transform: translate(-250px,0); /** Safari & Chrome **/
-o-transform: translate(-250px,0); /** Opera **/
-moz-transform: translate(-250px,0); /** Firefox **/
width: 250px;
}
}
.left {
position: absolute;
top: 122px;
background-color: green;
width: 25px;
height: 0px;
animation: left 1s linear;
animation-fill-mode: forwards;
animation-delay: 3s;
}
#keyframes left {
0% {
transform: translate(0,0);
}
100% {
transform: translate(0,-250px);
-webkit-transform: translate(0,-250px); /** Safari & Chrome **/
-o-transform: translate(0,-250px); /** Opera **/
-moz-transform: translate(0,-250px); /** Firefox **/
height: 277px;
}
}
<div class='head'>
<div class='container'>
<div class='top'></div>
<div class='box'>
<h1 id='timer'>
1
</h1>
</div>
<div class='right'></div>
<div class='bottom'></div>
<div class='left'></div>
</div>
</div>
<script type="text/javascript">
init()
function init()
{
sec = 0;
setInterval(tick, 1000);
}
function tick()
{ if (sec<3) { sec++
document.getElementById("timer").
childNodes[0].nodeValue = sec;
} else {
clearInterval(0);
}
}
</script>
Also, instead of the SetInterval script, you can take values from your block width and height styles and output a mathematical calculation in h1 instead of a stopwatch.
upd: After your comment, I decided to do what I wrote about above. You can play with values and math, I add a snippet of another solution that changes the progress bar from the entered values within the entered range. (of course, it would be easier on react than on pure js)
function grade () {
let grade = +document.getElementById("grade").value;
let range = +document.getElementById("range").value;
document.getElementById("timer").innerHTML = `${grade}/${range}`;
progress(grade,range)
}
function progress (value, grade) {
document.getElementById('1').style.backgroundColor = `white`
document.getElementById("left").className = "noactive";
document.getElementById('top').style.width = `0%`
document.getElementById('right').style.height = `0%`
document.getElementById('bottom').style.width = `0%`
let GradeValuSide = grade/4;
if (value <= GradeValuSide) {
document.getElementById('top').style.width =
`${value/GradeValuSide*100}%`
} else if (value > GradeValuSide && value <= (GradeValuSide*2)) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height =
`${(value-GradeValuSide)/GradeValuSide*100}%`
} else if (value >= grade/2 && value < (grade/4)*3) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height = `100%`
document.getElementById('bottom').style.width =
`${((((value-(GradeValuSide*2)) / GradeValuSide) *100) / 100) *27}%`
} else if (value >= grade-(grade/4) /* && value < value + 1 */) {
document.getElementById('top').style.width = `100%`
document.getElementById('right').style.height = `100%`
document.getElementById('bottom').style.width = `100%`
document.getElementById('1').style.backgroundColor = `green`
document.getElementById("left").className = "left";
document.getElementById('left').style.height =
`${(40 - (40 * ((((value-(GradeValuSide*3)) * 100) / GradeValuSide)/ 100)))}%`
}
}
h1 {
font-size:20px;
position: absolute;
left: 40px;
display: block;
margin: 0 auto;
align-items: center;
padding-top:10%;
}
.container {
display:flex;
width: 150px;
height: 150px;
border: 1px solid black;
margin:0;
margin: -10px;
}
div.top {
display:block;
background-color: green;
height: 24px;
width: 0%; /* gorizontal top */
z-index:999;
}
div.right {
position:relative;
background-color: green;
height: 0%;/* right */
width: 32px;
z-index: 9999;
}
.box {
position: fixed;
top: 32.5px;
left: 32.5px;
background-color:white;
width: 100px;
height: 100px;
border: 1px solid black;
margin: auto;
z-index: 120;
margin: -10px -10px;
}
.wrap{
position: relative;
}
div.bottom {
position: absolute;
top: 123px;
background-color: green;
width: 0%; /* 27 = 100% */
height: 27px;
float: right;
right: 78vw;
z-index: 100;
}
div.left {
position: absolute;
background-color: white;
width: 23px;
height: 40%;
top: 23px;
bottom: 10px;
left: 0;
float: top;
}
div.noactive {
position: absolute;
background-color: white;
width: 23px;
height: 0%;
top: 23px;
bottom: 10px;
left: 0;
float: top;
}
.items {
margin-top: 50px;
text-align: center;
}
.grade,
.value {
height: 15px;
width: 50px;
align-items: center;
}
<div class='head'>
<div id='1' class='container'>
<div id='top' class='top'></div>
<div class='box'>
<h1 id='timer'>1</h1>
<div class='items'>
value<input id='grade' class='grade' type=number oninput="grade()"/>
range<input id='range' class='value' type=number oninput="grade()"/>
</div>
</div>
<div id='right' class='right'></div>
<div id='bottom' class='bottom'></div>
<div id='left' class='noactive'></div>
</div>
</div>
<script src='app.js'></script>
Is there a easy way to change color or background-color when the cursor is on the black divs, and show them in the white "cursor-area" ?
I know that it is possible if you change the black divs color and z-index on hover, but is there a way to do it through the white cursor - so that i don't have to modify every div that i want to show above the cursor.
EDIT: I made a new codepen-site. So I want the 'Hello'-text to get black when the white-cursor is over it. The black 'hello'-text should appear in the white area
// Cursor modified
var cursor = document.getElementById('cursor');
document.addEventListener('mousemove', function(e) {
e.stopPropagation();
var x = e.clientX;
var y = e.clientY;
cursor.style.left = x + 'px';
cursor.style.top = y + 'px';
});
// Cursor HOVER modified - When hovering an element
var cursor = document.getElementById('cursor');
var clickableCursor = document.getElementsByClassName('clickableCursor');
for (var i = 0; i < clickableCursor.length; i++) {
clickableCursor[i].addEventListener('mouseover', () => {
cursor.style.height = "80px";
cursor.style.width = "80px";
cursor.style.animation = "cursorAnimation 5s linear infinite";
cursor.style.background = "white";
});
clickableCursor[i].addEventListener('mouseout', () => {
cursor.style.height = "40px";
cursor.style.width = "40px";
cursor.style.animation = "none";
cursor.style.border = "2px solid white";
cursor.style.background = "none";
});
}
body {
cursor: none;
}
.container {
height: 3000px;
width: 100%;
position: relative;
background: orange;
}
#cursor {
backface-visibility: hidden;
z-index: 1000000000;
position: fixed;
width: 40px;
height: 40px;
border: 2px solid white;
transition: .1s;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
transition-duration: 100ms;
transition-timing-function: ease-out;
}
#cursor::before {
content: '';
position: absolute;
height: 7px;
width: 7px;
border-radius: 100%;
background-color: white;
}
.clickableCursor {
font-size: 50px;
color: white;
position: fixed;
background: black;
padding: 50px
}
.one {
top: 50px;
left: 50px;
}
.two {
top: 50px;
right: 50px;
}
<div class="container">
<div id="cursor"></div>
<p class="clickableCursor one"> Hello </p>
</div>
You can consider the use of mix-blend-mode with the darken value since your cursor is white. You have to adjust your code to add an extra wrapper to isolate the mix-blend-mode effect from the background.
You can also simplify your JS code and consider CSS only hover effect:
// Cursor modified
var cursor = document.getElementById('cursor');
document.addEventListener('mousemove', function(e) {
e.stopPropagation();
var x = e.clientX;
var y = e.clientY;
cursor.style.left = x + 'px';
cursor.style.top = y + 'px';
});
body {
cursor: none;
margin: 0;
}
.container {
height: 3000px;
width: 100%;
position: relative;
background: orange;
}
#cursor {
backface-visibility: hidden;
z-index: 100000;
position: fixed;
width: 40px;
height: 40px;
border: 2px solid white;
background: radial-gradient(circle 4px, #fff 98%, transparent 100%);
transition: .1s ease-out;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
mix-blend-mode: darken;
}
.clickableCursor {
position: fixed;
height: 20px;
width: 20px;
background: black;
}
.clickableCursor:hover~#cursor {
width: 80px;
height: 80px;
background: white;
}
.clickableCursor:hover {
background:blue;
}
.one {
top: 50px;
left: 50px;
}
.two {
top: 50px;
right: 50px;
}
.three {
bottom: 50px;
left: 50px;
}
.four {
bottom: 50px;
right: 50px;
}
<div class="container">
<div style="isolation:isolate">
<div class="clickableCursor one"></div>
<div class="clickableCursor two"></div>
<div class="clickableCursor three"></div>
<div class="clickableCursor four"></div>
<div id="cursor"></div>
</div>
</div>
UPDATE TO UPDATED QUESTION
replace <p> with div, put into it <div id="cursor"></div>.
Then wrap text for example with <span> and make css
.text:hover {
color: black;
z-index: 1000000001; /*higher that #cursor's*/
position: relative; /*this is neede to z-index work*/
}
Also, if you replace <span> with <div>, take away padding from .clickableCursor and put it to .text, which is now <div>, result will be better. Look up in the snippet.
// Cursor modified
var cursor = document.getElementById('cursor');
document.addEventListener('mousemove', function(e) {
e.stopPropagation();
var x = e.clientX;
var y = e.clientY;
cursor.style.left = x + 'px';
cursor.style.top = y + 'px';
});
// Cursor HOVER modified - When hovering an element
var cursor = document.getElementById('cursor');
var clickableCursor = document.getElementsByClassName('clickableCursor');
for (var i = 0; i < clickableCursor.length; i++) {
clickableCursor[i].addEventListener('mouseover', () => {
cursor.style.height = "80px";
cursor.style.width = "80px";
cursor.style.animation = "cursorAnimation 5s linear infinite";
cursor.style.background = "white";
});
clickableCursor[i].addEventListener('mouseout', () => {
cursor.style.height = "40px";
cursor.style.width = "40px";
cursor.style.animation = "none";
cursor.style.border = "2px solid white";
cursor.style.background = "none";
});
}
body {
cursor: none;
}
.container {
height: 3000px;
width: 100%;
position: relative;
background: orange;
}
#cursor {
backface-visibility: hidden;
z-index: 1000000000;
position: fixed;
width: 40px;
height: 40px;
border: 2px solid white;
transition: .1s;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
transition-duration: 100ms;
transition-timing-function: ease-out;
}
#cursor::before {
content: '';
position: absolute;
height: 7px;
width: 7px;
border-radius: 100%;
background-color: white;
}
.clickableCursor {
font-size: 50px;
color: white;
position: fixed;
background: black;
}
.one {
top: 50px;
left: 50px;
}
.two {
top: 50px;
right: 50px;
}
.text {
padding: 50px
}
.text:hover {
color: black;
z-index: 1000000001;
position: relative;
}
<div class="container">
<div class="clickableCursor one">
<div id="cursor"></div>
<div class="text">
Hello
</div>
</div>
</div>
Why not use :hover? It works fine - or did I not understand you.
// Cursor modified
var cursor = document.getElementById('cursor');
document.addEventListener('mousemove', function(e) {
e.stopPropagation();
var x = e.clientX;
var y = e.clientY;
cursor.style.left = x + 'px';
cursor.style.top = y + 'px';
});
// Cursor HOVER modified - When hovering an element
var cursor = document.getElementById('cursor');
var clickableCursor = document.getElementsByClassName('clickableCursor');
for (var i = 0; i < clickableCursor.length; i++) {
clickableCursor[i].addEventListener('mouseover', () => {
cursor.style.height = "80px";
cursor.style.width = "80px";
cursor.style.animation = "cursorAnimation 5s linear infinite";
cursor.style.background = "white";
});
clickableCursor[i].addEventListener('mouseout', () => {
cursor.style.height = "40px";
cursor.style.width = "40px";
cursor.style.animation = "none";
cursor.style.border = "2px solid white";
cursor.style.background = "none";
});
}
body {
cursor: none;
}
.container {
height: 3000px;
width: 100%;
position: relative;
background: orange;
}
#cursor {
backface-visibility: hidden;
z-index: 1000000000;
position: fixed;
width: 40px;
height: 40px;
border: 2px solid white;
transition: .1s;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
transition-duration: 100ms;
transition-timing-function: ease-out;
}
#cursor::before {
content: '';
position: absolute;
height: 7px;
width: 7px;
border-radius: 100%;
background-color: white;
}
.clickableCursor {
position: fixed;
height: 20px;
width: 20px;
background: black;
}
.clickableCursor:hover {
z-index: 1000000001;
background: red;
}
.one {
top: 50px;
left: 50px;
}
.two {
top: 50px;
right: 50px;
}
.three {
bottom: 50px;
left: 50px;
}
.four {
bottom: 50px;
right: 50px;
}
<div class="container">
<div id="cursor"></div>
<div class="clickableCursor one"></div>
<div class="clickableCursor two"></div>
<div class="clickableCursor three"></div>
<div class="clickableCursor four"></div>
</div>
I am currently building a modified cursor for my portfolio-website. Unfortunately, my cursor lags when I try to scroll and move the cursor. However, it works when I remove all the other elements from HTML, CSS, and JavaScript and ONLY have the code concerning my cursor (https://codepen.io/djaisdjasidj/pen/RwNvePZ).
// Cursor modified
var cursor = document.getElementById('cursor');
document.addEventListener('mousemove', function(e) {
e.stopPropagation();
var x = e.clientX;
var y = e.clientY;
cursor.style.left = x + 'px';
cursor.style.top = y + 'px';
});
// Cursor HOVER modified - When hovering an element
var cursor = document.getElementById('cursor');
var clickableCursor = document.getElementsByClassName('clickableCursor');
for (var i = 0; i < clickableCursor.length; i++) {
clickableCursor[i].addEventListener('mouseover', () => {
cursor.style.height = "80px";
cursor.style.width = "80px";
cursor.style.animation = "cursorAnimation 5s linear infinite";
cursor.style.background = "white";
});
clickableCursor[i].addEventListener('mouseout', () => {
cursor.style.height = "40px";
cursor.style.width = "40px";
cursor.style.animation = "none";
cursor.style.border = "2px solid white";
cursor.style.background = "none";
});
}
body {
cursor: none;
}
.container {
height: 3000px;
width: 100%;
position: relative;
background: orange;
}
#cursor {
backface-visibility: hidden;
z-index: 1000000000;
position: fixed;
width: 40px;
height: 40px;
border: 2px solid white;
transition: .1s;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
transition-duration: 100ms;
transition-timing-function: ease-out;
}
#cursor::before {
content: '';
position: absolute;
height: 7px;
width: 7px;
border-radius: 100%;
background-color: white;
}
.clickableCursor {
font-size: 50px;
color: white;
position: fixed;
background: black;
padding: 50px
}
.one {
top: 50px;
left: 50px;
}
.two {
top: 50px;
right: 50px;
}
<div class="container">
<div id="cursor"></div>
<p class="clickableCursor one"> Hello </p>
</div>
CSS for my Cursor:
#cursor {
backface-visibility: hidden;
z-index: 1000000000;
position: fixed;
width: 40px;
height: 40px;
border: 2px solid white;
transition: .1s;
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
transition-duration: 100ms;
transition-timing-function: ease-out;
}
My question is - how do I prevent this cursor 'lag' when I have a bigger HTML, CSS, and JavaScript file?
I had the same problem and i solved it with this code :
(hope it can help you or other developers)
$(window).ready(function(){
let mouseX = 0;
let mouseY = 0;
let xp = 0;
let yp = 0;
$(document).mousemove(function(e){
$(".custom__cursor__inner").css({
transform: 'translate(' + (e.clientX - 3.25) + 'px, ' + (e.clientY - 3.25) + 'px)'
});
mouseX = e.clientX - 10;
mouseY = e.clientY - 10;
});
setInterval(function(){
xp += ((mouseX - xp)/6);
yp += ((mouseY - yp)/6);
$(".custom__cursor__outer").css({transform: 'translateX('+ (xp - 15) +'px) translateY('+ (yp - 15) +'px)'} );
}, 10);
})
*{
cursor: none;
}
.custom__cursor__inner{
height: 7.5px;
width: 7.5px;
position: fixed;
transform: translate(0px, 0px);
background-color: #F7D883;
border-radius: 50%;
transition: height .3s cubic-bezier(0.46,0.03,0.52,0.96), width .3s cubic-bezier(0.46,0.03,0.52,0.96);
z-index: 5000;
pointer-events: none;
}
.custom__cursor__outer{
height: 50px;
width: 50px;
border-radius: 50%;
border: 1px solid #0F1928;
background-color: transparent;
position: fixed;
z-index: 5000;
transform: translate(0px, 0px);
pointer-events: none;
opacity: 0.4;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="custom__cursor__outer">
</div>
<div class="custom__cursor__inner">
</div>
The lag happens because you are using a transition to move the cursor to the current mouse location, explicitly stating that it should be lagging behind 100ms.
You should only apply the CSS transition on the elements and attributes that you want to animate, but not the location of the cursor.
Use the transition-property rule to define which attributes should be "transitioned" or use the transition shorthand syntax to explicitly specify the attribute names like #Tyler Roper does in his comment.
I have searched this website to find progress bars, but the ones I have been able to found show animated circles that go to the full 100%.
I would like it to stop at certain percentages like in the screenshot below. Is there any way I can do that using only CSS?
I created a fiddle using only CSS.
.wrapper {
width: 100px; /* Set the size of the progress bar */
height: 100px;
position: absolute; /* Enable clipping */
clip: rect(0px, 100px, 100px, 50px); /* Hide half of the progress bar */
}
/* Set the sizes of the elements that make up the progress bar */
.circle {
width: 80px;
height: 80px;
border: 10px solid green;
border-radius: 50px;
position: absolute;
clip: rect(0px, 50px, 100px, 0px);
}
/* Using the data attributes for the animation selectors. */
/* Base settings for all animated elements */
div[data-anim~=base] {
-webkit-animation-iteration-count: 1; /* Only run once */
-webkit-animation-fill-mode: forwards; /* Hold the last keyframe */
-webkit-animation-timing-function:linear; /* Linear animation */
}
.wrapper[data-anim~=wrapper] {
-webkit-animation-duration: 0.01s; /* Complete keyframes asap */
-webkit-animation-delay: 3s; /* Wait half of the animation */
-webkit-animation-name: close-wrapper; /* Keyframes name */
}
.circle[data-anim~=left] {
-webkit-animation-duration: 6s; /* Full animation time */
-webkit-animation-name: left-spin;
}
.circle[data-anim~=right] {
-webkit-animation-duration: 3s; /* Half animation time */
-webkit-animation-name: right-spin;
}
/* Rotate the right side of the progress bar from 0 to 180 degrees */
#-webkit-keyframes right-spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(180deg);
}
}
/* Rotate the left side of the progress bar from 0 to 360 degrees */
#-webkit-keyframes left-spin {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
/* Set the wrapper clip to auto, effectively removing the clip */
#-webkit-keyframes close-wrapper {
to {
clip: rect(auto, auto, auto, auto);
}
}
<div class="wrapper" data-anim="base wrapper">
<div class="circle" data-anim="base left"></div>
<div class="circle" data-anim="base right"></div>
</div>
Also check this fiddle here (CSS only)
#import url(http://fonts.googleapis.com/css?family=Josefin+Sans:100,300,400);
.arc1 {
width: 160px;
height: 160px;
background: #00a0db;
-webkit-transform-origin: -31% 61%;
margin-left: -30px;
margin-top: 20px;
-webkit-transform: translate(-54px,50px);
-moz-transform: translate(-54px,50px);
-o-transform: translate(-54px,50px);
}
.arc2 {
width: 160px;
height: 160px;
background: #00a0db;
-webkit-transform: skew(45deg,0deg);
-moz-transform: skew(45deg,0deg);
-o-transform: skew(45deg,0deg);
margin-left: -180px;
margin-top: -90px;
position: absolute;
-webkit-transition: all .5s linear;
-moz-transition: all .5s linear;
-o-transition: all .5s linear;
}
.arc-container:hover .arc2 {
margin-left: -50px;
-webkit-transform: skew(-20deg,0deg);
-moz-transform: skew(-20deg,0deg);
-o-transform: skew(-20deg,0deg);
}
.arc-wrapper {
width: 150px;
height: 150px;
border-radius:150px;
background: #424242;
overflow:hidden;
left: 50px;
top: 50px;
position: absolute;
}
.arc-hider {
width: 150px;
height: 150px;
border-radius: 150px;
border: 50px solid #e9e9e9;
position:absolute;
z-index:5;
box-shadow:inset 0px 0px 20px rgba(0,0,0,0.7);
}
.arc-inset {
font-family: "Josefin Sans";
font-weight: 100;
position: absolute;
font-size: 413px;
margin-top: -64px;
z-index: 5;
left: 30px;
line-height: 327px;
height: 280px;
-webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,1), rgba(0,0,0,0.2));
}
.arc-lowerInset {
font-family: "Josefin Sans";
font-weight: 100;
position: absolute;
font-size: 413px;
margin-top: -64px;
z-index: 5;
left: 30px;
line-height: 327px;
height: 280px;
color: white;
-webkit-mask-image: -webkit-linear-gradient(top, rgba(0,0,0,0.2), rgba(0,0,0,1));
}
.arc-overlay {
width: 100px;
height: 100px;
background-image: linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -o-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -moz-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(217,217,217) 10%, rgb(245,245,245) 90%, rgb(253,253,253) 100%);
padding-left: 32px;
box-sizing: border-box;
-moz-box-sizing: border-box;
line-height: 100px;
font-family: sans-serif;
font-weight: 400;
text-shadow: 0 1px 0 #fff;
font-size: 22px;
border-radius: 100px;
position: absolute;
z-index: 5;
top: 75px;
left: 75px;
box-shadow:0px 0px 20px rgba(0,0,0,0.7);
}
.arc-container {
position: relative;
background: #e9e9e9;
height: 250px;
width: 250px;
}
<div class="arc-container">
<div class="arc-hider"></div>
<div class="arc-inset">
o
</div>
<div class="arc-lowerInset">
o
</div>
<div class="arc-overlay">
35%
</div>
<div class="arc-wrapper">
<div class="arc2"></div>
<div class="arc1"></div>
</div>
</div>
Or this beautiful round progress bar with HTML5, CSS3 and JavaScript.
What about that?
HTML
<div class="chart" id="graph" data-percent="88"></div>
Javascript
var el = document.getElementById('graph'); // get canvas
var options = {
percent: el.getAttribute('data-percent') || 25,
size: el.getAttribute('data-size') || 220,
lineWidth: el.getAttribute('data-line') || 15,
rotate: el.getAttribute('data-rotate') || 0
}
var canvas = document.createElement('canvas');
var span = document.createElement('span');
span.textContent = options.percent + '%';
if (typeof(G_vmlCanvasManager) !== 'undefined') {
G_vmlCanvasManager.initElement(canvas);
}
var ctx = canvas.getContext('2d');
canvas.width = canvas.height = options.size;
el.appendChild(span);
el.appendChild(canvas);
ctx.translate(options.size / 2, options.size / 2); // change center
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg
//imd = ctx.getImageData(0, 0, 240, 240);
var radius = (options.size - options.lineWidth) / 2;
var drawCircle = function(color, lineWidth, percent) {
percent = Math.min(Math.max(0, percent || 1), 1);
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
ctx.strokeStyle = color;
ctx.lineCap = 'round'; // butt, round or square
ctx.lineWidth = lineWidth
ctx.stroke();
};
drawCircle('#efefef', options.lineWidth, 100 / 100);
drawCircle('#555555', options.lineWidth, options.percent / 100);
and CSS
div {
position:relative;
margin:80px;
width:220px; height:220px;
}
canvas {
display: block;
position:absolute;
top:0;
left:0;
}
span {
color:#555;
display:block;
line-height:220px;
text-align:center;
width:220px;
font-family:sans-serif;
font-size:40px;
font-weight:100;
margin-left:5px;
}
http://jsfiddle.net/Aapn8/3410/
Basic code was taken from Simple PIE Chart http://rendro.github.io/easy-pie-chart/
Check this out :)
I made this one using conic-gradient.
background: conic-gradient(
SomeColor1 80%,
SomeColor2 80%
);
You can create a pie chart using conic-gradient.
div {
background: conic-gradient(
red 36deg, orange 36deg 170deg, yellow 170deg);
border-radius: 50%
}
I select only two colors for the pie chart.
background: conic-gradient(
rgb(3, 133, 255) 80%,
rgb(242, 242, 242) 80%
);
then place a div on top of the pie chart to make it looks like a circular progress indicator. Then set progress using HTML DOM innerHTML option.
Then you can use incrementProgress() and decrementProgress() fuctions to change progress dynamically.
Follow my complete example to get some idea :)
You can make upload/download progress indicators, charts for dashboards, etc. using this.
<html>
<head>
<style>
body {
display: flex;
align-items: center;
justify-content: center;
}
#progress-spinner {
border-radius: 50%;
height: 100px;
width: 100px;
}
#middle-circle {
position: absolute;
border-radius: 50%;
height: 80px;
width: 80px;
background-color: rgb(248, 248, 248);
display: flex;
align-items: center;
justify-content: center;
font-size: large;
font-weight: bold;
}
</style>
</head>
<body>
<div
style="
position: relative;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
"
>
<div
style="
position: relative;
display: flex;
justify-content: center;
align-items: center;
"
>
<div id="middle-circle"></div>
<div id="progress-spinner"></div>
</div>
<div style="margin-top: 30px">
<button type="button" id="incbtn">+</button>
<button type="button" id="decbtn">-</button>
</div>
</div>
<script>
var progress = 0;
document
.getElementById("incbtn")
.addEventListener("click", incrementProgress);
document
.getElementById("decbtn")
.addEventListener("click", decrementProgress);
function incrementProgress() {
if (progress != 100) {
progress = progress + 10;
console.log(progress);
setProgress();
}
}
function decrementProgress() {
if (progress != 0) {
progress = progress - 10;
console.log(progress);
setProgress();
}
}
function setProgress() {
document.getElementById("progress-spinner").style.background =
"conic-gradient(rgb(3, 133, 255) " +
progress +
"%,rgb(242, 242, 242) " +
progress +
"%)";
document.getElementById("middle-circle").innerHTML =
progress.toString() + "%";
}
window.onload = function () {
setProgress();
};
</script>
</body>
</html>
Another pure css based solution that is based on two clipped rounded elements that i rotate to get to the right angle:
http://jsfiddle.net/maayan/byT76/
That's the basic css that enables it:
.clip1 {
position:absolute;
top:0;left:0;
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
}
.slice1 {
position:absolute;
width:200px;
height:200px;
clip:rect(0px,100px,200px,0px);
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
background-color:#f7e5e1;
border-color:#f7e5e1;
-moz-transform:rotate(0);
-webkit-transform:rotate(0);
-o-transform:rotate(0);
transform:rotate(0);
}
.clip2
{
position:absolute;
top:0;left:0;
width:200px;
height:200px;
clip:rect(0,100px,200px,0px);
}
.slice2
{
position:absolute;
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
background-color:#f7e5e1;
border-color:#f7e5e1;
-moz-transform:rotate(0);
-webkit-transform:rotate(0);
-o-transform:rotate(0);
transform:rotate(0);
}
and the js rotates it as required.
quite easy to understand..
Hope it helps,
Maayan
A minimalistic approach using just one element and a couple of attributes:
Use data-progress to define the internal label and --progress to define the progress from 0deg to 360deg.
<div data-progress="36" style="--progress: 36deg;">36%</div>
div {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
background: conic-gradient(red var(--progress), gray 0deg);
font-size: 0;
}
div::after {
content: attr(data-progress) '%';
display: flex;
justify-content: center;
flex-direction: column;
width: 100%;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
<div data-progress="36" style="--progress: 36deg;">36%</div>
Here's a naïve approach to the animation, again all CSS, no JS and just one element:
div {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
background: conic-gradient(red var(--progress), gray 0deg);
font-size: 0;
animation: .4s ease-out turn_in reverse;
}
div::after {
content: attr(data-progress);
display: flex;
justify-content: center;
flex-direction: column;
width: 100%;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
#keyframes turn_in {
5% {
background: conic-gradient(red calc(var(--progress) * .95), gray 0deg);
}
10% {
background: conic-gradient(red calc(var(--progress) * .9), gray 0deg);
}
15% {
background: conic-gradient(red calc(var(--progress) * .85), gray 0deg);
}
20% {
background: conic-gradient(red calc(var(--progress) * .8), gray 0deg);
}
25% {
background: conic-gradient(red calc(var(--progress) * .75), gray 0deg);
}
30% {
background: conic-gradient(red calc(var(--progress) * .7), gray 0deg);
}
35% {
background: conic-gradient(red calc(var(--progress) * .65), gray 0deg);
}
40% {
background: conic-gradient(red calc(var(--progress) * .6), gray 0deg);
}
45% {
background: conic-gradient(red calc(var(--progress) * .55), gray 0deg);
}
50% {
background: conic-gradient(red calc(var(--progress) * .5), gray 0deg);
}
55% {
background: conic-gradient(red calc(var(--progress) * .45), gray 0deg);
}
60% {
background: conic-gradient(red calc(var(--progress) * .4), gray 0deg);
}
65% {
background: conic-gradient(red calc(var(--progress) * .35), gray 0deg);
}
70% {
background: conic-gradient(red calc(var(--progress) * 0.3), gray 0deg);
}
75% {
background: conic-gradient(red calc(var(--progress) * 0.25), gray 0deg);
}
80% {
background: conic-gradient(red calc(var(--progress) * .2), gray 0deg);
}
85% {
background: conic-gradient(red calc(var(--progress) * .15), gray 0deg);
}
90% {
background: conic-gradient(red calc(var(--progress) * .1), gray 0deg);
}
95% {
background: conic-gradient(red calc(var(--progress) * .05), gray 0deg);
}
100% {
background: conic-gradient(gray 0deg);
}
}
<div data-progress="85%" style="--progress: 85%;">85%</div>
Disclaimer: cross-browsing not tested.
A different idea with new #property. See the support table
#property --a {
syntax: '<angle>';
inherits: false;
initial-value: 90deg;
}
.circle {
width: 120px;
height: 120px;
padding: 12px;
box-sizing: border-box;
-webkit-mask:
conic-gradient(#000 var(--a), transparent var(--a)),
linear-gradient(#000, #000) content-box;
-webkit-mask-composite: source-out;
mask-composite: subtract;
background: tomato;
border-radius: 50%;
animation: progress 1s .3s linear forwards;
}
#keyframes progress {
to {
--a: 250deg;
}
}
<div class="circle"></div>
And I saw a more powerful example by Alvaro Montoro. Be sure to check this out.
acceding your data you can change process like <div ... data-num="50"> output 50% that go to the show fully animated circles and number.
change in data-num="/* 0-100 */".
you can add multiple process like 5,10.
using Javascript,CSS,Html with animated circle and number.
Output
Code
let items = document.querySelectorAll('.progress-item');
const counters = Array(items.length);
const intervals = Array(items.length);
counters.fill(0);
items.forEach((number,index) => {
intervals[index] = setInterval(() => {
if(counters[index] == parseInt(number.dataset.num)){
clearInterval(intervals[index]);
}else{
counters[index] += 1;
number.style.background = "conic-gradient(red calc(" + counters[index] + "%), gray 0deg)";
number.setAttribute('data-value', counters[index] + "%");
number.innerHTML = counters[index] + "%";
}
}, 15);
});
#progress{
display: flex;
justify-content: space-around;
}
.progress-item {
display: flex;
width: 100px;
height: 100px;
border-radius: 50%;
font-size: 0;
animation: .4s ease-out reverse;
}
.progress-item::after {
content: attr(data-value);
display: flex;
justify-content: center;
flex-direction: column;
width: 100px;
margin: 10px;
border-radius: 50%;
background: white;
font-size: 1rem;
text-align: center;
}
<div id="progress" >
<div data-num="40" class="progress-item">sd</div>
<div data-num="80" class="progress-item">sd</div>
<div data-num="57" class="progress-item">sd</div>
<div data-num="83" class="progress-item">sd</div>
<div data-num="90" class="progress-item">ds</div>
</div>
Flexible SVG solution for radial progress-bar (CSS only): the solution in calculating(via calc) border length of circle inside SVG.
Progress-circle in samples is overlay on element, and may be transparent.
jQuery(function($){
setTimeout(() => $('#element1 [data-role="radial-progress"]').css('--progress-percent', '100'), 1000);
$('#element2 [data-role="radial-progress"]').css('--progress-percent', '80');
$('#element3 [data-role="radial-progress"]').css('--progress-percent', '100');
let progress4 = 0;
let progress4incrementor = setInterval(() => {
progress4++;
$('#element4 .value').html(progress4 + '%');
$('#element4 [data-role="radial-progress"]').css('--progress-percent', progress4.toString());
if (progress4 >= 100) clearInterval(progress4incrementor);
}, 100);
});
.element
{
position: relative;
}
[data-role="radial-progress"]
{
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
--progress-percent: 0;
--progress-color: #CC000077;
--progress-bar-width: 100%;
}
[data-role="radial-progress"] > circle
{
stroke-width: var(--progress-bar-width);
stroke-dasharray: calc(100% * 3.141592);
stroke-dashoffset: calc(100% * (100 - var(--progress-percent))/100 * 3.141592);
stroke: var(--progress-color);
}
/*Just for animate --data-percent */
#element1 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 4s linear;
}
#element2 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 2s linear;
}
#element3 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 6s linear;
}
#element4 [data-role="radial-progress"] > circle
{
transition: stroke-dashoffset 0.1s linear;
}
/*Сode that does not depend on radial-progress*/
.element
{
background-image: url(https://static.wikia.nocookie.net/dune/images/2/2f/Duneii-wind-trap.jpg/revision/latest);
background-size: 100% 100%;
display: inline-block;
width: 180px;
height: 110px;
border: 2px solid red;
text-align: center;
color: red;
}
#element3
{
width: 110px;
}
#element3 [data-role="radial-progress"]
{
transform: rotate(-90deg);
}
#element4
{
display: inline-flex;
align-items: center;
justify-content: center;
}
#element4 .value
{
font-size: 2em;
font-weight: bold;
z-index: 2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="element1" class="element">
Content
<svg data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>
<div id="element2" class="element">
Content
<svg style="--progress-percent:30" data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>
<div id="element3" class="element">
Content
<svg style="--progress-bar-width:10px;--progress-color:red;" data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="44%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>
<div id="element4" class="element">
<span class="value">0%</span>
<svg data-role="radial-progress" width="100%" height="100%" viewPort="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg"><circle r="50%" cx="50%" cy="50%" fill="transparent"></circle></svg>
</div>