Reputation: 73
how can I create a circle progress bar that expands in both clockwise + non clockwise direction from the starting point?
here is my progress so far: https://jsfiddle.net/qchygknu/
HTML:
<div class="wheel circle-menu is-draggable-horizontal">
<div class="wheel__list circle-menu__circle" style="transform: rotate(1deg);">
<div class="wheel__list__item circle-menu__circle__item position--top-right" style="transform: rotate(60deg);">
<a href="#">
<div class="circle-menu__circle__item__inner" style="transform: rotate(-61deg);">
</div>
</a>
</div>
<div class="wheel__list__item circle-menu__circle__item position--bottom" style="transform: rotate(180deg);">
<a href="#">
<div class="circle-menu__circle__item__inner" style="transform: rotate(-181deg);">
</div>
</a>
</div>
<div class="wheel__list__item circle-menu__circle__item position--top-left" style="transform: rotate(300deg);">
<a href="#">
<div class="circle-menu__circle__item__inner" style="transform: rotate(-301deg);">
</div>
</a>
</div>
<svg class="circle-menu__circle__svg" viewBox="0 0 100 100">
<text id="myTimer" text-anchor="middle" x="100" y="110" style="font-size: 36px;" >0%</text>
<circle id="svg-circle-1" class="circle-menu__circle__svg__circle_1" cx="50" cy="50" r="50" transform="rotate(-90 50 50)"></circle>
<circle id="svg-circle-2" class="circle-menu__circle__svg__circle_2" cx="50" cy="50" r="50" transform="rotate(-90 50 50)"></circle>
<circle class="circle-menu__circle__svg__line" cx="50" cy="50" r="50" transform="rotate(-90 50 50)"></circle>
</svg>
</div>
</div>
CSS:
.circle-menu__circle {
list-style: none;
padding: 0;
margin: 0 auto;
position: relative;
width: 400px;
height: 400px;
}
.circle-menu__circle__item {
width: 0;
height: 100%;
position: absolute;
margin: 0 50%;
cursor: auto;
}
.circle-menu__circle__item__inner {
position: absolute;
left: 50%;
bottom: 98%;
margin-left: -5px;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #333;
}
.circle-menu__circle__svg {
height: 100%;
overflow: visible;
}
.circle-menu__circle__svg__circle_1 {
fill: transparent;
stroke: #333;
stroke-width: 0.5px;
}
.circle-menu__circle__svg__circle_2 {
fill: transparent;
stroke: #333;
stroke-width: 4px;
}
.circle-menu__circle__svg__line {
fill: transparent;
stroke: black;
stroke-width: 0.5px;
stroke-dasharray: 315;
stroke-dashoffset: 315;
-webkit-transition: stroke-dashoffset 1s;
transition: stroke-dashoffset 1s;
}
Javascript:
(function () {
// math trick 2*pi*57 = 358, must be less than 360 degree
var circle = document.getElementById('svg-circle-2');
var myTimer = document.getElementById('myTimer');
var interval = 30;
var angle = 0;
var angle_increment = 6;
window.timer = window.setInterval(function () {
circle.setAttribute("stroke-dashoffset", 45 );
circle.setAttribute("stroke-dasharray", angle + ", 20000");
myTimer.innerHTML = angle;
if (angle >= 90) {
window.clearInterval(window.timer);
}
angle += angle_increment;
}.bind(this), interval);
})()
I have tried using svg
to draw the circle and using stroke-dasharray
and stroke-dashoffset
but I cannot set the starting point and it can only expand in 1 direction, I need the progress bar to expand on both direction when the dot is clicked
Example - Step 1
Example - Step 2
Example - Step 3
Example - Step 4
Upvotes: 0
Views: 1816
Reputation: 101810
You can achieve the effect you want with pure CSS.
.circle-menu__circle {
display: block;
margin: 0 auto;
width: 400px;
height: 400px;
}
.circle-menu__circle__svg__circle_1 {
fill: transparent;
stroke: #999;
stroke-width: 0.5px;
}
.circle-menu__circle__item {
fill: transparent;
stroke: #333;
stroke-width: 4px;
stroke-linecap: round;
stroke-dasharray: 0px 314.2px;
stroke-dashoffset: 157.5px;
transition: all 1s;
pointer-events: visibleStroke;
}
.position--top-right {
transform: rotate(150deg);
}
.position--bottom {
transform: rotate(-90deg);
}
.position--top-left {
transform: rotate(30deg);
}
.circle-menu__circle__item:hover {
stroke-dasharray: 100px 214.2px;
stroke-dashoffset: 207.5px;
}
<div class="wheel circle-menu is-draggable-horizontal">
<svg class="wheel__list circle-menu__circle" viewBox="-52 -52 104 104">
<circle id="svg-circle-1" class="circle-menu__circle__svg__circle_1" cx="0" cy="0" r="50"></circle>
<circle cx="0" cy="0" r="50" class="circle-menu__circle__item position--top-right"/>
<circle cx="0" cy="0" r="50" class="circle-menu__circle__item position--bottom"/>
<circle cx="0" cy="0" r="50" class="circle-menu__circle__item position--top-left"/>
</svg>
</div>
Upvotes: 1
Reputation: 1530
This can be helpful
(function () {
// math trick 2*pi*57 = 358, must be less than 360 degree
var circle = document.getElementById('svg-circle-2');
var myTimer = document.getElementById('myTimer');
var interval = 30;
var angle = 0;
var angle_increment = 6;
var pointLocation = -30; // -30, 90, 210
var arc = 120;
window.timer = window.setInterval(function () {
circle.setAttribute("stroke-dasharray", (angle) + ", 20000");
circle.setAttribute("transform", "rotate("+ (pointLocation -angle/1.8) +" 50 50)");
myTimer.innerHTML = angle;
if (angle >= arc) {
window.clearInterval(window.timer);
}
angle += angle_increment;
}.bind(this), interval);
})()
.circle-menu__circle {
list-style: none;
padding: 0;
margin: 0 auto;
position: relative;
width: 400px;
height: 400px;
}
.circle-menu__circle__item {
width: 0;
height: 100%;
position: absolute;
margin: 0 50%;
cursor: auto;
}
.circle-menu__circle__item__inner {
position: absolute;
left: 50%;
bottom: 98%;
margin-left: -5px;
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #333;
}
.circle-menu__circle__svg {
height: 100%;
overflow: visible;
}
.circle-menu__circle__svg__circle_1 {
fill: transparent;
stroke: #333;
stroke-width: 0.5px;
}
.circle-menu__circle__svg__circle_2 {
fill: transparent;
stroke: #333;
stroke-width: 4px;
}
.circle-menu__circle__svg__line {
fill: transparent;
stroke: black;
stroke-width: 0.5px;
stroke-dasharray: 315;
stroke-dashoffset: 315;
-webkit-transition: stroke-dashoffset 1s;
transition: stroke-dashoffset 1s;
}
<div class="wheel circle-menu is-draggable-horizontal">
<div class="wheel__list circle-menu__circle" style="transform: rotate(1deg);">
<div class="wheel__list__item circle-menu__circle__item position--top-right" style="transform: rotate(60deg);">
<a href="#">
<div class="circle-menu__circle__item__inner" style="transform: rotate(-61deg);">
</div>
</a>
</div>
<div class="wheel__list__item circle-menu__circle__item position--bottom" style="transform: rotate(180deg);">
<a href="#">
<div class="circle-menu__circle__item__inner" style="transform: rotate(-181deg);">
</div>
</a>
</div>
<div class="wheel__list__item circle-menu__circle__item position--top-left" style="transform: rotate(300deg);">
<a href="#">
<div class="circle-menu__circle__item__inner" style="transform: rotate(-301deg);">
</div>
</a>
</div>
<svg class="circle-menu__circle__svg" viewBox="0 0 100 100">
<text id="myTimer" text-anchor="middle" x="100" y="110" style="font-size: 36px;" >0%</text>
<circle id="svg-circle-1" class="circle-menu__circle__svg__circle_1" cx="50" cy="50" r="50" transform="rotate(-90 50 50)"></circle>
<circle id="svg-circle-2" class="circle-menu__circle__svg__circle_2" cx="50" cy="50" r="50" ></circle>
<circle class="circle-menu__circle__svg__line" cx="50" cy="50" r="50" transform="rotate(-90 50 50)"></circle>
</svg>
</div>
</div>
Upvotes: 0