my context
HTML
<div class="cart">
<div class="black"></div>
</div>
JS
var whiteEl="<div class="white"></div>";
//I would like to replace black with white, flip animation.
$(".cart").empty().append(whiteEl);
whiteEl.addClass("flipanim");
css
#-webkit-keyframes flip{
from{
-webkit-transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(180deg);
}
}
/*
similar cross browser code*/
.flipanim{
-webkit-animation: flip 1s 1;
-moz-animation:flip 1s 1;
-o-animation:flip 1s 1;
animation:flip 1s 1;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
I am using key frame animation for show transform animation.
and in javascript adding class to attached element.
my animation not working.
How can I add the new element with flip animation to ".cart"?
try this
$(".cart").html('').append(whiteEl);
//since you have already appended the created div here.. you can use class selctor.
$('.white').addClass("flipanim");
You don't need to remove any content for that and also don't need Javascript for it:
html-markup:
<div class="container">
<div class="cart">
<div class="black">Black side</div>
<div class="white">White side</div>
</div>
</div>
css:
.cart div {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
}
.cart .black {
background:#111;
color:white;
}
.cart .white {
-webkit-transform: rotateY(180deg);
color: black;
background: #eee;
}
Now you can apply your effects simply with:
.container:hover .cart {
-webkit-transform: rotateY(180deg);
}
See the Demo
Related
I am trying to have a animation play when an element is selected, and the reverse animation play when the element is deselected. My CSS looks like this:
#keyframes scale-effect {
from {
transform: scale(1);
}
to {
transform: scale(0.75);
}
}
.card.active {
animation: 1s ease-in-out reverse scale-effect;
}
.card.inactive {
animation: 1s ease-in-out forwards scale-effect;
transform: scale(0.75);
}
This plays the correct animations on page load. However, if I try to change the selected class in javascript:
newActiveObject.classList.remove('inactive');
oldActiveObject.classList.remove('active');
oldActiveObject.classList.add('inactive');
newActiveObject.classList.add('active');
Now, the classes get added properly, and I can see the size changes. However, no animation plays.
Things I have tried:
Using setTimeout(..., 0), between removing and adding classes does not have any effect. Same for 1.
Using setTimeout(..., 10), works, but very clear ugly fash of post-animation style before animation starts
Putting the animation in .card, instead of .inactive. This seems to just disable all animation even on page load.
Using getComputedStyle to force DOM redraw in between removing and adding classes. Has no effect.
Does anyone know how to properly replace a animation after removing a class?
Why don't you use transition instead? With animation, it's hard to control the flow. You need either to use a 2nd animation (one for active, one for inactive) or to trigger a reflow in JavaScript (see similar question). Here an example with transition:
const $cards = Array.from(document.getElementsByClassName("card"))
function handleClick(evt) {
$cards.forEach($card => $card.classList.remove("active"))
evt.target.classList.add("active")
}
$cards.forEach($card => $card.addEventListener("click", handleClick))
.card {
display: inline-block;
margin: 10px;
width: 100px;
height: 100px;
border: 1px solid gray;
cursor: pointer;
transition: transform 1s ease-in-out;
transform: scale(0.75);
}
.card.active {
transform: scale(1);
}
<div class="card">CARD 1</div>
<div class="card">CARD 2</div>
<div class="card">CARD 3</div>
<div class="card">CARD 4</div>
If your really need animation, here a working example with 2 animations:
const $cards = Array.from(document.getElementsByClassName("card"))
function handleClick(evt) {
$cards.forEach($card => {
$card.classList.remove("active")
$card.classList.add("inactive")
})
evt.target.classList.remove("inactive")
evt.target.classList.add("active")
}
$cards.forEach($card => $card.addEventListener("click", handleClick))
#keyframes scale-effect-out {
from { transform: scale(1); }
to { transform: scale(0.75); }
}
#keyframes scale-effect-in {
from { transform: scale(0.75); }
to { transform: scale(1); }
}
.card {
display: inline-block;
margin: 10px;
width: 100px;
height: 100px;
border: 1px solid gray;
cursor: pointer;
}
.card.inactive {
animation: 1s forwards ease-in-out scale-effect-out;
}
.card.active {
animation: 1s forwards ease-in-out scale-effect-in;
}
<div class="card inactive">CARD 1</div>
<div class="card inactive">CARD 2</div>
<div class="card inactive">CARD 3</div>
<div class="card inactive">CARD 4</div>
I have faced this before, you need to reset the animation for the target element, before adding another animation by javascript.
var el = document.getElementById('target_element_id');
el.style.animation = 'none'; // clear animation
el.offsetHeight; /* trigger reflow */
and then you can add another animation/class.
If needed try css '!important' while changing animation.
Assuming the active card should start on .75, then get bigger.
.card.active {
transform: scale(0.75); /* moved this to here */
animation: 1s ease-in-out reverse scale-effect;
}
.card.inactive {
animation: 1s ease-in-out forwards scale-effect;
}
What I would like to accomplish is that when the image changes after the hover it stays like that for a few seconds, and then it returns to the original image.
What I would like to know is if there's a way to add that kind of delay. I have attached my code below.
<html>
<body>
<img src='http://www.freedigitalphotos.net/images/img/homepage/87357.jpg'
width='142' height='162'
onmouseover="this.src='http://7606-presscdn-0-74.pagely.netdna-cdn.com/wp-content/uploads/2016/03/Dubai-Photos-Images-Oicture-Dubai-Landmarks-800x600.jpg';"
onmouseout="this.src=http://7606-presscdn-0-74.pagely.netdna-cdn.com/wp-content/uploads/2016/03/Dubai-Photos-Images-Oicture-Dubai-Landmarks-800x600.jpg';" />
</body>
</html>
Use CSS transitions with the transition-delay property.
.classname {
width: 100px;
height: 100px;
background-color: red;
transition-property: background-color;
transition-delay: 1s;
transition-duration: 0.1s;
}
.classname:hover {
transition-delay: 0s;
background-color: blue;
}
.image {
width: 142px;
height: 162px;
background-image: url('http://www.freedigitalphotos.net/images/img/homepage/87357.jpg');
background-size: 100% 100%;
transition-property: background-image;
transition-delay: 1s;
transition-duration: 0.1s;
}
.image:hover {
transition-delay: 0s;
background-image: url('http://7606-presscdn-0-74.pagely.netdna-cdn.com/wp-content/uploads/2016/03/Dubai-Photos-Images-Oicture-Dubai-Landmarks-800x600.jpg')
}
<div class="classname"></div>
<div class="image"></div>
Change your onmouseout event to call a JS function with setTimeout
setTimeout(function(){
this.src= "...";
}, 5000);
Where 5000 is the time in milliseconds you want to delay.
You could just use CSS transitions.
.button {
background-color: #222;
color: #fff;
padding: 14px 36px;
text-decoration: none;
transition: 0.6s background-color ease
}
.button:hover {
background-color: #555;
}
<a href='#' class='button'>Hover me</a>
See this example to change <img> src with onmouseover event and wait 3's then get back to original image onmouseout
//copy original img to variable
var original = $("img")[0].src;
//mouse over event
$("img").mouseover(function() {
$(this).fadeOut("fast").fadeIn("fast");
//change image
$(this)[0].src = "http://7606-presscdn-0-74.pagely.netdna-cdn.com/wp-content/uploads/2016/03/Dubai-Photos-Images-Oicture-Dubai-Landmarks-800x600.jpg";
});
//mouse out event
$("img").mouseout(function() {
var img = $(this);
//on mouse over wait 3 second and getback to original img
setTimeout(function() {
img.fadeOut("fast").fadeIn("fast");
img[0].src = original;
}, 3000);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src='http://www.freedigitalphotos.net/images/img/homepage/87357.jpg' width='142' height='162' />
There is a several ways to do this.
You can try the snippet below:
<div>
<img src='http://7606-presscdn-0-74.pagely.netdna-cdn.com/wp-content/uploads/2016/03/Dubai-Photos-Images-Oicture-Dubai-Landmarks-800x600.jpg' width='142' height='162'/>
<img src='http://www.freedigitalphotos.net/images/img/homepage/87357.jpg' width='142' height='162'/>
</div>
div{
width:142px;
height:162px;
overflow: hidden; /*required*/
}
div img{
position: absolute;
transition: opacity .5s ease;
transition-delay: .5s; /*time of transition that you want*/
}
div img:hover{
opacity: 0;
}
Another way is just use a background of this images and manage each one.
Full example: jsbin
So I got this slideshow code working, where when you click an image, it fades into another image. However, if, for example, there was a vertical orientated image with empty space on its right, if you click that space the whole slideshow kind of glitches out.
Here's my website where you can test it out:
http://danielshultz.github.io
The code:
$(document).ready(function() {
$.fn.nextOrFirst = function (selector) {
var next = this.next(selector);
return (next.length) ? next : this.prevAll(selector).last();
};
$("#cf2 img").click(function() {
$(this)
.removeClass('visible')
.nextOrFirst()
.addClass('visible');
});
});
CSS:
#cf2 {
position:relative;
height:281px;
width:450px;
margin:0 auto;
}
#cf2 img {
position:absolute;
left:0;
max-height: 600px;
max-width: 600px;
opacity: 0;
z-index: 0;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
#cf2 img.visible {
opacity: 1;
z-index: 1;
}
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cf2" class="shadow">
<img class="visible" src="http://static.ddmcdn.com/gif/storymaker-best-hubble-space-telescope-images-20092-514x268.jpg" alt="1"/>
<img src="http://economictimes.indiatimes.com/thumb/msid-45891755,width-640,resizemode-4/nasas-images-of-most-remarkable-events-you-cant-miss.jpg" alt="2"/>
<img src="http://i.dailymail.co.uk/i/pix/2013/11/03/article-2486855-192ACC5200000578-958_964x682.jpg" alt="3"/>
<img src="http://mstatic.mit.edu/nom150/items/199-HybridImage.jpg" alt="4"/>
</div>
If i understood, the problem here is when you click outside the image but inside the square of the previous image, then the slide does not change.
This approach, makes no changes in yout javascript but changes the html and some selectors.
In the example below, I wrapped each <img> into a '<div>' and changed the selectors to match with those divisions. Minor stylings too.
So, if you click outside the image but over the div, the slide changes as expected.
$(document).ready(function() {
$.fn.nextOrFirst = function (selector) {
var next = this.next(selector);
return (next.length) ? next : this.prevAll(selector).last();
};
$("#cf2 div.holder").click(function() {
$(this)
.removeClass('visible')
.nextOrFirst()
.addClass('visible');
});
});
body {
font-family: verdana;
font-size: 8pt;
color: #000;
}
#cf2 {
position: relative;
height: 600px;
width: 600px;
margin: 0 auto;
}
#cf2 div.holder {
position: absolute;
left: 0;
height: 600px;
width: 600px;
opacity: 0;
z-index: 0;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
#cf2 div.holder img {
max-height: 600px;
max-width: 600px;
}
#cf2 div.holder.visible {
opacity: 1;
z-index: 1;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<td valign="center">
<div id="cf2" class="shadow">
<div class="holder visible">
<img src="//danielshultz.github.io/Images/Cute-Door-1.jpg" alt="1"/></div>
<div class="holder"><img src="//danielshultz.github.io/Images/Cute-Door-2.jpg" alt="2"/></div>
<div class="holder"><img src="//danielshultz.github.io/Images/Cute-Door-3.jpg" alt="3"/></div>
</div>
</td>
</table>
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.
Need help with a javascript on a button to trigger these transformations like a slider 1,2,3 and alternate back and forth. Like on the apple website for iPhone features slider. Anyone?
The HTML:
<div id="anima-slide1">
<div class="anima-text-slide1">Genuinity comes at a price.<br>
<font color="#f06">Will you pay it?</font></div>
<div class="anima-image-slide1"><img src="img/lowrider1.png" width="250" height="250"> </div>
</div>
<div id="anima-slide2">
<div class="anima-text-slide2">Genuinity comes at a price.<br>
<font color="#f06">Will you pay it?</font></div>
<div class="anima-image-slide2"><img src="img/lowrider1.png" width="250" height="250"> </div>
</div>
<div id="anima-slide3">
<div class="anima-text-slide3">Genuinity comes at a price.<br>
<font color="#f06">Will you pay it?</font></div>
<div class="anima-image-slide3"><img src="img/lowrider1.png" width="250" height="250"> </div>
</div>
The CSS: (Same for 2 and 3)
.anima-text-slide1 {
margin-top:10px;
position:absolute;
font-family: 'BebasRegular';
color:#FFF;
font-size:40px;
}
.anima-text-slide1 {
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 0;
-webkit-transform: translate(-497px, 0px) rotate(0deg);
}
.anima-image-slide1 {
position:absolute;
left: 610px;
top: 0px;
}
.anima-image-slide1 {
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 0;
-webkit-transform: translate(497px, 0px) rotate(0deg);
}
By adding a class name you can create several animation steps. Using jQuery makes it a lot easier to change the class names on the target element. You can apply this technique to your particular situation.
<div class="container">
Hello
</div>
Frame 1
Frame 2
JS:
function setFrame(frameName) {
$('.container').addClass(frameName);
}
CSS:
.container {
font-size:24px;
}
.frame1 {
font-size:48px;
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 20;
-webkit-transform: translate(200px, 0px) rotate(0deg);
}
.frame2 {
font-size:64px;
color:#ff0000;
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 20;
-webkit-transform: translate(0px, 150px) rotate(30deg);
}
EDIT:
So if you want to do multiple elements you can do something like this:
.containerA .frame1 {
...
}
.containerB .frame1 {
...some different style...
}
Then:
function setFrame(frameName) {
$('.containerA').addClass(frameName);
$('.containerB').addClass(frameName);
}