CSS Animation Onclick

CSS Animation onClick

Are you sure you only display your page on webkit? Here is the code, passed on safari.
The image (id='img') will rotate after button click.

function ani() {
document.getElementById('img').className = 'classname';
}
.classname {
-webkit-animation-name: cssAnimation;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease;
-webkit-animation-fill-mode: forwards;
}

@-webkit-keyframes cssAnimation {
from {
-webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(100px);
}
to {
-webkit-transform: rotate(0deg) scale(2) skew(0deg) translate(100px);
}
}
<input name="" type="button" onclick="ani()" value="Click">
<img id="img" src="https://i.stack.imgur.com/vghKS.png" width="328" height="328" />

Trigger CSS Animation on Click via javascript

A bit ugly, because of the extra class needed, but it works:

var hamburgerMenu = document.querySelector('.hamburger-menu');
hamburgerMenu.addEventListener('click', function() {
var hamburgerMenuSpan2 = document.querySelector('.hamburger-second');

if (hamburgerMenuSpan2.classList.contains("animate-out")) {
hamburgerMenuSpan2.classList.remove("animate-out");
hamburgerMenuSpan2.classList.add("animate-in");
} else {
hamburgerMenuSpan2.classList.add("animate-out");
hamburgerMenuSpan2.classList.remove("animate-in");
}

});
.hamburger-menu {
position: absolute;
top: 20px;
right: 20px;
}

.hamburger-line-2 {
animation-duration: 3s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
animation-direction: alternate;
}

.animate-out {
animation-name: animate-out;
}

.animate-in {
animation-name: animate-in;
}

@keyframes animate-out {
0% {
width: 40px;
}
100% {
width: 0px;
}
}

@keyframes animate-in {
0% {
width: 0px;
}
100% {
width: 40px;
}
}

.hamburger-menu span {
display: block;
width: 40px;
height: 2px;
background: black;
margin: 10px 0px;
}
<div class="hamburger-menu">
<span class="hamburger-line-1"></span>
<span class="hamburger-second hamburger-line-2"></span>
<span class="hamburger-line-3"></span>
</div>

Trigger CSS Animation on div click

Note that in your code, the elements that have "animation" css rules are the LI elements. So changing the animation property of the UL's style won't work.

Here I changed your CSS a bit so that you can give the UL the class of "animate" and the child LIs will animate. When you press the button it removes that class, and then using a setTimeout re-adds it, it should reset and replay the animation.

document.getElementById("clickable").addEventListener("click", controlAnimation);

function controlAnimation() {
const menu = document.querySelector('#menu-main-menu');
menu.classList.remove('animate');
setTimeout(() => {
menu.classList.add('animate');
}, 0);
}
#menu-main-menu li {
border-bottom: solid 1px #999;
}

#menu-main-menu.animate li {
opacity: 0;
-webkit-animation: fadeInMenu 0.5s 1;
animation: fadeInMenu 0.5s 1;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}

#menu-main-menu.animate li:nth-child(5n+1) {
-webkit-animation-delay: 0.1s;
animation-delay: 0.1s;
}

#menu-main-menu.animate li:nth-child(5n+2) {
-webkit-animation-delay: 0.3s;
animation-delay: 0.3s;
}

#menu-main-menu.animate li:nth-child(5n+3) {
-webkit-animation-delay: 0.5s;
animation-delay: 0.5s;
}

#menu-main-menu.animate li:nth-child(5n+4) {
-webkit-animation-delay: 0.7s;
animation-delay: 0.7s;
}

#menu-main-menu.animate li:nth-child(5n+5) {
-webkit-animation-delay: 0.9s;
animation-delay: 0.9s;
}

/* Animation steps */

@-webkit-keyframes fadeInMenu {
0% {
opacity: 0.0;
transform: translateY(16px);
}
100% {
opacity: 1.0;
}
}

@keyframes fadeInMenu {
0% {
opacity: 0.0;
transform: translateY(16px);
}
100% {
opacity: 1.0;
}
<div id="clickable" >Click me</div>
<br>
<ul id="menu-main-menu" class='animate'>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>

</ul>

I can make an div fade in onclick, but how do i make it fade out?

Easier approach using jQuery animation, no CSS animation

function scrollToAccept() {
const terms = document.querySelector('.terms-and-conditions');
const button = document.querySelector('.accept');
// const watch = document.querySelector('.watch');

if (!terms) {
return; // quit function because there is no terms
}

// fires on page load because can't find element
function obCallback(payload) {
// console.log(payload[0].isIntersecting); // whether element is in view or not
// console.log(payload[0].intersectionRatio); // how much of the element is showing
if (payload[0].intersectionRatio === 1) {
button.disabled = false;
// stop observing the last element
ob.unobserve(terms.lastElementChild);
}
}

// takes in callback parameter
// will be called every time it needs to check if something is currently on the page
// watcher (needs to be told what to watch
const ob = new IntersectionObserver(obCallback, {
root: terms,
threshold: 1,
});

// call observe method on what we want to watch
// ob.observe(watch);
ob.observe(terms.lastElementChild);

}
scrollToAccept();

$('.yes').on('click', function(e) {
e.preventDefault();
$('.TOSHIDE').fadeToggle(3000).toggleClass('active');
//$(this).parents('ul').next().toggleClass('active');
});
body {
background: #ffffff;
}

.wrapper-all {
min-height: 94vh;
display: grid;
justify-content: center;
align-content: center;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 2;
}

.wrapper {
width: 400px;
height: 80vh;
padding: 20px;
border: 1px solid black;
background: white;
display: grid;
grid-template-rows: 1fr auto;
}

button {
background: #133C55;
color: white;
font-size: 1rem;
padding: 20px;
transition: opacity 0.2s;
}

button[disabled] {
opacity: 0.1;
/* transform: translateX(-300%) scale(0.5); */
}

.terms-and-conditions {
overflow: scroll;
}

footer {
background-color: #192718;
width: 100%;
padding: 8px 0;
margin-top: 8px;
}

footer .container {
width: 800px;
margin: 0 auto;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
justify-content: space-between;
align-items: flex-start;
}

footer .container a {
color: #fff;
}

footer a:hover {
color: #fce26a;
}

.tacbox {
display: block;
padding: 1em;
margin: 2em;
border: 3px solid #ddd;
background-color: #eee;
max-width: 800px;
}

input {
height: 2em;
width: 2em;
vertical-align: middle;
}

.TOSHIDE {
display: none;
}

.TOSHIDE.active {
display: block;
opacity: 1;
}
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Terms of Service</title>
<link rel="stylesheet" href="./scroll-to-accept.css" />
<link rel="stylesheet" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>

<body>

<script>
function unhideTOS() {
document.getElementById("text").style.display = "";
}
</script>

<script>
function unlockBTN() {
document.getElementById("text").style.display = "";
}
</script>

<div class="tacbox">
<!-- The code for the checkbox + download if checked. -->
I agree to these ‌<a href="#tos" class="yes">Terms and Conditions.</a>
<br>
<a id="text" style="display:none" href="file.doc" Download>Download!</a>
</div>

<div class="TOSHIDE">
<div class="wrapper-all">
<div class="wrapper">
<div class="terms-and-conditions">
<h1>Terms and Conditions</h1>
<p>Disclaimer THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. You are the Current Maintainer of the Software, and to permit recipients of the Licensed Product for any such warranty, support,
indemnity or liability obligations to one or more recipients of Covered Code. However, You may do so in a commercial product offering.</p>
<hr>
</div>
<button class="accept" disabled autocomplete="off" id="myCheck" onclick="unlockBTN()">Accept</button>
</div>
</div>
</div>
<script src="./scroll-to-accept.js"></script>
</body>

</html>

How to synchronize CSS animations that were started/restarted at different times

For this purpose document.getAnimations() is a useful method. It returns an array of all animation objects currently in effect whose target elements are descendants of the document. More information: https://developer.mozilla.org/en-US/docs/Web/API/Document/getAnimations

Items of document.getAnimations() include currentTime property, that can use for syncing animations. More information: https://drafts.csswg.org/web-animations/#dom-documentorshadowroot-getanimations

toggleFx function was modified and now it has three parts.

In the first part, search document.getAnimations() and find currentTime attribute where animationName is one of pulse_active or pulse_inverted; then store them in the realted variables (i.e. pulseActiveStart and pulseInvertedStart).

In the 2nd part, className of spanTarget changed as you told.

In the 3rd part, pulseActiveStart and pulseInvertedStart applied to currentTime attribute of related animation (reverse 1st part).

function toggleFx(spanID) {

let spanTarget = document.getElementById(spanID);

let pulseActiveStart;
let pulseInvertedStart;
let anims = document.getAnimations()
for(let i = 0; i < anims.length; i++) {
if(anims[i].animationName == "pulse_active") pulseActiveStart = anims[i].currentTime;
else if(anims[i].animationName == "pulse_inverted") pulseInvertedStart = anims[i].currentTime;
}



if(spanTarget.classList.contains('pulse_invert')) {
spanTarget.classList.remove('pulse_invert');
spanTarget.classList.remove('pulse');
} else if(spanTarget.classList.contains('pulse')) {
spanTarget.classList.add('pulse_invert');
spanTarget.classList.remove('pulse');
} else {
spanTarget.classList.add('pulse');
}

anims = document.getAnimations()
for(let i = 0; i < anims.length; i++) {
if(anims[i].animationName == "pulse_active") {
if(pulseActiveStart) anims[i].currentTime = pulseActiveStart;
} else if(anims[i].animationName == "pulse_inverted") {
if(pulseInvertedStart) anims[i].currentTime = pulseInvertedStart;
}
}
}
div {
display: flex;
flex-flow: column;
}

span.pulse {
color: #f00;
animation: pulse_active 1.5s ease-in infinite;
}

span.pulse_invert {
color: #00f;
animation: pulse_inverted 3s ease-in infinite;
}

@keyframes pulse_active {
0% { opacity: 0; }
50% { opacity: 0.66; }
100% { opacity: 0; }
}

@keyframes pulse_inverted {
0% { opacity: 1; }
50% { opacity: 0.33; }
100% { opacity: 1; }
}
<div>
<span id="spA" onclick="toggleFx('spA')">A</span>
<span id="spB" onclick="toggleFx('spB')">B</span>
<span id="spC" onclick="toggleFx('spC')">C</span>
<span id="spD" onclick="toggleFx('spD')">D</span>
</div>

css animation-play-state on click

You can use the ~ to change properties of changing css of the element's sibling.

Assuming you want to totally do it in css, you can't really make the button play & pause at the same time, you can use JS for a single button.

I have done it using 2 buttons here, one button for playing & one for pausing.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<button class="button" id="play">play</button>
<button class="button" id="pause">pause</button>
<div id="stage"></div>
</body>
</html>

CSS

#stage{
height:300px;
border:1px solid #000;
overflow: hidden;
animation: stage-change 6s 6 forwards;
animation-play-state: paused;
}

@keyframes stage-change {
0% {
background-color: darkorange ;
}
100% {
background-color: #1c1341;
}
}
#play:focus ~ #stage{
animation-play-state: running;
}
#pause:focus ~ #stage{
animation-play-state: paused;
}

OR

You can use the checkbox hack, if you really just want to use one input element to control the animation.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<input type="checkbox" id="check"> play
<div id="stage"></div>
</body>
</html>

CSS

#stage{
height:300px;
border:1px solid #000;
overflow: hidden;
animation: stage-change 6s 6 forwards;
animation-play-state: paused;
}

@keyframes stage-change {
0% {
background-color: darkorange ;
}
100% {
background-color: #1c1341;
}
}
#play:checked ~ #stage{
animation-play-state: running;
}

How to start css animation on click and run the animation reversed on second click?

If you really want to make this reversible animation, I suggest you to use transition instead of keyframes, since when you start the animation, there's no way to keep track the current state and the target state, so if you click the button while the animation is unfinished, it'll jump directly to the last frame and play reverse.

But still, here's the solution:

const demo = document.querySelector('.demo');

const button = document.querySelector('button');

let reverse = false;

button.addEventListener('click', onClickPlay);

function onClickPlay(){

// Save the animation state

let animation = demo.style.animation;



// Clear the animation

demo.style.animation = 'none';



// You need to call this at next draw call to make the animation take effects

setTimeout(()=>{

// Restore the animation

demo.style.animation = animation;

// Make the animation running

demo.style.animationPlayState = 'running';

// Set the animation direction by current state

demo.style.animationDirection = reverse ? 'reverse' : 'normal';

// Flip the state

reverse = !reverse;

button.innerText = reverse ? 'Reverse' : 'Forward';

}, 0);

}
@keyframes anim {

0% {

width: 0px;

background-color: red;

}



100% {

width: 100px;

background-color: blue;

}

}

.demo {

/* Make the animation paused at the beginning */

animation: anim 1s paused both;

width: 0px;

height: 20px;

}
<button>Forward</button>

<div class="demo"><div>

CSS Animations Onclick

I think it should be

document.getElementById("s1_imgB").className += " shake";


Related Topics



Leave a reply



Submit