How to trigger css3 rotate effect by clicking? - javascript

I have two divs. One is applied the rotate effect and another would trigger by clicking.
$(function() {
$("a").click(function() {
$("#d1").addClass(".spinEffect");
});
});
#d1,
#d2 {
width: 100px;
height: 100px;
background-color: red;
margin: 50px 50px 50px 50px;
}
#d2 {
background-color: green;
-webkit-animation: spin 10s infinite linear;
}
.spinEffect {
-webkit-animation: spin 0.5s 1 linear;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="d1">
</div>
<div id="d2">
</div>
<a href=#>click me</a>
Here is the demo page. I know the problem should be in js, could someone tell me how to modify it?
It's working when I remove the .
But when I click the link, it only work once. How can I fix that?

You have an error near your addClass, you should put $("#d1").addClass("spinEffect"); and not ".spinEffect", the . is useless there ;)
For your second question, just add infinite in your css
.spinEffect{
-webkit-animation: spin 0.5s infinite linear;
}
EDIT
If you want the box to turn once every time you click on the button you can achieve it with the following method
$(function(){
$("a").click(function(){
var $d1 = $("#d1"); //little optimization because we will use it more than once
$d1.removeClass("spinEffect");
setTimeout(function(){$d1.addClass("spinEffect")},0);
});
});
You may ask why the setTimeout, it's because otherwise, the class is re-added to quickly for the CSS to trigger the effect ;)

all you have do is just remove the '.' from class name in js
JS:
$(function(){
$("a").click(function(){
$("#d1").addClass("spinEffect");
});
});

You can actually do this entirely in CSS and eschew the javascript completely (assuming the target browsers support the :target pseudo-class)
:target selects whichever element has the ID specified by the hash portion of the url, for example: http://localhost/#d1 would be the URL after clicking the link in this answer.
Note I realized that this means the animation would only happen once. So if this was for a situation where the link could be clicked multiple times, definitely go with the JS solution (though I think you'll have to remove the class and add it again to re-trigger the animation)
HTML:
<div id="d1">
</div>
<div id="d2">
</div>
click me
CSS:
#d1, #d2{
width: 100px;
height: 100px;
background-color: red;
margin: 50px 50px 50px 50px;
}
#d2{
background-color: green;
-webkit-animation: spin 10s infinite linear;
}
/* or #d1:target */
:target{
-webkit-animation: spin 0.5s 1 linear;
}
#-webkit-keyframes spin {
0% {-webkit-transform: rotate(0deg);}
100% {-webkit-transform: rotate(360deg);}
}

Related

How do i stop webkit animation through js? + fixing image to the right

I'm trying to build a puzzle game website. I'm using webkit animation to rotate (and translate) two images.
My plan is to have rotating gears attached to the left and right edge of my page, offset in a way that only half of each image is shown at a time.
The animation works fine but
(1) i am unable to pause it, and
(2) depending on window size the images are moved out of view (with an automatic scrollbar popping up) or into full view.
The setup is pretty simple:
I have 3 divs: one bar at the top with 100% width and two divs with 50% width below as containers for my images.
I might need to add more below or in between the two divs down the road but for now a solution for this would be good enough^^
For the animation i have a pseudo button on each side which adds a pause class to my images.
HTML
<div id="div-left">
<p>Hey this is the left div</p>
<img src="images/zahnrad.png" alt="zahnrad" id="image1">
<p id="pausebtn1" onclick="pause1()">pause</p>
</div>
<div id="div-right">
<p>hey this is the right div</p>
<img src="images/zahnrad.png" alt="zahnrad" id="image2">
<p id="pausebtn2" onclick="pause2()">pause</p>
</div>
CSS
#image1{
-webkit-animation: rotation-left 30s infinite linear;
}
#image1.paused1::-webkit-progress-value{
-webkit-animaion-play-state:paused;
animaion-play-state:paused;
}
#image2{
align: right;
-webkit-animation: rotation-right 30s infinite linear;
}
#image2.paused2::-webkit-progress-value{
-webkit-animaion-play-state:paused;
animaion-play-state:paused;
}
/* Animations */
#-webkit-keyframes rotation-left{
from {
-webkit-transform: translate(-50%,0px) rotate(0deg);
}
to{
-webkit-transform: translate(-50%,0px) rotate(359deg);
}
}
#-webkit-keyframes rotation-right{
from {
-webkit-transform:translate(+50%,0px) rotate(0deg);
}
to{
-webkit-transform:translate(+50%,0px) rotate(-359deg);
}
}
Javascript
function pause1() {
console.log("pause img 1");
document.getElementById('image1').classList.toggle("paused1");
}
function pause2() {
console.log("pause img 2");
document.getElementById('image2').classList.toggle("paused2");
}
So to sum it all up:
I have two images in the wrong places. They are animated. My two buttons are working but trying to pause the animation by adding a paused class doesn't function.
Any help would be appreciated and i'll see if i can add images later
You shouldn't be targeting ::-webkit-progress-value, that's for <progress> elements. Just toggle the class onto the element:
button.addEventListener('click', function () {
square.classList.toggle('paused');
});
#square {
animation: rotate 1s infinite;
background: lightblue;
border: 1px solid black;
height: 100px;
left: 50px;
position: absolute;
top: 50px;
width: 100px;
}
#square.paused {
animation-play-state: paused;
}
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<button id="button">Pause/Resume</button>
<div id="square">Rotate</div>

How to stop transforms in a CSS transition

I have set a CSS transition like
transition: all 2s
Then I apply a CSS to change the transform like:
transform: rotate(20deg);
Transition starts.
I want to stop it midway and have it stay there so I can then apply some other JS on it that is application dependent... what that is post-pausing is irrelevant to the question To test, I use:
setTimeout(function() {
...
}, 1000);
One crude way to stop the transition is to set CSS display to 'none'.
Setting transform to 'none' or empty string does not work. The transition goes to the end for transform. Another trick of resetting the CSS to the current one, works for other properties but not for transforms. Setting transition property to none or empty string also does not stop the transition's transform.
Surely there must be some way.
Any suggestion? Preferrably in JQuery
I do not want to use animation.
Why not using animation where you can easily manage the state:
$('button').eq(0).click(function() {
$('.box').css('animation-play-state', 'paused');
});
$('button').eq(1).click(function() {
$('.box').css('animation', 'none');
});
.box {
margin: 50px;
width: 100px;
height: 100px;
background: red;
display:inline-block;
vertical-align:top;
animation: anime 10s forwards;
}
#keyframes anime {
to {
transform: rotate(180deg);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
</div>
<button>Stop</button>
<button>Reset</button>
UPDATE
Here is a way that you can try with transition:
$('button').eq(0).click(function() {
$('.box').addClass('rotate');
});
$('button').eq(1).click(function() {
var e = $('.box').css('transform'); // get the current state
$('.box').css('transform', e); //apply inline style to override the one defined in the class
});
.box {
margin: 50px;
width: 100px;
height: 100px;
background: red;
display:inline-block;
vertical-align:top;
transition: all 10s;
}
.rotate {
transform: rotate(180deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
</div>
<button>start</button>
<button>stop</button>

CSS - Play animation while hovering, but not with an abrupt end

I am trying to create a sort of loading animation, with 3 bars that are below eachother that all have seperate keyframes.
The 3 bars are div elements, located inside a parent div.
<div id="menu">
<div id="menubox1"></div>
<div id="menubox2"></div>
<div id="menubox3"></div>
</div>
The animation properties are assigned to the individual menubox ids.
#menubox1:after {
content: '';
position: absolute;
bottom: 0px;
transform: translateY(-50%);
border-top: 1px solid #FFDADA;
animation: menukeyframes1;
animation-duration: 2000ms;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
animation-play-state: inherit;
}
#keyframes menukeyframes1 {
0% { width: 100%; left:0;}
...
}
My goal is to play the animation while the cursor is hovering over the parent div.
My attempt was to play around with animation-play-state which was set to running or paused, depending if the parent div was hovered.
The problem is that the animation is immediatly paused, before the animation is complete, which looks kind of bad if it stops mid-motion.
Is there a good fix for this, preferrably without JavaScript/jQuery, and across all browsers?
As you see it can't be done with just CSS at this moment, and as good jquery answers are already referenced, it's worth to mention that it could be solved in few lines of vanillaJS:
var dur = 2000;
document.querySelectorAll('.smooth').forEach(el=>{
var t;
el.addEventListener('mouseover',_=>{t = performance.now();el.style.animationPlayState = 'running'})
el.addEventListener('mouseout',_=>window.setTimeout(()=>el.style.animationPlayState = 'paused',dur-(performance.now()-t)%dur));
})
working pen
non-es6: BABEL
You can always fade out the animated divs using transitions.
Something like this might work for you:
#menubox1 {
opacity: 0;
transition: opacity .5s linear;
}
#menu:hover {
#menubox1 {
opacity: 1;
transition: opacity .5s linear;
}
}

How to make a marquee cycle once at a button click?

What I am trying to achieve is so that a marquee plays once when I click the button. My problem is that if I set the loop to 1 then it only plays once and then does nothing. My other problem is that it stops midway with my current code if I let go of the left mouse button. Or it stops where it was. Is there any way to make it either play once when the button is pressed and then play again whenever the button is pressed again and allow it to complete the loop completely. Here is the code, I am open to using java script instead of html. Here is my current code:
<marquee behavior="scroll" direction="up" scrollamount="30" id="marquee" height="40">
<p>+1</p>
</marquee>
<input type="button" id="gather" class="build" Value="play" onmousedown="document.getElementById('marquee').start()." onmouseup="document.getElementById('marquee').stop()" onload="document.getElementById('marquee').stop()">
You can use CSS keyframes and JQuery (or Javascript) in order to accomplish that.
In the example below, I'm using CSS rules to achieve the animation effect, and applying it adding/removing the span element from te DOM using JQuery.
Code example:
var marquee = '<span class="anim">+1</span>';
$('.btn').click(function(){
$('.anim').remove(); //remove the node if its there
$('.marquee').append(marquee); //append the node
});
.marquee{
width: 20px;
height: 20px;
overflow:hidden;
}
.marquee > span {
position:relative;
top:-100%;
left:0;
}
.anim{
animation-name: example;
animation-duration: 2s;
}
#keyframes example {
0%,100% {
opacity:0;
top:100%;
}
50% {
opacity:1;
top:0;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="marquee"></div>
<button class="btn">Click here!</button>
Are you willing to use pure CSS?
It seems like you want a "+1" counter on click. You can accomplish this using CSS transitions. I'm going to use an anchor rather than an input, because you have more control over styling it.
You'll probably want to add some movement to it, change the timing, maybe swap linear to ease-out, but this is a starting point. Please consider it a proof of concept.
HTML:
a.play {
padding:6px 8px;
border-radius:4px;
background:#ccc;
border:1px solid #bbb;
text-decoration:none;
color:#111;
position:relative;
}
a.play:focus:before,
a.play:active:before {
Content:"+1";
position:absolute;
top:-16px;
left:6px;
color:#006699;
font-weight:bold;
-webkit-animation: fadeinout 1.3s linear forwards;
animation: fadeinout 1.3s linear forwards;
}
#-webkit-keyframes fadeinout {
0%,100% { opacity: 0; }
10% { opacity: 1; }
}
#keyframes fadeinout {
0%,100% { opacity: 0; }
10% { opacity: 1; }
}
<div style="height:60px;"></div>
Play

CSS animation, toggle rotate on click

I am try to have the caret in the following rotate 180 degrees on click for my dropdown menu. In the solution Im trying to implement, it changes the class of the the caret to toggle-up or toggle-down on click. The first time I click on it rotates up, the second time it immediately goes back to its starting position and then rotates back up. I smell dirty code, whats the easiest way to add this toggle rotation animation. Thanks in advance for any help. Heres my current css:
.toggle-up {
animation-name: toggle-up;
animation-delay: 0.25s;
animation-duration: 0.75s;
animation-fill-mode: forwards;
}
.toggle-down {
animation-name: toggle-down;
animation-delay: 0.25s;
animation-duration: 0.75s;
animation-fill-mode: forwards;
}
/*animations*/
#keyframes toggle-up {
100% {
transform: rotate(180deg);
}
}
#keyframes toggle-down {
100% {
transform: rotate(180deg);
}
}
You don't really need a keyframe animation for something this simple. If you just add a class to your icon on click then remove it this will apply your rotation. Here is a working plunkr using font awesome and a simple rotation. This is just a simple example, you will want to make use of vendor prefixes and be aware that css transitions do not work in older browsers.
<div id="container">
<i id="icon" class="fa fa-arrow-down"></i>
</div>
.fa-arrow-down{
transform: rotate(0deg);
transition: transform 1s linear;
}
.fa-arrow-down.open{
transform: rotate(180deg);
transition: transform 1s linear;
}
(function(document){
var div = document.getElementById('container');
var icon = document.getElementById('icon');
var open = false;
div.addEventListener('click', function(){
if(open){
icon.className = 'fa fa-arrow-down';
} else{
icon.className = 'fa fa-arrow-down open';
}
open = !open;
});
})(document);
.square {
width: 100px;
height: 100px;
background-color: #ff0000;
transition: all 0.75s 0.25s;
}
.toggle-up {
transform: rotate(180deg);
}
.toggle-down {
transform: rotate(0);
}
You should have an initial state in order to complete your animation.
Here is the example: codepen
UPDATE
Here is the version without using javascript: codepen
<label for="checkbox">
<input type="checkbox" id="checkbox">
<div class="square toggle-down"></div>
</label>
#checkbox {
display: none;
}
.square {
width: 100px;
height: 100px;
background-color: #ff0000;
transition: all 0.75s 0.25s;
transform: rotate(0);
}
#checkbox:checked + .square {
transform: rotate(180deg);
}
The general idea is to change the block class using Adjacent sibling selectors and the checkbox checked state.

Categories

Resources