Issue
I have 3 svgs I use in my button element an unchecked svg, checked and loading. By default the unchecked is set to 1 while the rest are 0. I'd like to change the opacity of the unchecked to zero the checked when the button is clicked, and set a small timeout where the loading svg opacity is set to 1 and after the timeout, the checked svg is set 1 while the rest are 0 and vice versa. But it's not working as expected the opacity of the unchecked isn't changing when the button is clicked. Neither do the checked changes.
Here's my code snippets of the issue
Html:
function toggleState(buttonIndex) {
const uncheckedSvg = document.querySelector(`#button${buttonIndex} .unchecked`);
const checkedSvg = document.querySelector(`#button${buttonIndex} .checked`);
const loadingSvg = document.querySelector(`#button${buttonIndex} .loading`);
loadingSvg.style.opacity = '1';
setTimeout(() => {
loadingSvg.style.opacity = '0';
uncheckedSvg.style.opacity = checkedSvg.style.opacity === '0' || checkedSvg.style.opacity === '' ? '1' : '0';
checkedSvg.style.opacity = uncheckedSvg.style.opacity === '0' || uncheckedSvg.style.opacity === '' ? '1' : '0';
}, 1000);
}
.check-box {
display: block;
height: fit-content;
position: relative;
}
.svg-container {
position: relative;
}
.svg-container .unchecked {
opacity: 1;
/* Set initial opacity to 1 */
}
.svg-container .checked,
.svg-container .loading {
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
.checked {
animation: fadeOutChecked 1s ease-in-out forwards;
}
.loading {
animation: fadeOutLoading 1s ease-in-out forwards;
}
@keyframes fadeOutChecked {
to {
opacity: 0;
}
}
@keyframes fadeOutLoading {
to {
opacity: 0;
}
}
<button class="check-box" id="button1" onclick="toggleState(1)">
<div class="svg-container">
<svg class="unchecked button1" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="12" stroke="#8b8b8b" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4 6" />
</svg>
<svg class="checked button1" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="12" r="10" fill="#303030"></circle>
<path d="M17.2738 8.52629C17.6643 8.91682 17.6643 9.54998 17.2738 9.94051L11.4405 15.7738C11.05 16.1644 10.4168 16.1644 10.0263 15.7738L7.3596 13.1072C6.96908 12.7166 6.96908 12.0835 7.3596 11.693C7.75013 11.3024 8.38329 11.3024 8.77382 11.693L10.7334 13.6525L15.8596 8.52629C16.2501 8.13577 16.8833 8.13577 17.2738 8.52629Z" fill="#fff"></path>
</svg>
<svg class="loading button1" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 28 28" fill="none">
<path
d="M26 14C26 16.3734 25.2962 18.6935 23.9776 20.6668C22.6591 22.6402 20.7849 24.1783 18.5922 25.0866C16.3995 25.9948 13.9867 26.2324 11.6589 25.7694C9.33114 25.3064 7.19295 24.1635 5.51472 22.4853C3.83649 20.8071 2.6936 18.6689 2.23058 16.3411C1.76755 14.0133 2.00519 11.6005 2.91345 9.4078C3.8217 7.21509 5.35977 5.34094 7.33316 4.02236C9.30655 2.70379 11.6266 2 14 2"
stroke="#8b8b8b"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</button>
Here's what I have so far. I'd appreciate any assistance. Thanks
Solution
Let's create a class of .active {opacity:1} along with transition on the element(s) itself, then toggle the class on the correct images.
function toggleState(buttonIndex) {
const uncheckedSvg = document.querySelector(`#button${buttonIndex} .unchecked`);
const checkedSvg = document.querySelector(`#button${buttonIndex} .checked`);
const loadingSvg = document.querySelector(`#button${buttonIndex} .loading`);
if (checkedSvg.classList.contains("active")) {
// toggle off
loadingSvg.classList.add('active');
checkedSvg.classList.remove('active');
setTimeout(function() {
uncheckedSvg.classList.add('active');
loadingSvg.classList.remove('active');
}, 500)
} else {
// toggle on
uncheckedSvg.classList.remove('active');
loadingSvg.classList.add('active');
setTimeout(function() {
loadingSvg.classList.remove('active');
checkedSvg.classList.add('active');
}, 500)
}
}
.check-box {
display: block;
height: fit-content;
position: relative;
}
.svg-container {
position: relative;
width: 30px;
height: 30px;
}
.svg-container .button1.active {
opacity: 1;
}
.svg-container .button1 {
transition: 250ms;
position: absolute;
top: 0;
left: 0;
opacity: 0;
}
<button class="check-box" id="button1" onclick="toggleState(1)">
<div class="svg-container">
<svg class="unchecked button1 active" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 32 32" fill="none">
<circle cx="16" cy="16" r="12" stroke="#8b8b8b" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="4 6" />
</svg>
<svg class="checked button1" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 24 24" fill="none">
<circle cx="12" cy="12" r="10" fill="#303030"></circle>
<path d="M17.2738 8.52629C17.6643 8.91682 17.6643 9.54998 17.2738 9.94051L11.4405 15.7738C11.05 16.1644 10.4168 16.1644 10.0263 15.7738L7.3596 13.1072C6.96908 12.7166 6.96908 12.0835 7.3596 11.693C7.75013 11.3024 8.38329 11.3024 8.77382 11.693L10.7334 13.6525L15.8596 8.52629C16.2501 8.13577 16.8833 8.13577 17.2738 8.52629Z" fill="#fff"></path>
</svg>
<svg class="loading button1" xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 28 28" fill="none">
<path
d="M26 14C26 16.3734 25.2962 18.6935 23.9776 20.6668C22.6591 22.6402 20.7849 24.1783 18.5922 25.0866C16.3995 25.9948 13.9867 26.2324 11.6589 25.7694C9.33114 25.3064 7.19295 24.1635 5.51472 22.4853C3.83649 20.8071 2.6936 18.6689 2.23058 16.3411C1.76755 14.0133 2.00519 11.6005 2.91345 9.4078C3.8217 7.21509 5.35977 5.34094 7.33316 4.02236C9.30655 2.70379 11.6266 2 14 2"
stroke="#8b8b8b"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
</button>
Answered By - IT goldman
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.