I am working on making a simple sliding panel in AngularJS using ng-animate. This works fine in Chrome, but in FireFox the animation is very inconsistent. It could be due to Transitions support in Gecko. It almost seems like a action queue problem. Because you can interrupt the show/hide and have the animation execute, but then it will pop into place at random moments.
Why is this inconsistency occurring?
Can this be corrected, and if so, is there an elegant cross browser fix?
JS Fiddle:
http://jsfiddle.net/7SwST/11/
Angular:
var app = angular.module('myApp', []);
app.controller('sidePanel', ['$scope', '$rootScope', '$timeout', '$animation', function($scope, $rootScope, $timeout, $animation) {
$scope.showMe = false;
$scope.hideMe = function() {
$scope.showMe = false;
}
$scope.$on('showPanel', function() {
$scope.showMe = true;
});
$scope.showPanel = function() {
$rootScope.$broadcast('showPanel');
};
}]);
CSS:
.side-panel { position: relative; display: block; border: 2px solid #000; } /* left: -50px; overflow: visible; */
.side-panel div { width: 210px; height: 180px; background-color: #ffcc00; }
.animate-show,
.animate-hide {
-webkit-transition: 550ms linear all;
-moz-transition: 550ms linear all;
-ms-transition: 550ms linear all;
-o-transition: 550ms linear all;
transition: 550ms linear all;
position: relative;
display: block;
}
.animate-show.animate-show-active,
.animate-hide { left: 0; }
.animate-hide.animate-hide-active,
.animate-show { left: -500px; }
Related
So I was experimenting with css filter, the experiment worked quite well but not in Firefox.
I wanted to apply a filter onto a segment of the background image. The idea was to fix the background image of the wrapper and the inner elements to create the illusion that the filter is applying only to a certain area and can be moved, here with scrolling.
This is what I tried:
html,
body {
width: 100%;
height: 100%;
}
body {
margin: 0px;
height: 200%;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column
}
body,
div {
background-image: url("https://i.imgur.com/wu7EkAX.jpg");
background-attachment: fixed;
}
div {
filter: saturate(0%);
width: 50%;
height: 40%;
}
<div></div>
<div></div>
This works quite well with Chrome (and I think also in other browsers) but not with Firefox. It seems like it is a result of some optimization which misbehaves.
If you scroll with your mousewheele and then click, it refreshes, otherwise it stays in this state (at least if you run it standalone).
The "solution" is quite simple, you force Firefox to re render, there are whole posts about this topic but here are two of my approaches:
With a css animation
#keyframes renderFix {
from {
outline-color: red;
}
to {
outline-color: blue;
}
}
html {
outline: 1px solid red;
animation: 1s infinite alternate renderFix;
}
With some JavaScript
{
let html, s = false,
cycle = function () {
html.style.outlineColor = s ? "red" : "blue"
s = !s;
window.requestAnimationFrame(cycle)
}
window.requestAnimationFrame(function () {
html = document.body.parentElement
html.style.outlineStyle = "solid";
html.style.outlineWidth = "1px";
cycle()
})
}
The JavaScript fix applied:
{
let html, s = false,
cycle = function () {
html.style.outlineColor = s ? "red" : "blue"
s = !s;
window.requestAnimationFrame(cycle)
}
window.requestAnimationFrame(function () {
html = document.body.parentElement
html.style.outlineStyle = "solid";
html.style.outlineWidth = "1px";
cycle()
})
}
html,
body {
width: 100%;
height: 100%;
}
body {
margin: 0px;
height: 200%;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column
}
body,
div {
background-image: url("https://i.imgur.com/wu7EkAX.jpg");
background-attachment: fixed;
}
div {
filter: saturate(0%);
width: 50%;
height: 40%;
}
<div></div>
<div></div>
I have a script that as soon as the user starts to scroll a box shadow is added that looks very nice. However, this box shadow is added instantly. I would prefer that it fade in using CSS 3. I have tried creating keyframes that change the opacity from 0 - 1 over 1 second but that doesn't work.
Here is the script I am using:
$(function() {
$(window).scroll(function() {
var top_offset = $(window).scrollTop();
if (top_offset) {
$('.top_head_separator').addClass('fixed-top fade-in');
}
});
CSS:
.fixed-top {
background:#FFFFFF;
box-shadow: 0 7px 15px 4px rgba(0,0,0,0.38);
height: 90px;
overflow: hidden;
position: fixed;
top: 0;
width: 100%;
z-index: 9999;
}
#keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
.fadeIn {
animation-duration: 1s;
animation-fill-mode: both;
animation-name: fadeIn;
}
How do I have the box shadow fade in?
Note: I omitted vendor prefixes in this question but they are in my code.
I think you just have a spelling mistake and a syntax error or two, otherwise you're fine. Two things:
Close both functions in your jQuery.
Your CSS mentions fadeIn, but jQuery had fade-in
Here's the new, fixed jQuery code:
$(function() {
$(window).scroll(function() {
var top_offset = $(window).scrollTop();
if (top_offset) {
$('.top_head_separator').addClass('fixed-top fadeIn'); // <<<< "fadeIn"
}
}); // <<<< ADDED
});
See this -webkit- demo for a working example.
http://dev.viral-minds.com/miller/abc/abc.html
two questions about this
How do I keep the green block from "blinking" at the beginning when the page loads?
The animation only works on chrome at the moment...how to get it to work in FF and IE?
thanks.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
<style type="text/css">
body
{
background-color:#FFFFF0; /*ivory*/
overflow: hidden;
}
#box
{
position: absolute;
width:495px;
height:263px;
background:#32331d;
top: 20px;
left: 20px;
}
#nav
{
position: absolute;
margin-left:30px;
width:100%;
height:100px;
top: 425px;
z-index: 100;
background-image:url('colors.png');
background-repeat:no-repeat;
}
#stars,
#stars-2,
#small-stars,
#small-stars-2 {
position: absolute;
top: 50%;
left: 50%;
width: 800px;
height: 800px;
margin: -300px 0 0 -300px;
background: url(stars-large.png) no-repeat center center;
-webkit-animation-name: starsLarge;
-webkit-animation-duration: 240s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
#-webkit-keyframes starsLarge {
from {
-webkit-transform: rotate(0deg) scale(3);
opacity: .9;
}
to {
-webkit-transform: rotate(360deg) scale(.5);
opacity: .5;
}
}
#stars-2 {
-webkit-animation-name: starsLargeAlt;
-webkit-animation-duration: 180s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
#-webkit-keyframes starsLargeAlt {
from {
-webkit-transform: rotate(180deg) scale(3);
opacity: .9;
}
to {
-webkit-transform: rotate(360deg) scale(.5);
opacity: .5;
}
}
#small-stars,
#small-stars-2 {
background: url(stars-small.png) no-repeat center center;
-webkit-animation-duration: 60s;
-webkit-animation-name: starsSmall;
}
#small-stars-2 {
-webkit-animation-name: starsSmallAlt;
-webkit-animation-duration: 120s;
}
#-webkit-keyframes starsSmall {
from {
-webkit-transform: rotate(360deg) scale(3);
opacity: .9;
}
to {
-webkit-transform: rotate(0deg) scale(.5);
opacity: .5;
}
}
#-webkit-keyframes starsSmallAlt {
from {
-webkit-transform: rotate(0deg) scale(3);
opacity: .9;
}
to {
-webkit-transform: rotate(360deg) scale(.5);
opacity: .5;
}
}
</style>
</head>
<body>
<div id="box"><img src="actual.png"></img></div>
<div id="nav"></div>
<div id="stars"></div>
<div id="stars-2"></div>
<div id="small-stars"></div>
<div id="small-stars-2"></div>
</body>
Item 1: The green block flickers because the overlayed image is not retrieved from the server yet. You could add display: none; to the CSS for #box, then programmatically display it after the page has been fully loaded. For example:
// jQuery:
$(document).ready(function(){
$('#box').show();
});
Item 2: The animation only works in Chrome because you are using -webkit specific style definitions. You will need to research alternatives, such as -moz and -ms in order to see if it can work in those browsers. You could also try omitting the prefix altogether.
I. You can change the background color of that div to match the page background. And later, when the image has been loaded, you change it to dark green via jQuery:
$(function() {
$('#box img').load(function() {
$(this).parent().css('background-color', '#32331D');
});
});
II. You have to add browser specific prefixes other than -webkit.
For FF - -moz
For IE - -ms
For Opera - -o
Just keep in mind that those animations won't work in older versions of IE (8 and under) despite the prefixes. Those suckers don't support CSS animations.
http://jsfiddle.net/wX6eU/
The rotation eases in and out even though I don't specify the out parameter. How can I make it stay at 360 or just go back to 0 without any animation?
div {
position: absolute;
left: 100px;
top: 100px;
width: 100px;
height: 100px;
background-color: blue;
-webkit-transition:-webkit-transform 0.5s ease-in;
}
div:hover {
-webkit-transform:rotate(360deg);
}
Just place the transition within the :hover pseudo-selector:
div {
position: absolute;
left: 100px;
top: 100px;
width: 100px;
height: 100px;
background-color: blue;
}
div:hover {
-webkit-transform:rotate(360deg);
-webkit-transition:-webkit-transform 0.5s ease-in;
}
http://jsfiddle.net/DgBDt/
I don't believe it's possible to set the timing on the "out" differently than the "in". The ease-in option is the timing function. Other options are default, linear, ease-out, ease-in-out, and cubic-bezier. You can read more about them here, but there isn't any information on setting the transition-out to zero seconds, unfortunately.
An alternate option might be to use JS to get the functionality you want and still use the CSS animation:
$(function(){
var timer;
$('.animated').hover(function(){
timer = setTimeout(function(){ $('.animated').removeClass('animated') }, 500)
}, function(){
clearTimeout(timer);
$(this).addClass('animated');
});
});
Is it possible to block the UI when using $.mobile.pageLoading(false)?
This feature isn't implemented in jQueryMobile Alpha 1.0a4.1.
I solved the problem adding a overlay div with high enough z-index.
JS:
$(document).ready(function () {
$('body').append('<div id="block-ui"></div>');
$('#ajax_request').click(function(){
$('#block-ui').show();
$.mobile.pageLoading(false);
});
});
CSS:
#block-ui {
display: none;
cursor: wait;
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 9;
background-color: #CCCCCC;
opacity: 0.5;
}
If you're using using fixed-bars you need to override z-index value:
.ui-header-fixed, .ui-footer-fixed {
z-index: 8 !important;
}