CSS rotate and translate transform give unexpected results - javascript

I've checked CSS-TRICKS and any other site Google offered me up to page two of their list of links, so my only assumption is I'm misunderstanding how this works or doing it wrong.
What I want is for an image to slide in from its current position to the absolute center of the page. As it slides, I want it to rotate at its center, spinning like a perfectly-balanced wheel. As it slides and rotates, I want it to appear to come towards the user. I want to do this while still keeping the image flat and unskewed.
What it does instead is rotate the image clockwise around and down back towards the left side of the page and off of it.
Here's my code (borrowed from animate.css and changed to suit my needs):
#-webkit-keyframes rotOutZm {
0% {
-webkit-transform-origin: center;
transform-origin: center;
opacity: 1;
}
100% {
-webkit-transform-origin: center;
transform-origin: center;
-webkit-transform: rotate3d(0, 0, 1, 90deg) scale3d(3, 3, 3) translate3d(100% ,100% ,0);
transform: rotate3d(0, 0, 1, 90deg) scale3d(3, 3, 3) translate3d(100% ,100% ,0);
opacity: 0;
}
}
#keyframes rotOutZm {
0% {
-webkit-transform-origin: center;
transform-origin: center;
opacity: 1;
}
100% {
-webkit-transform-origin: center;
transform-origin: center;
-webkit-transform: rotate3d(0, 0, 1, 90deg) scale3d(3, 3, 3) translate3d(100% ,100% ,0);
transform: rotate3d(0, 0, 1, 90deg) scale3d(3, 3, 3) translate3d(100% ,100% ,0);
opacity: 0;
}
}
.rotOutZm {
-webkit-animation-name: rotOutZm;
animation-name: rotOutZm;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
Currently, my code does not take into account the starting point of the image, which will be wrong/messy when I have a row of images. Is there a way to dynamically figure from their starting locations, if they need to slide up to the center, slide down to the center, etc? I'm pretty sure this is a job for JavaScript or jQuery but I'm not sure how to code that.
Am I simply expecting too much of the animation functions? Should I simplify my design to not do this due to complexity?
EDIT: Here is a JSFiddle showing the code in action. It's an image with a small delay to the animation so you can see the image and then watch how it animates to see my problem. My apologies for not providing this sooner.
JSFiddle

Sure you can do it:
FireFox Live example
#keyframes rotOutZm {
100% {
margin: -50px; /* image is 100x100px size so... */
transform: translate3d(50vw, 50vh, 0) scale(3) rotate(360deg);
opacity: 0;
}
}
.rotOutZm {
transform-origin: center;
animation: rotOutZm 2s forwards 0.5s;
}
P.S: Expand the above also for -webkit- and other vendor prefixes
vw and vh are the Viewport sizes. 50vh is half the viewport height
Note that is extremly important the order you place your stack of transform, i.e: if you move translate3d to the end or the transform rule you might get unwanted results.

Related

Activating the animation of one part of a page by clicking an image in another part

After sifting through a bunch of forums and questions on stackoverflow, it seems to me that using JavaScript is a unavoidable here. I have successfully implemented an animation of a list on my site, but I would like the animation to only play after an image has been clicked (and then to close it by clicked again).
This is the animation:
.scale-in-hor-left { -webkit-animation: scale-in-hor-left 1.2s cubic-bezier(0.19, 1, 0.22, 1) both;
animation: scale-in-hor-left 1.2s cubic-bezier(0.19, 1, 0.22, 1) both;
}
#-webkit-keyframes scale-in-hor-left {
0% {
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
opacity: 1;
}
100% {
-webkit-transform: scaleX(1);
transform: scaleX(1);
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
opacity: 1;
}
}
#keyframes scale-in-hor-left {
0% {
-webkit-transform: scaleX(0);
transform: scaleX(0);
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
opacity: 1;
}
100% {
-webkit-transform: scaleX(1);
transform: scaleX(1);
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
opacity: 1;
}
}
And the image I would like to activate it has nothing special going on
<img id="imagename" src="#" height="#" />
I know the JavaScript looks something like this:
function ani(){
document.getElementById('imagename').className ='scale-in-hor-left';
}
But every time I try some HTML to use the two together, I just end up with a button or nothing, and I have yet to get the animation to stop before the click. (Also, will successfully getting the onclick to work ensure that the animated element is invisible before activation based n the 0%s in the CSS?)
You are right in thinking that you'll want to control the animation with a click event handler; otherwise, as you're seeing, your CSS animation kicks off immediately.
As written, your ani() function will only add your animation class to your target "list" element. You will need to toggle the class name on 'click' to alternately add or remove it. To do that, the event handler needs to determine which action to take.
Assuming that you're attempting to accomplish this in vanilla JavaScript (that is, you aren't using a library like jQuery — which has a .toggleClass() method of its own), you can use the presence of the class name itself to determine this…
var
CLASSNAME_TOGGLE = 'toggle-class',
el_trigger = document.getElementById('trigger'),
el_target = document.getElementById('target');
function toggleClass(event) {
event.preventDefault();
if (el_target.classList.contains(CLASSNAME_TOGGLE)) {
// remove the class
el_target.classList.remove(CLASSNAME_TOGGLE);
} else {
// add the class
el_target.classList.add(CLASSNAME_TOGGLE);
};
}
el_trigger.addEventListener('click', toggleClass, false);
#target {
/* this would be your list's default styles */
padding: 20px;
margin: 20px;
border: 1px solid #fbb;
background: #fee;
}
#target.toggle-class {
/* this would be your list's animation */
border-color: #bfb;
background: #efe;
}
<div id="target">
Your "List" Element [the target of the toggled class]
</div>
<img id="trigger" src="https://via.placeholder.com/300x50?text=Your+Trigger+Image" />
If your okay with using jquery then:
https://api.jquery.com/click/
$("#imagename").click(function() {
$("#imagename").addClass("scale-in-hor-left");
});
Or with vanilla javascript:
document.getElementById("imagename").addEventListener("click", ani); // This calls your function ani

css keyframe transition best way to do

Right now I am using Rico St.Cruz brillant working query.transit library but now I have to change some things to do with classes instead though not being this firm in CSS transitions. I tried to
replace:
JS:
$("#target_element").mouseenter( function() {
$("#arr_left")
.transition( { x: 3 }, 300, 'easeOutSine' )
.transition( { x: 0 }, 300, 'easeInSine' );
};
}
with:
JS:
$("#target_element").mouseenter( function() {
$("#arr_left").addClass('hint');
}
CSS:
#arr_left.hint {
-webkit-animation: hint_left 600ms;
-moz-animation: hint_left 600ms;
-o-animation: hint_left 600ms;
animation: hint_left 600ms;
}
#keyframes hint_left {
0%, 100% {
-webkit-transform: translate(0);
-moz-transform: translate(0);
-o-transform: translate(0);
transform: translate(0);
-webkit-animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1); /* easeOutSine */
animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1);
}
50% {
-webkit-transform: translate(3px);
-moz-transform: translate(3px);
-o-transform: translate(3px);
transform: translate(3px);
-webkit-animation-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715); /* easeInSine */
animation-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715) ;
}
}
but this new code does not work.
1) What I am doing wrong here?
2) What is the shortest code (browser compatible) to reach this?
Addition: I’d like to keep the "hint" class generic to address via JS with each arrow has a specific own translation property. Thanks so much in advance!
EDIT:
http://jsfiddle.net/bg7w6jmh/61/
I added a fiddle. Note: I need the extra container for the arrow because it’s animated (rotated) in other places.
The aim is to make the little arrow smoothly move to the left 3px and back in to indicate the target_element being animated on click or swipe. For the values and easing see the keyframes. Thanks for help!
Happens to be ok now. While I was working endlessly on my fiddle I recognized that I missed a round bracket at the end of my event declaration…

Css animations firing twice and "blinking" in firefox

I'm having a bit of an issue using some css animations in firefox. I am using them to slide in some radio buttons when the user clicks a button. In chrome everything seems to be fine but in firefox they kind of look like they are firing the animation twice (the second one slightly over the first one). I've tried a few things and can't seem to solve this problem. Here's what I'm doing :
$(document).on("click", ".addLesson", function(){
$(".contentList").addClass("fadeOutRight");
$(".contentList").hide();
$(".lessonOptions").addClass("fadeInLeft");
});
$(document).on("click", ".lessonCancel", function(){
$(".contentList").removeClass("fadeOutRight");
$(".contentList").addClass("fadeInLeft");
$(".contentList").show();
$(".lessonOptions").removeClass("fadeInLeft");
$(".lessonOptions input[type='radio']").removeAttr("checked");
});
And I'm just using animate.css styles for the animations themselves -
.fadeInLeft
-webkit-animation: fadeInLeft 1s forwards
animation: fadeInLeft 1s forwards
#-webkit-keyframes fadeInLeft
0%
opacity: 0
-webkit-transform: translate3d(-100%, 0, 0)
transform: translate3d(-100%, 0, 0)
100%
opacity: 1
-webkit-transform: none
transform: none
#keyframes fadeInLeft
0%
opacity: 0
-webkit-transform: translate3d(-100%, 0, 0)
transform: translate3d(-100%, 0, 0)
100%
opacity: 1
-webkit-transform: none
transform: none
.fadeOutRight
-webkit-animation: fadeOutRight 1s
animation: fadeOutRight 1s
#-webkit-keyframes fadeOutRight
0%
opacity: 1
100%
opacity: 0
-webkit-transform: translate3d(2000px, 0, 0)
transform: translate3d(2000px, 0, 0)
#keyframes fadeOutRight
0%
opacity: 1
100%
opacity: 0
-webkit-transform: translate3d(2000px, 0, 0)
transform: translate3d(2000px, 0, 0)
I think maybe I'm making the javascript and css fight against each other, but I'm not to sure because it works fine in chrome.
I also noticed when I mouse over the lessOptions div I'm sliding in (after it's entered the stage) it flickers or blinks.
I would appreciate any help on this, thanks for reading!!
Pen here - http://codepen.io/anon/pen/IkhGp
So for me, this problem occurred because I had an animation that lasted .5s, and a transition: all 1s; as well on my animated elements, and this was causing the animation to fire twice. Removing the transition and leaving the animation alone fixed the issue for me.
A while since this was posted but I came looking after having the same issue. For me seems to be an issue for me only when developer tools are open. Close the tools and refresh and the animation was playing correctly.

Countdown timer css analysis

I'm trying to learn more about front end web dev and trying to see the page sources of different cool elements i find on the web. I came across this and was trying to understand how they did the css for the countdown. I only understand parts of the html and I've found where they keep the example:
<div class="countdown-container" id="main-example">
it would be much clearer if i was able to reproduce it in jsfiddle but i can't. Any insight is appreciated.
To achieve this "flip-down" effect you can use css animations or transitions.
Here's a quick look at how to do it with css animations(minus the styling). Transitions will work similarly, but will require a change in state(such as :hover).
#-webkit-keyframes flip-top {
0% {
transform: rotateX(0deg);
transform-origin: 50% 100%;
}
50% {
transform: rotateX(-90deg);
}
100% {
transform: rotateX(-90deg);
transform-origin: 50% 100%;
}
}
#-webkit-keyframes flip-bottom {
0% {
transform: rotateX(-90deg);
transform-origin: 100% 0%;
}
50% {
transform: rotateX(-90deg);
}
100% {
transform: rotateX(0deg);
transform-origin: 100% 0%;
}
}.top.curr {
z-index: 1;
-webkit-animation: flip-top 2s ease-in infinite;
}
.top.next {
z-index: 0;
}
.bottom.curr {
z-index: 0;
}
.bottom.next {
z-index: 1;
-webkit-animation: flip-bottom 2s ease-out infinite;
}
Here's an example to play around with: plnkr
note: I only prefixed for chrome, so you should open it with chrome or add additional prefixes.

Javascript, Jquery or css3 oscilating letter animation

i'm new in javascript and especially in animation. The challenge for me is to make a letter oscilate back and forth max 30 degrees from the sides. The picture i uploaded is an example of the the animation, the letter will move from the upper right corner or from the pin but i think that is harder.
I need some guidance into this if anyone can help please reply.
Thanks in advance
because i'm new i cannot post images so here is the link: http://i.stack.imgur.com/byzUC.png
Well, this took far longer than I care to admit, and is only reliable in (from my own limited testing) Chromium 12+ and Firefox 5+ on Ubuntu 11.04 (it does not work in Opera 11). That being the case I'll show only the excerpts to cover Firefox and Chromium, though the linked JS Fiddle has vendor prefixes to at least try with Opera (even if it fails). Using the following mark-up:
<img src="http://i.stack.imgur.com/byzUC.png" id="envelope" />
The following CSS produces an (infinitely) oscillating envelope for you to adjust to your preferences:
#envelope {
-webkit-animation-name: oscillate;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: 10;
-webkit-animation-direction: infinite;
-moz-animation-name: oscillate;
-moz-animation-duration: 10s;
-moz-animation-iteration-count: 10;
-moz-animation-direction: infinite;
}
#-webkit-keyframes oscillate {
0% {
-webkit-transform: rotate(0deg);
-webkit-transform-origin: 108px 23px;
}
33% {
-webkit-transform: rotate(15deg);
-webkit-transform-origin: 108px 23px;
}
100% {
-webkit-transform: rotate(-20deg);
-webkit-transform-origin: 108px 23px;
}
}
#-moz-keyframes oscillate {
0% {
-moz-transform: rotate(0deg);
-moz-transform-origin: 110px 26px;
}
33% {
-moz-transform: rotate(15deg);
-moz-transform-origin: 110px 26px;
}
100% {
-moz-transform: rotate(-20deg);
-moz-transform-origin: 110px 26px;
}
}
JS Fiddle demo.
Given the spectacular failure rate of this approach, though (it certainly doesn't work in Opera 11, and I can only imagine that it achieves nothing in IE...) I'd strongly suggest an animated gif for the sheer simplicity and cross-browser compliance.

Categories

Resources