Setting .className of SVG path not working - javascript

I have a chevron SVG at the bottom of my page that I want to hide once the user scrolls down. I can't figure out why my JS isn't working and the chevron is never hidden:
NOTE: the console.log statements do run and the css stylesheet does work.
chevron = document.getElementById("down-accelerate-path");
window.addEventListener("scroll", e => {
const y = window.scrollY;
if (y >= 1) {
console.log(y + " " + chevron)
chevron.className = ""
chevron.hidden = true;
} else {
chevron.className = "hide"
chevron.hidden = false;
}
});
body {
height: 300vh;
}
.hide {
display: none;
}
#down-accelerate {
position: fixed;
top: 88%;
transform: translateX(-50%);
}
<span class="center">
<svg height=88 width=88 viewBox="0 0 444.819 444.819" xmlns="http://www.w3.org/2000/svg" id = "down-accelerate">
<path id="down-accelerate-path" style="" fill="white" stroke="none"
d="M434.252,114.203l-21.409-21.416c-7.419-7.04-16.084-10.561-25.975-10.561c-10.095,0-18.657,3.521-25.7,10.561
L222.41,231.549L83.653,92.791c-7.042-7.04-15.606-10.561-25.697-10.561c-9.896,0-18.559,3.521-25.979,10.561l-21.128,21.416
C3.615,121.436,0,130.099,0,140.188c0,10.277,3.619,18.842,10.848,25.693l185.864,185.865c6.855,7.23,15.416,10.848,25.697,10.848
c10.088,0,18.75-3.617,25.977-10.848l185.865-185.865c7.043-7.044,10.567-15.608,10.567-25.693
C444.819,130.287,441.295,121.629,434.252,114.203z"/>
</svg>
</span>

Your code appears to be working. But I couldn't see the chevron. So I made it black and changed its position for testing. I also cleaned up the code a bit.
chevron = document.getElementById("chevron");
window.addEventListener("scroll", e => {
const y = window.scrollY;
if (y >= 1) {
chevron.className = 'hide'
} else {
chevron.className = ''
}
});
body {
height: 300vh;
}
.hide {
display: none;
}
#down-accelerate {
position: fixed;
right: 50%;
}
<span class="center" id="chevron">
<svg height=88 width=88 viewBox="0 0 444.819 444.819" xmlns="http://www.w3.org/2000/svg" id = "down-accelerate">
<path id="down-accelerate-path" style="" fill="black" stroke="none"
d="M434.252,114.203l-21.409-21.416c-7.419-7.04-16.084-10.561-25.975-10.561c-10.095,0-18.657,3.521-25.7,10.561
L222.41,231.549L83.653,92.791c-7.042-7.04-15.606-10.561-25.697-10.561c-9.896,0-18.559,3.521-25.979,10.561l-21.128,21.416
C3.615,121.436,0,130.099,0,140.188c0,10.277,3.619,18.842,10.848,25.693l185.864,185.865c6.855,7.23,15.416,10.848,25.697,10.848
c10.088,0,18.75-3.617,25.977-10.848l185.865-185.865c7.043-7.044,10.567-15.608,10.567-25.693
C444.819,130.287,441.295,121.629,434.252,114.203z"/>
</svg>
</span>

Related

How to use javascript to display a loading animation before the api has fully loaded the data?

How to make the API data load the load animation first before all the data is returned, and then open the popup after the API has passed all the data in? Because currently when the load disappears, the data in the popup has not been fully loaded, which will cause the user to see the moment when the data is loaded and the size of the popup will change. I hope that the load animation will be displayed before all the data is uploaded to the popup , After the data is loaded, open the popup and close the loading animation. How should I modify this to make my user experience better? Thanks
let btn = document.querySelector('.btn');
let popup = document.querySelector('.popup');
let wrap = document.querySelector('.wrap');
let photo = document.querySelector('.photo');
let svg = document.querySelector('svg');
btn.addEventListener('click', function(e) {
svg.style.display = "block"
axios.get("https://dog.ceo/api/breeds/image/random")
.then((response) => {
let Data = response.data.message;
photo.src = Data;
svg.style.display = "none"
popup.style.display = "flex";
})
.catch((error) => console.log(error));
});
wrap.addEventListener('click', function(e) {
e.stopPropagation();
});
popup.addEventListener('click', function() {
popup.style.display = "none";
});
.popup {
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100vh;
display: none;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.popup .wrap {
width: 300px;
background-color: #fff;
text-align: center;
border-radius: 20px;
padding: 20px;
}
.popup .wrap .photo {
width: 100%;
height: 100%;
object-fit: conver;
border-radius: 20px;
}
svg {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
svg .load {
stroke-dasharray: 0 500;
animation: rot 1s linear infinite;
}
#keyframes rot {
100% {
stroke-dasharray: 500 500;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.2/axios.min.js"></script>
<button class='btn'>open data</button>
<div class="popup">
<div class="wrap">
<h1>Pet</h1>
<img class="photo" src="" alt="">
</div>
</div>
<svg width="240px" height="240px" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="110" cy="110" r="90" stroke-width="10" stroke="gainsboro" fill="none"></circle>
<circle cx="110" cy="110" r="90" stroke-width="10" stroke="darkturquoise" fill="none" class="load"></circle>
</svg>
Your code looks good, but you are missing one little piece. The tricky part is that image loading also takes time, and you want to show a loading indicator while the image itself is loading.
Based on the above, you need to wait for the image to load fully and only then show the final view.
Here is the change that you need to make:
btn.addEventListener('click', function(e) {
svg.style.display = "block"
axios.get("https://dog.ceo/api/breeds/image/random")
.then((response) => {
// set handler to show the image once it is loaded
photo.addEventListener('load', () => {
svg.style.display = "none"
popup.style.display = "flex";
});
// set image src after adding 'load' handler
photo.src = response.data.message;
})
.catch((error) => console.log(error));
});
Update based on additional questions in comments
To handle multiple images, you will need a bit more complex approach.
Since your code was just an example for a single image, for simplicity and demonstration's sake, based on your question in the comments, I'm assuming that your server can return an array of image URLs.
btn.addEventListener('click', function(e) {
svg.style.display = "block"
axios.get("https://dog.ceo/api/breeds/image/random")
.then((response) => {
// assuming your API returns tens of images
// this is an array of image URLs
const imageURLs = response.message.imageURLs;
// retrieving array of img elements from the page
// I would recommend actually generating img tags here
const imageElements = document.querySelector('.photo');
// we create a Promise for each img element
const imagePromises = imageElements.map((element, index) => {
return new Promise((resolve, reject) => {
element.addEventHandler('load', resolve);
element.addEventHandler('error', (e) => reject(e));
element.src = imageURLs[index];
});
});
// this will wait for all the promises to settle
Promise.allSettled(imagePromises).then((results) => {
// go through 'results' and handle errors if needed
// otherwise, this is the place where you know that
// all the images are loaded/failed
svg.style.display = "none"
popup.style.display = "flex";
});
})
.catch((error) => console.log(error));
});
Regarding what you should do in the catch, it largely depends on the behavior and visual feedback you need to make in the case of errors.
If you want to notify a user about an error, you can use catch to show some popup, for example.
Please let me know if this helps.
To solve that problem, you can try adding the onload property to the photo variable. The onload event occurs when an object has been loaded. Reference: https://www.w3schools.com/jsref/event_onload.asp
let btn = document.querySelector('.btn');
let popup = document.querySelector('.popup');
let wrap = document.querySelector('.wrap');
let photo = document.querySelector('.photo');
let svg = document.querySelector('svg');
btn.addEventListener('click', function(e) {
svg.style.display = "block"
axios.get("https://dog.ceo/api/breeds/image/random")
.then((response) => {
let Data = response.data.message;
photo.src = Data;
photo.onload = () => {
svg.style.display = "none";
popup.style.display = "flex";
}
})
.catch((error) => console.log(error));
});
wrap.addEventListener('click', function(e) {
e.stopPropagation();
});
popup.addEventListener('click', function() {
popup.style.display = "none";
});
.popup {
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100vh;
display: none;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.popup .wrap {
width: 300px;
background-color: #fff;
text-align: center;
border-radius: 20px;
padding: 20px;
}
.popup .wrap .photo {
width: 100%;
height: 100%;
object-fit: conver;
border-radius: 20px;
}
svg {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
svg .load {
stroke-dasharray: 0 500;
animation: rot 1s linear infinite;
}
#keyframes rot {
100% {
stroke-dasharray: 500 500;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.2/axios.min.js"></script>
<button class='btn'>open data</button>
<div class="popup">
<div class="wrap">
<h1>Pet</h1>
<img class="photo" src="" alt="">
</div>
</div>
<svg width="240px" height="240px" version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="110" cy="110" r="90" stroke-width="10" stroke="gainsboro" fill="none"></circle>
<circle cx="110" cy="110" r="90" stroke-width="10" stroke="darkturquoise" fill="none" class="load"></circle>
</svg>

Custom cursor not growing/scaling on hover (can't figure it out)

Hellol,I have a code for a custom cursor, and the cursor, which is a ball/circle, was supposed to grow/scale when hovering over a link, if you see the code below, this function is there, but it is not working, does anyone know what's wrong? Thank you in advance. Note, I am unable to create a snippet here. The code is from codepen: https://codepen.io/clementGir/pen/RQqvQx
<div class="cursor">
<div class="cursor__ball cursor__ball--big ">
<svg height="30" width="30">
<circle cx="15" cy="15" r="12" stroke-width="0"></circle>
</svg>
</div>
<div class="cursor__ball cursor__ball--small">
<svg height="10" width="10">
<circle cx="5" cy="5" r="4" stroke-width="0"></circle>
</svg>
</div>
</div>
<style>
body .cursor {
pointer-events: none;
}
body .cursor__ball {
position: fixed;
top: 0;
left: 0;
mix-blend-mode: difference;
z-index: 1000;
}
body .cursor__ball circle {
fill: #f7f8fa;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<script>
const $bigBall = document.querySelector('.cursor__ball--big');
const $smallBall = document.querySelector('.cursor__ball--small');
const $hoverables = document.querySelectorAll('a');
// Listeners
document.body.addEventListener('mousemove', onMouseMove);
for (let i = 0; i < $hoverables.length; i++) {
if (window.CP.shouldStopExecution(0)) break;
$hoverables[i].addEventListener('mouseenter', onMouseHover);
$hoverables[i].addEventListener('mouseleave', onMouseHoverOut);
}
// Move the cursor
window.CP.exitedLoop(0); function onMouseMove(e) {
TweenMax.to($bigBall, .4, {
x: e.clientX - 15,
y: e.clientY - 15
});
TweenMax.to($smallBall, .1, {
x: e.clientX - 5,
y: e.clientY - 7
});
}
// Hover an element
function onMouseHover() {
TweenMax.to($bigBall, .3, {
scale: 4
});
}
function onMouseHoverOut() {
TweenMax.to($bigBall, .3, {
scale: 1
});
}
</script>```
Growing cursor on hovering a link.
The codepen you are trying to copy links to external scripts and has been adapted to work inside codepen.
What I did to get the pen to work here (I think you only needed step 4):
For CSS & JS clicked down arrow top right, view compiled
Copy over all code
Settings>JS>External Scripts>Copy link into Stack Overflow snippet's external scripts
Removed 'window.CP' code junk which I assume is something to do with codepen and getting the window object of their sub-document
const $bigBall = document.querySelector('.cursor__ball--big');
const $smallBall = document.querySelector('.cursor__ball--small');
const $hoverables = document.querySelectorAll('.hoverable');
// Listeners
document.body.addEventListener('mousemove', onMouseMove);
for (let i = 0; i < $hoverables.length; i++) {
$hoverables[i].addEventListener('mouseenter', onMouseHover);
$hoverables[i].addEventListener('mouseleave', onMouseHoverOut);
}
// Move the cursor
function onMouseMove(e) {
TweenMax.to($bigBall, .4, {
x: e.pageX - 15,
y: e.pageY - 15 });
TweenMax.to($smallBall, .1, {
x: e.pageX - 5,
y: e.pageY - 7 });
}
// Hover an element
function onMouseHover() {
TweenMax.to($bigBall, .3, {
scale: 4 });
}
function onMouseHoverOut() {
TweenMax.to($bigBall, .3, {
scale: 1 });
}
body {
height: 100vh;
background: #010101;
cursor: none;
margin: 0;
display: flex;
font-family: monospace;
}
body h1,
body p,
body a {
color: #fff;
}
body a {
border-bottom: 2px solid #fff;
padding: 10px 0;
margin-top: 25px;
}
body .cursor {
pointer-events: none;
}
body .cursor__ball {
position: fixed;
top: 0;
left: 0;
mix-blend-mode: difference;
z-index: 1000;
}
body .cursor__ball circle {
fill: #f7f8fa;
}
body .left,
body .right {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
body .right {
background: #fff;
}
body .right a {
border-bottom: 2px solid #000;
}
body .right h1,
body .right p,
body .right a {
color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<div class="cursor">
<div class="cursor__ball cursor__ball--big ">
<svg height="30" width="30">
<circle cx="15" cy="15" r="12" stroke-width="0"></circle>
</svg>
</div>
<div class="cursor__ball cursor__ball--small">
<svg height="10" width="10">
<circle cx="5" cy="5" r="4" stroke-width="0"></circle>
</svg>
</div>
</div>
<div class="left">
<h1>Hello</h1>
<p>Check out this link:</p>
<a class="hoverable">Hover meh</a>
</div>
<div class="right">
<h1>Hello</h1>
<p>Check out this link:</p>
<a class="hoverable">Hover meh</a>
</div>

onmouseenter flickering tooltip

I want to display a tooltip when hovering over a svg rect but the tooltip keeps on flickering, switching between display: none and display: flex erratically and unpredictably.
When I used the same code but hovered over a div the result was very smooth, so it seems to be related to the rect element.
I get different behaviours in the snippet below than I do when I open the HTML in Chrome.
In the snippet it seems to work if i enter the rect from left to right or top to bottom, but not the other way around.
In Chrome it just keeps flickering which ever direction I enter.
Why is it behaving this way and what can I do about it?
const tooltips = document.querySelectorAll('.tooltip');
const bars = document.querySelectorAll('rect');
document.addEventListener('mousemove', fn);
function fn(e) {
tooltips[0].style.left = e.pageX + 'px';
tooltips[0].style.top = e.pageY + 'px';
}
bars[0].onmouseenter = () => {
tooltips[0].style.display = 'flex';
}
bars[0].onmouseleave = () => {
tooltips[0].style.display = 'none';
}
.tooltip {
display: none;
position: absolute;
background-color: grey;
}
<div class="tooltip">
<p>Rect 1</p>
</div>
<svg width="500" height="500">
<rect width="200" height="30" x="0" y="0" style="fill:rgb(0,0,255)" />
</svg>
Because when the tooltip is opened, it will come over the mouse. And mouseleave for rect is triggered, and tooltip closes and mouseenter is triggered again. So it goes into an infinite loop. We can use pointer-events: none to avoid mouse events on tooltip.
const tooltips = document.querySelectorAll('.tooltip');
const bars = document.querySelectorAll('rect');
document.addEventListener('mousemove', fn);
function fn(e) {
tooltips[0].style.left = e.pageX + 'px';
tooltips[0].style.top = e.pageY + 'px';
}
bars[0].onmouseenter = () => {
tooltips[0].style.display = 'flex';
}
bars[0].onmouseleave = () => {
tooltips[0].style.display = 'none';
}
.tooltip {
display: none;
position: absolute;
background-color: grey;
pointer-events: none;
}
<div class="tooltip">
<p>Rect 1</p>
</div>
<svg width="500" height="500">
<rect width="200" height="30" x="0" y="0" style="fill:rgb(0,0,255)" />
</svg>
Another way, you can push the tooltip a little further away from the mouse. I used e.pageX + 5 and e.pageY + 5 for example.
const tooltips = document.querySelectorAll('.tooltip');
const bars = document.querySelectorAll('rect');
document.addEventListener('mousemove', fn);
function fn(e) {
tooltips[0].style.left = (e.pageX + 5) + 'px';
tooltips[0].style.top = (e.pageY + 5) + 'px';
}
bars[0].onmouseenter = () => {
tooltips[0].style.display = 'flex';
}
bars[0].onmouseleave = () => {
tooltips[0].style.display = 'none';
}
.tooltip {
display: none;
position: absolute;
background-color: grey;
}
<div class="tooltip">
<p>Rect 1</p>
</div>
<svg width="500" height="500">
<rect width="200" height="30" x="0" y="0" style="fill:rgb(0,0,255)" />
</svg>

How to gradually change attribute values with Javascript? eg. Ease-in, Ease-out

I want to change an element's attribute (a filter for an SVG) from 0 to 10 and back to 0 infinitely. For this I made a js function breathe:
let flag = 0;
let loader = setInterval(breathe, 1000);
function breathe() {
if (flag === 0) {
document
.getElementById("main-blur")
.setAttribute("stdDeviation", "10");
flag = 1;
return;
} else {
document
.getElementById("main-blur")
.setAttribute("stdDeviation", "0");
flag = 0;
return;
}
}
The problem is that the blur value changes from 10 to 0 directly. I want it to gradually increase and decrease for a breathing type effect.
If you are going for the JS solution rather than using <animate>, you should use window.requestAnimationFrame():
// Get a reference to the SVG filter only once:
const gaussianBlur = document.getElementById('gaussianBlur');
// To control the animation: 0 to 100 we increase blur, 100 to 200 we decrease blur. We use these
// values instead of 0-10 and then divide by 10 to produce a smoother animation.
let step = 0;
function tick() {
const blur = step < 100 ? step : 200 - step;
// Update blur (converting step to 0-10). You could change this to take into account time:
gaussianBlur.setAttribute('stdDeviation', blur / 10);
// Update step:
step = (step + 1) % 200;
requestAnimationFrame(tick);
}
tick();
#element {
position: fixed;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
transform: translate(-50%, -50%);
}
<svg id="element" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<filter id="blurFilter" x="-100%" y="-100%" width="300%" height="300%">
<feGaussianBlur id="gaussianBlur" />
</filter>
<circle cx="50" cy="50" r="25" style="filter: url(#blurFilter); " />
</svg>
Otherwise, using <animate>, you need to use its values and keyTimes attributes:
#element {
position: fixed;
top: 50%;
left: 50%;
width: 200px;
height: 200px;
transform: translate(-50%, -50%);
}
<svg id="element" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<filter id="blurFilter" x="-100%" y="-100%" width="300%" height="300%">
<feGaussianBlur id="gaussianBlur" stdDeviation="1" />
</filter>
<animate
xlink:href="#gaussianBlur"
attributeName="stdDeviation"
dur="2s"
repeatCount="indefinite"
values="0; 10; 0"
keyTimes="0; .5; 1"
/>
<circle cx="50" cy="50" r="25" style="filter: url(#blurFilter); " />
</svg>
You could try using a simple number incrementor/decrementor like so:
let delta = 1;
let current = 0;
let loader = setInterval(breathe, 1000);
function breathe() {
if (current === 10) delta = -1;
else if (current === 0) delta = 1;
current += delta;
document.getElementById("main-blur")
.setAttribute("stdDeviation", String(current));
}

Circular countdown JavaScript from 10 to Zero

I have been trying to reverse the countdown in this demo from 10 down to zero Without luck.
I have tried reversing the countdown by doing this:
(1*(initialOffset/time))-initialOffset )
It did reverse the animated circle but not the countdown.
Any ideas?
Thanks
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);
.item {
position: relative;
float: left;
}
.item h2 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
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">
<h2>0</h2>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/>
</svg>
</div>
Here is also a codepen copy:
https://codepen.io/kaolay/pen/LRVxKd
Try $('h2').text(time - i); instead of $('h2').text(i);
I also added $('h2').text(time); as the 4th line to draw 10 at the beginning
Also, the first part of the circle is not animated in your code, so I changed this line:
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
To this block:
$('.circle_animation').css('stroke-dashoffset', initialOffset);
setTimeout(() => {
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
})
var time = 10;
var initialOffset = '440';
var i = 1;
$('h2').text(time); // adding 10 at the beginning if needed
/* Need initial run as interval hasn't yet occured... */
$('.circle_animation').css('stroke-dashoffset', initialOffset);
setTimeout(() => {
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
})
var interval = setInterval(function() {
$('h2').text(time - i); // here is the clue
if (i == time) {
clearInterval(interval);
return;
}
$('.circle_animation').css('stroke-dashoffset', initialOffset-((i+1)*(initialOffset/time)));
i++;
}, 1000);
.item {
position: relative;
float: left;
}
.item h2 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
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">
<h2>0</h2>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/>
</svg>
</div>
If you update this line $('h2').text(time - i); then you'll get the numeric countdown. I also initalize i = 0 so that the starting number is 10:
var time = 10;
var initialOffset = '440';
var i = 0
/* Need initial run as interval hasn't yet occured... */
$('.circle_animation').css('stroke-dashoffset', initialOffset-(1*(initialOffset/time)));
var interval = setInterval(function() {
$('h2').text(time - i);
if (i == time) {
clearInterval(interval);
return;
}
$('.circle_animation').css('stroke-dashoffset', initialOffset-((i+1)*(initialOffset/time)));
i++;
}, 1000);
.item {
position: relative;
float: left;
}
.item h2 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
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">
<h2>0</h2>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/>
</svg>
</div>
What exactly are you asking here?
"It did reverse the animated circle but not the countdown."
you are just trying to countdown?
why not set i = 10 and then do i--
If you want to invert the animation just invert all states of initial values and change i to (time-i). So it goes like this:
<div class="item">
<h2>10</h2>
<svg width="160" height="160" xmlns="http://www.w3.org/2000/svg">
<circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/>
</svg>
</div>
.item {
position: relative;
float: left;
}
.item h2 {
text-align:center;
position: absolute;
line-height: 125px;
width: 100%;
}
svg {
transform: rotate(-90deg);
}
.circle_animation {
stroke-dasharray: 440; /* this value is the pixel circumference of the circle */
stroke-dashoffset: 0;
transition: all 1s linear;
}
var time = 10;
var initialOffset = 440;
var i = 0
/* Need initial run as interval hasn't yet occured... */
$('.circle_animation').css('stroke-dashoffset', 0);
var interval = setInterval(function() {
$('h2').text(time-i);
if (i == time) {
clearInterval(interval);
return;
}
$('.circle_animation').css('stroke-dashoffset', initialOffset*i/time);
i++;
}, 1000);
Code pen:
https://codepen.io/anon/pen/Xybpge

Categories