I need to increase circle height and width to double. But it's not working. Please suggest me where I put the error in the code. I have no idea about the value of r. Please help me to update the value of r.
Here is my sample code.
var time = 10;
var initialOffset = '440';
var i = 1
var r = $(".circle_animation").attr("r");
var interval = setInterval(function() {
$('.circle_animation').css(
'stroke-dashoffset',
initialOffset - (i * (initialOffset / time) * (r / 69.85699))
);
$('h2').text(i);
if (i == time) {
clearInterval(interval);
}
i++;
}, 1000);
.item {
position: relative;
float: left;
}
.item h2 {
text-align: center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440;
/* this value is the pixel circumference of the circle */
stroke-dashoffset: 440;
transition: all 1s linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item html">
<h2>0</h2>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/>
</g>
</svg>
</div>
As you guessed, you have to change the value of r to change the radius.
If we look at the javascript code:
var r = $(".circle_animation").attr("r");
It means that r is the value of the html attribute r of the element with class name circle_animation.
If we then look at the html markup:
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/>
we see that r is set to 69.85699 on the circle with class name circle_animation
After that you have to remember that since your drawing a larger circle, you will also have to double both the size of the svg and the stroke-dasharray and stroke-dashoffset (these values are supposed to be 2*2*PI*r for this animation).
Here is your example with doubled radius as you requested:
var time = 10;
var initialOffset = '440';
var i = 1
var r = $(".circle_animation").attr("r");
var interval = setInterval(function() {
$('.circle_animation').css(
'stroke-dashoffset',
initialOffset-(i*(initialOffset/time)*(r/139.71398))
);
$('h2').text(i);
if (i == time) {
clearInterval(interval);
}
i++;
}, 1000);
.item {
position: relative;
float: left;
}
.item h2 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
margin-top: 60px;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 878; /* this value is the pixel circumference of the circle */
stroke-dashoffset: 878;
transition: all 1s linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item html">
<h2>0</h2>
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle_animation" r="139.71398" cy="162" cx="162" stroke-width="8" stroke="#6fdb6f" fill="none"/>
your radius is 69.85699 on the circle. lets consider 70 for simplicity.
double will be 140, circumference of this circle would be 880
now your cx and cy should also consider the offset/width of the stroke.
so, 140 + (8/2)
most other calculations are simple as you have already done them.
var time = 10;
var initialOffset = '880';
var i = 1
var r = $(".circle_animation").attr("r");
var interval = setInterval(function() {
$('.circle_animation').css(
'stroke-dashoffset',
initialOffset-(i*(initialOffset/time)*(r/140))
);
$('h2').text(i);
if (i == time) {
clearInterval(interval);
}
i++;
}, 1000);
.item {
position: relative;
float: left;
}
.item h2 {
text-align: center;
position: absolute;
line-height: 265px;
width: 100%;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 880; /* this value is the pixel circumference of the circle */
stroke-dashoffset: 880;
transition: all 1s linear;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item html">
<h2>0</h2>
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle_animation" r="140" cy="144" cx="144" stroke-width="8" stroke="#6fdb6f" fill="none"/>
</g>
</svg>
</div>
You need this, Check this fiddle and code https://jsfiddle.net/rmcej7vk/
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item html">
<h2>0</h2>
<svg width="320" height="320" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle_animation" r="139.7139" cy="162" cx="162" stroke-width="8" stroke="#6fdb6f" fill="none"/>
</g>
</svg>
</div>
JS
var time = 10;
var initialOffset = '880';
var i = 1
var r = $(".circle_animation").attr("r");
var interval = setInterval(function() {
$('.circle_animation').css(
'stroke-dashoffset',
initialOffset - (i * (initialOffset / time) * (r / 139.7139))
);
$('h2').text(i);
if (i == time) {
clearInterval(interval);
}
i++;
}, 1000);
CSS
.item {
position: relative;
float: left;
}
.item h2 {
text-align: center;
position: absolute;
line-height: 250px;
width: 100%;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 880;
/* this value is the pixel circumference of the circle */
stroke-dashoffset: 880;
transition: all 1s linear;
}
Related
i am going to do some circular charts and now i have full circle with progress bar but dont know why i cannot make it 3/4circle and progress bar.
code:
<!-- The HTML structure for the progress bar -->
<div class="progress-container">
<svg class="progress-bar" width="100%" height="100%" viewBox="0 0 42 42">
<circle class="progress-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent"/>
<circle class="progress-value" cx="21" cy="21" r="15.91549430918954" fill="transparent"/>
</svg>
<div class="progress-text">0%</div>
</div>
/* The CSS styles for the progress bar */
.progress-container {
position: relative;
width: 200px;
height: 200px;
}
.progress-bar {
position: absolute;
top: 0;
left: 0;
}
.progress-ring {
stroke: #ddd;
stroke-width: 2;
fill: transparent;
}
.progress-value {
stroke: #3498db;
stroke-width: 2;
fill: transparent;
stroke-dasharray: 0 100;
transition: stroke-dasharray 0.3s;
}
.progress-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 18px;
font-weight: bold;
text-align: center;
color: #3498db;
}
// The JavaScript code to update the progress bar
const progressContainer = document.querySelector('.progress-container');
const progressBar = progressContainer.querySelector('.progress-bar');
const progressValue = progressBar.querySelector('.progress-value');
const progressText = progressContainer.querySelector('.progress-text');
const updateProgress = (value) => {
// Update the value of the progress bar
progressValue.style.strokeDasharray = `${value} 100`;
// Update the text inside the progress bar
progressText.textContent = `${value}%`;
}
updateProgress(50); // Set the progress bar to 50%
This is how it looks like:
but i want it to looks some similar to:
If someone know how to rebuild my code, please help me out.
You would need to draw the 3/4 arc segment with svg path,
<svg class="progress-bar" width="100%" height="100%" viewBox="0 0 42 42">
<!--
<circle class="progress-ring" cx="21" cy="21" r="15.91549430918954" fill="transparent"/>
<circle class="progress-value" cx="21" cy="21" r="15.91549430918954" fill="transparent"/>
-->
<path class="progress-ring" d="M21 21 m-11.254 11.254 a 15.91549430918954 15.91549430918954 135 1 1 22.508 0" fill="transparent" stroke-linecap="round"/>
<path class="progress-value" d="M21 21 m-11.254 11.254 a 15.91549430918954 15.91549430918954 135 1 1 22.508 0" fill="transparent" stroke-linecap="round"/>
</svg>
and adjust the length accordingly.
//progressValue.style.strokeDasharray = `${value} 100`;
progressValue.style.strokeDasharray = `${value * 3 / 4} 75`;
I am trying to style a circle showing the progress percent as the circumference. I want to get the radius in JS but style the circle in CSS.
The function I use to do this is setPercent. It reads the radius of the circle by selecting the radius element and getting the radius measures from there.
This is the code that works:
const fn = function() {
let circle = document.querySelector('circle.percent')
debugger
let radius = circle.r.baseVal.value
let circumference = 2 * Math.PI * radius
circle.style.strokeDasharray = `${circumference} ${circumference}`
this.setPercent = function(percent) {
circle.style.strokeDashoffset = (100 - percent) / 100 * circumference
}
}
setTimeout(fn, 1)
:root {
--back-ground: #30384a;
--neutral-circle-border: #656c79;
--completed-color: #67ed8b;
background: var(--back-ground)
}
div.normal_square {
width: 100px;
height: 100px;
}
svg.progress-ring {
margin: 0 auto;
display: block;
}
svg.progress-ring circle {
fill: transparent;
stroke-width: 2;
stroke: black;
cx: 50%;
cy: 50%;
r: 40%;
}
svg.progress-ring circle.percent {
transition: all 0.5s ease-out;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
svg.progress-ring circle.background {
stroke: var(--neutral-circle-border)
}
<div margin="0 auto">
<svg class="progress-ring" width="200px" height="200px" xmlns="http://www.w3.org/2000/svg">
<circle class="background"/>
<circle class="percent" fill="transparent" stroke-width="6" stroke="black" cx="50%" cy="50%" r="40%" />
</svg>
</div>
However, when I remove that r="40%" from my code, I can't get the radius measured from circle.r.... Why does it happen and how can I fix it?
Use window.getComputedStyle(element) to retrieve the value instead.
Currently you're retrieving the property value from the element reference, when you remove the property there's nothing left to retrieve.
Just ran into the same problem. This worked:
let radius = circle.getBoundingClientRect().width / 2;
Seems silly to have to do this though. Hopefully someone posts a better way.
Circle outline completes before timer finish. Although it is working fine when with the larger circle. fiddle
var time = 10;
var initialOffset = '440';
var i = 1
/* Need initial run as interval hasn't yet occured... */
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
var interval = setInterval(function() {
$('h2').text(i);
if (i == time) {
clearInterval(interval);
return;
}
$('.circle_animation').css('stroke-dashoffset', initialOffset-((i+1)*(initialOffset/time)));
i++;
}, 1000);
svg {
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440;
stroke-dashoffset: 440;
transition: all 1s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item html">
<h2>0</h2>
<svg width="70" height="70" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle_animation" r="25" cy="35" cx="35" stroke-width="4" stroke="#6fdb6f" fill="#ccc"/>
</g>
</svg>
</div>
You have to reduce the offset, both in css and javascript, i updated your code there :
http://jsfiddle.net/3recj0s9/
CSS :
.circle_animation {
stroke-dasharray: 155;
stroke-dashoffset: 155;
transition: all 1s linear;
}
JS
var initialOffset = '155';
I have made an example countdown using svg but i need a clock face which would be just a dark circle which is being filled with the colour of the countdown which i made.
Here is the code i got:
var time = 1800;
var initialOffset = '440';
var i = 1
/* Need initial run as interval hasn't yet occured... */
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
var interval = setInterval(function() {
$('h3').text(secondsToTime(1800-i).m.toString()+" min " +secondsToTime(1800-i).s.toString()+" sek");
if (i == time) {
clearInterval(interval);
return;
}
$('.circle_animation').css('stroke-dashoffset', initialOffset-((i+1)*(initialOffset/time)));
i++;
}, 1000);
function secondsToTime(secs)
{
var hours = Math.floor(secs / (60 * 60));
var divisor_for_minutes = secs % (60 * 60);
var minutes = Math.floor(divisor_for_minutes / 60);
var divisor_for_seconds = divisor_for_minutes % 60;
var seconds = Math.ceil(divisor_for_seconds);
var obj = {
"m": minutes,
"s": seconds
};
return obj;
}
.item {
position: relative;
float: left;
}
.item h3 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440; /* this value is the pixel circumference of the circle */
stroke-dashoffset: 440;
transition: all 1s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item html">
<h3>0</h3>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="15" stroke="blue" fill="none"/>
</g>
</svg>
</div>
This is the result i am looking for (dark clock face) and countdown filling it out:
One of my tries to accomplish what i want was adding a new css class named "circle" but it does not seem to show up when i add it to <circle id="circle" class="circle circle_animation" r="69.85699" cy="81" cx="81" stroke-width="15" stroke="blue" fill="none"/>.
var time = 1800;
var initialOffset = '440';
var i = 1
/* Need initial run as interval hasn't yet occured... */
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
var interval = setInterval(function() {
$('h3').text(secondsToTime(1800-i).m.toString()+" min " +secondsToTime(1800-i).s.toString()+" sek");
if (i == time) {
clearInterval(interval);
return;
}
$('.circle_animation').css('stroke-dashoffset', initialOffset-((i+1)*(initialOffset/time)));
i++;
}, 1000);
function secondsToTime(secs)
{
var hours = Math.floor(secs / (60 * 60));
var divisor_for_minutes = secs % (60 * 60);
var minutes = Math.floor(divisor_for_minutes / 60);
var divisor_for_seconds = divisor_for_minutes % 60;
var seconds = Math.ceil(divisor_for_seconds);
var obj = {
"m": minutes,
"s": seconds
};
return obj;
}
.item {
position: relative;
float: left;
}
.item h3 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.circle {
border: 15px solid #03002e;
height: 125px;
border-radius:50%;
width: 125px;
}
.circle_animation {
stroke-dasharray: 440; /* this value is the pixel circumference of the circle */
stroke-dashoffset: 440;
transition: all 1s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="item html">
<h3>30 min 00 sek</h3>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<g>
<title>Layer 1</title>
<circle id="circle" class="circle circle_animation" r="69.85699" cy="81" cx="81" stroke-width="15" stroke="blue" fill="none"/>
</g>
</svg>
</div>
Just add another circle to your svg area before the current circle and make sure it doesn't have the same class the one you are animating. <circle id="circle" r="69.85699" cy="81" cx="81" stroke-width="15" stroke="#1F2837" fill="none"/>
You can see a demo on jsbin
I have an SVG with two circles that are animated using #keyframes. I want to display the value of the circle's growth. Using javascript I want to display the value as they shrink and grow. getTotalLength() is probably not what I should be using but am not sure of the name of what I am looking for that does size/value check.
My codepen
an example of how it would look
// console.log("DOM Ready!");
// // setInterval, changes global var, translates the size of the val.
// // ever second or two
// // point 0.1 means 10px
// // displaying each circle's value as they grow and shrink
// var redValue = document.getElementById('red-grow').innerHTML = span;
// // var greenValue = document.getElementById('green-grow').innerHTML =
// var redCircle = document.getElementsByClassName('red');
// var greenCircle = document.getElementsByClassName('green');
// var current = 0;
// var width = 0;
// var destination = 700;
// var friction = 0.04;
// // scaling up both circles
// function scaleUp() {
// // console.log(scaleUp);
// current += (destination - current) * friction;
// redCircle[0].style.width = (current * 0.5 + 'px');
// greenCircle[0].style.width = (current * 0.5 + 'px');
// if (current >= destination - 0.1) {
// // clearInterval(redAnimate);
// }
// }
// var redAnimate = setInterval(scaleUp, 20);
// // scaling down both circles
// function scaleDown() {
// //console.log(redCircle[0].style, greenCircle[0].style);
// current += (destination - current) * friction;
// redCircle[0].style.width = (current * 0.5 + 'px');
// greenCircle[0].style.width = (current * 0.5 + 'px');
// if (current >= destination - 0.1) {
// // clearInterval(greenAnimate);
// }
// }
// var greenAnimate = setInterval(scaleDown, 20);
body {
background-color: #584E56;
}
h1 {
color: #fff;
text-align: center;
margin: 10px 0;
font-family: 'Roboto', sans-serif;
font-weight: bold;
font-size: 2.4rem;
text-transform: uppercase;
letter-spacing: .3rems;
}
svg {
position: absolute;
top: 0;
left: 0;
bottom: 0;
margin: auto;
}
.red, .green {
transform-origin: 60% 60%;
-webkit-animation: zoom 1s ease-in-out infinite alternate;
animation: zoom 1s ease-in-out infinite alternate;
}
#keyframes zoom {
from {
transform: scale(1, 1);
}
to {
transform: scale(0.7, 0.7);
}
}
.timeline {}
<h1>Animation SVG</h1>
<span class="" id="red-grow">
<!-- display here the red circle's value when growing and shrinking -->
Value:
</span>
<span class="" id="green-grow">
<!-- display here the green circle's value when growing and shrinking -->
Value:
</span>
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<path fill="none" d="M-1-1h502v302H-1z"/>
<g>
<path class="timeline" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="null" stroke-width="4.5" stroke="#000" fill="none" d="M39.5 31.5v239M463.5 269.5l-422-1"/>
<ellipse class="red" id="inner" stroke="#e5a3a3" ry="65.5" rx="67" cy="165" cx="158.5" stroke-width="4.5" fill="none"/>
<ellipse class="green" stroke="#98FB98" ry="65.5" rx="67" cy="165" cx="361.5" stroke-width="4.5" fill="none"/>
</g>
</svg>
The current value of the animated transform property can be extracted using the getComputedStyle() method. That returns a matrix in string form which then need to extract the scale value from.
Here's an example solution that displays the current scale as a percentage.
var redCircle = document.getElementsByClassName('red')[0];
var greenCircle = document.getElementsByClassName('green')[0];
var redLabel = document.getElementById('red-grow');
var greenLabel = document.getElementById('green-grow');
function updateLabels()
{
var transformValue = getComputedStyle(redCircle).getPropertyValue('transform');
// transformValue is a string of the form "matrix(1, 0, 0, 1, 0 ,0)".
// For this example the first number in the matrix corresponds to the scale.
// We'll use a regular expression to extract it.
var currentScale = transformValue.match(/matrix\(([\d.]+)\,/)[1];
redLabel.textContent = Math.round(currentScale * 100) + '%';
requestAnimationFrame(updateLabels);
}
requestAnimationFrame(updateLabels);
body {
background-color: #584E56;
}
h1 {
color: #fff;
text-align: center;
margin: 10px 0;
font-family: 'Roboto', sans-serif;
font-weight: bold;
font-size: 2.4rem;
text-transform: uppercase;
letter-spacing: .3rems;
}
svg {
position: absolute;
top: 0;
left: 0;
bottom: 0;
margin: auto;
}
.red, .green {
transform-origin: 60% 60%;
-webkit-animation: zoom 1s ease-in-out infinite alternate;
animation: zoom 1s ease-in-out infinite alternate;
}
#keyframes zoom {
from {
transform: scale(1, 1);
}
to {
transform: scale(0.7, 0.7);
}
}
.timeline {}
<h1>Animation SVG</h1>
<span class="" id="red-grow">
<!-- display here the red circle's value when growing and shrinking -->
Value:
</span>
<span class="" id="green-grow">
<!-- display here the green circle's value when growing and shrinking -->
</span>
<svg width="500" height="300" xmlns="http://www.w3.org/2000/svg">
<path fill="none" d="M-1-1h502v302H-1z"/>
<g>
<path class="timeline" stroke-linecap="null" stroke-linejoin="null" stroke-opacity="null" stroke-width="4.5" stroke="#000" fill="none" d="M39.5 31.5v239M463.5 269.5l-422-1"/>
<ellipse class="red" id="inner" stroke="#e5a3a3" ry="65.5" rx="67" cy="165" cx="158.5" stroke-width="4.5" fill="none"/>
<ellipse class="green" stroke="#98FB98" ry="65.5" rx="67" cy="165" cx="361.5" stroke-width="4.5" fill="none"/>
</g>
</svg>
However in my opinion, it might be more straightforward to avoid using CSS animation, and instead update the circle transform or radius yourself in the requestAnimationFrame() function.