CSS3 Animating full page container with several children causes lag - javascript

Whenever I try to animate my container (described below), I'm often experiencing some lag (like choppy movement) of the container. I've made some re-search and tried some stuff, but haven't found a solution. The only thing I did found out tho, was that if I remove all images but one, everything works smooth.
So by eliminating all the images, and just having one there, solves the issue. But I need all the images.. the functionality is a slideshow actually (regular fade transition of images).
Please take a look at my setup, and notice me if I'm doing any bad things here (currently only for WebKit):
<div id="container">
<div id="inner">
<div class="image"></div>
<div class="image"></div>
<div class="image"></div>
[...]
</div>
</div>
With the CSS:
#container {
width:100%;
height:100%
position:absolute;
-webkit-transform: translate3d(0,0,0);
-webkit-transition: -webkit-transform 800ms linear;
-webkit-backface-visibility: hidden;
-webkit-transform-style: preserve-3d; /* *should* improve performance? */
}
#inner {
position:relative;
width:100%;
height:100%;
}
.image {
position:absolute;
left:0;
top:0;
background-image:[something];
width:100%;
height:100%;
background-size:cover;
}
Then I just do a couple of these in my code to make the container move around
$('#container').css('-webkit-transform', 'translate3d(0,500px,0)');
Thanks in advance!
EDIT: Here's a fiddle btw (remember that the result-window is very small here, which gives me nice smoothness. But in full-screen, its a bit choppy)
EDIT2: Fixed the broken fiddle!

In this case, you have a lag probably because you are moving the container with all of the images (and these images are big). The browser need to calculate new positions for every DOM element that are change the position and move it (that mean redraw all of these big images) in all steps of animation.
If you move only one DOM element with image the animation should be smooth:
$('.image').css('-webkit-transform', 'translate3d(0,500px,0)');
here you have a fsfidde that move only one DOM element.

Animation lags are often in such cases, because of overload. Maybe you should do some images preload.
Just like it is shown here
And full manual here

Related

How is the scroll effect on the iphone 11 site built?

site - https://www.apple.com/iphone-11-pro/
I feel like I this is such a simple effect but I can't seem to wrap my head around how to achieve it. ( I am talking about the way elements are layered behind each other )
I figured it was some mix of position:fixed/sticky but I don't see how that is possible without a bunch of height: ~100vh etc and I hope that isnt how the effect is achieved on their site...
I don't even know what the proper name of this effect is to google it.
If anyone has any resources I could read up on or videos to watch, id greatly appreciate it.
Thank you.
I would use position: absolute for both objects and declare their z-index order to show based on which layer is up-front.
I also see an overflow:hidden style a lot whenever you want to place an element's extra pixels away or behind other elements.
#b1 {
background-color:red;
height:100px;
width:100px;
display:table;
position: absolute;
z-index:1;
}
#b2 {
background-color:blue;
height:100px;
width:100px;
display:table;
position: absolute;
left:50px;
top:50px;
z-index:2;
}
<div id="b1"></div>
<div id="b2"></div>
AOS is a jquery library for on scroll animations
an example of usage
<div data-aos="fade-up"
data-aos-duration="2000">
</div>
The site explains as your scroll.
some nice tutorials keithclark, codepen , w3schools

How do I change an element with transition with jQuery when hovering on another element?

So I have a list of 9 icons with titles representing 9 different areas of service. Divided into three rows of three using floats etc. Each has a description below it (a couple of paragraphs). I have used 'visibility: hidden' and 'height: 0px' to hide the descriptions. (not at the same time.) I want to hover or mouseover the icon and have the description appear below it.
I don't think I can use straight CSS (unless someone thinks otherwise) because I am triggering one element and changing another.
<div id="category1" class="category_col1 cathead">
<div><img src="images/..." name="category1" class="image-item-lead"/>
<h3>Type of category</h3>
</div>
<div id="category1description" class="hide">
<p>Some content...</p>
<p>Some more content...</p>
</div>
</div>
And we do that two more times per row.
The CSS that is applied to these elements is as follows.
.category_col1 {float:left;
clear:left;
width:32%;
padding:.5em .5em .5em 0em;
}
.image-item-lead {width: 90%;
margin-left:auto;
margin-right:auto;
display:block;
}
.cathead {visibility:visible;
}
.hide {height:0px;
overflow:hidden;
}
The jQuery that I have tried is as follows:
Surrounding all options
$(document).ready(function(){
});
This works:
$('#category1').mouseover(function(event){
$(#category1description).css('height','auto');
});
But obviously it shows up instantly, I would like it to show up gradually.
I have tried:
$('#category1').mouseover(function(){
$('#category1descrioption').slideToggle('slow');
});
$('#category1').mouseover(function(){
$('#category1descrioption').animate({height: auto}, {duration:1500});
});
$('#category1').mouseover(function(event){
$('#category1descrioption').transition({height: auto}, ease, 1500);
});
I am definitely missing something here. I hope someone can help.
All CSS:
.category_col1:hover .hide {
height: 100px;
}
.hide {
height:0px;
overflow:hidden;
transition: height 1.5s;
}
caveat: The set height is due to auto not being supported. If auto is used, the effect is instantaneous instead of transitioned, this is part of the spec. Figure out what height you will need, and use that length value.
Option 2 is to use max-height for height:auto; :
How to animate height from 0 to auto using CSS Transitions article from bradshawenterprises.com
and
SO question CSS transition height: 0; to height: auto;
One way or another, you will have to make some decision on how to deal with height, as the max height method will have some animation timing issues that could lead to big delays on the hover-off if some are small heights, and some are large as the max-height value will determine the animation time. See the comments in the accepted answer.
Option 3: Figure out height of each div with JS/jQuery and set using an event listener for hover

Can I blur the entire site except for some items

We have a large application where we want to blur the entire site except for a few items during a walkthrough. As if it is an overlay.
We have explored things such as:
1. Apply blur to the body, but that means all underlaying items will be blurred.
2. Using html2canvas to create a copy in a canvas, however this is too performance intensive.
We can not do large dom manipulations nor heavy jQuery use due to our clients being on slow machines often without graphics cards and the size of the application.
Any suggestions?
Edit: I should also add that we only require it to work in webkit browsers.
Yeah you can do this with a plugin name Foggy..
Check this...It will help you
Simply toggle a blur class. See JSFiddle.
<style>
.blur {
opacity: 0.4;
}
.blur p {
text-shadow: 0px 0px 10px rgba(0, 0, 0, 0.9);
color: rgba(0, 0, 0, 0);
}
.blur img {
-webkit-filter: blur(3px);
filter: blur(3px);
}
</style>
<script>
$(function(){
$('.box').hover(function () {
$('.box').addClass('blur');
$(this).removeClass('blur');
});
});
</script>
<div class="box blur">
<p>A</p>
<img src="example.png">
</div>
<div class="box">
<p>B</p>
</div>
Source: http://tympanus.net/Tutorials/ItemBlur/
I might be missing the point here, but if you ONLY require support for webkit browsers, then why not just use the -webkit-filter:
nav, header, main, footer {
-webkit-filter: grayscale(1) blur(5px);
}
*:hover {
-webkit-filter: none;
}
It's pretty responsive for me on my old MacBook Pro and the cool thing is that you have so many options to add grayscale, adjustments for brightness, saturation, contrast, opacity, etc. And, it would be fairly simple and lightweight to script a demo in jQuery for your walkthrough, since all you would need to do is remove or add the -webkit-filter to your desired elements.
DEMO >
(I just reused a Bootply I had as an example since it had a fair amount of content).
I'm not sure what your browser requirements are, or how archaic the technology you're developing for is, but you might check out blur.js I could see it not being too heavy, dependent on how much content you have.
Worst case you could probably put a full-width, full-height div between your active area and the rest of the site using absolute positioning and a z-index, and then run blur on that so that the active area has the appearance of being the only unblurred thing.
I had the same problem.
The only solution I found was to have a transparent layer over the content with a hole in it.
.layer{
position:fixed;
width: 80px;
height: 80px;
top: 20px;
left: 20px;
box-shadow : 0 0 0 1000px red;
opacity: 0.5;
}
http://jsfiddle.net/zLYjA/
It's a good solution if you have a slow machine. But you need to do a bit of work to determine the position of the element you want to show.
i am giving a simple approach for creating a modal.
You can do this by blurring all the items except the items you don't want to be.
Float those items over the blurred ones with higher z-index
for ex:
html:
<div class="blur">../*items to be blured */..</div>
<div class=floated-item">../*items not to be blured */..</div>
CSS:
.blur{
opacity:0.4;
width:100%;
height:100%;
position:fixed;
top:0px;
left:0px;
}
.floated-item{
z-index:999;
position:fixed;
margin-top:10%;
margin-left:10%;
}

Resizing browser causes divs to scroll

I am trying to make a parallax scrolling website and its template is as follows:
HTML
<div id="content">
<div id="container1"></div>
<div id="container2"></div>
<div id="container3"></div>
</div>
CSS
#content {
height:auto
}
#container1, #container2, #container3 {
position:relative;
height:100%;
width:100%;
background-size:cover;
overflow:hidden;
}
#container1 {
background-color:#FF0000;
}
#container2 {
background-color:#000;
}
#container3 {
background-color:#363636;
}
Problem: If you scroll down to either #container2 or #container3 and resize the browser, the website appears to scroll.
I suspect that the height:100%; is causing issue. In particular, resizing causes all three containers to resize, creating a weird offset.
Things I have tried:
Binding the resize event and dynamically changing the height of the divs
Adding a min-height property so that the resize locks after resizing
Hiding the div that is no longer in the view
Is there any simple way of fixing this? The last attempt fixes it, but I feel like there should be a better way rather cluttering my JS file with several .hide() and .show() events.

CSS3 translate out of screen

For a number of projects now I have had elements on the page which I want to translate out of the screen area (have them fly out of the document). In proper code this should be possible just by adding a class to the relevant element after which the css would handle the rest. The problem lies in the fact that if for example
.block.hide{
-webkit-transform:translateY(-10000px);
}
is used the element will first of all fly out of the screen unnecessarily far and with an unnecessarily high speed. And purely from an aesthetic point of view there's a lot left to be desired (Theoretically speaking for example a screen with a height of 10000px could be introduced one day in the future).
(Update) The problem why percentages can't be used is that 100% is relative to the element itself, rather than to the parent element/screen size. And containing the element in a full-sized parent would be possible, but would create a mess with click events. And after a few answers, allow me to point out that I am talking about translations, not about position:absolute css3 transitions (which are all fine, but once you get enough of them they stop being fun).
What aesthetically pleasing solutions to allow an element to translate out of a screen in a fixed amount of time can you guys think of?
Example code can be found in this jsfiddle demonstrating the basic concept.
http://jsfiddle.net/ATcpw/
(see my own answer below for a bit more information)
If you wrap the .block div with a container:
<div class="container">
<div class="block"></div>
</div>
<button>Click</button>
you could expand and then, translate the container itself after the click event
document.querySelector("button").addEventListener("click", function () {
document.querySelector(".container").classList.add("hide");
});
with this style
.block {
position:absolute;
bottom:10px;
right:10px;
left:10px;
height:100px;
background:gray;
}
.container {
-webkit-transition: -webkit-transform ease-in-out 1s;
-webkit-transform-origin: top;
-webkit-transition-delay: 0.1s; /* Needed to calculate the vertical area to shift with translateY */
}
.container.hide {
position:absolute;
top:0;
left:0;
bottom:0;
right:0;
/* background:#f00; /* Uncomment to see the affected area */
-webkit-transform: translateY(-110%);
}
In this way, it is possible to apply a correct translationY percentage ( a little more than 100%, just to have it out of the way ) and mantaining the button clickable.
You could see a working example here : http://jsfiddle.net/MG7bK/
P.S: I noticed that the transition delay is needed only for the transitionY property, otherwise the animation would fail, probably because it tries to start before having an actual value for the height. It could be omitted if you use the horizontal disappearing, with translateX.
What I did is use the vh (view height) unit. It's always relative to the screen size, not the element itself:
/* moves the element one screen height down */
translateY(calc(100vh))
So if you know the position of the element in the screen (say top:320px), you can move it exactly off the screen:
/* moves the element down exactly off the bottom of the screen */
translateY(calc(100vh - 320px))
I know this is not exactly what you were asking but...
Would you consider using CSS animations with Greensock's Animation Platform? It is terribly fast (it claims it's 20 times faster than jQuery), you can see the speed test here: http://www.greensock.com/js/speed.html
It would make your code nicer I believe, and instead of trying to hack CSS animations you could focus on more important stuff.
I have created a JSFiddle here: http://jsfiddle.net/ATcpw/4/
Both CSS and possible JS look simpler:
document.querySelector("button").addEventListener("click",function(){
var toAnimate = document.querySelector(".block");
TweenMax.to(toAnimate, 2, {y: -window.innerHeight});
});
CSS:
.block{
position:absolute;
bottom:10px;
right:10px;
left:10px;
height:100px;
background-image: url(http://lorempixel.com/800/100);
}
I recently built an app which used precisely this technique for sliding 'panels' (or pages) and tabs of the application in and out of view. A basic implementation of the tabs mechanism can be seen here.
Basically (pesudo-code to illustrate the concept, minus prefixes etc):
.page {
transform: translateY(100%);
}
.page.active {
transform: translateY(0%);
}
The problem I had was that Android Webkit in particular wouldn't calculate percentage values correctly. In the end I had to use script to grab the viewport width and specify the value in pixels, then write the rules using a library for dynamic stylesheet parsing.
But eventually, and in spite of only these minor platform-specific problems, this worked perfectly for me.
Use calc method (http://jsfiddle.net/ATcpw/2/):
.block{
position:absolute;
top: -webkit-calc(100% - 110px);
right:10px;
left:10px;
height:100px;
background:gray;
-webkit-transition: all 2s;
/*this adds GPU acceleration*/
transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);
}
.block.hide{
top: -100px;
}
Since you are using -webkit prefix I used it as well.
calc is supported by majority of browsers: http://caniuse.com/#search=calc
One very simple, but not aesthetically pleasing solution is to define the class dynamically:
var stylesheet = document.styleSheets[0];
var ruleBlockHide;
and
//onresize
if(ruleBlockHide) stylesheet.deleteRule(ruleBlockHide);
ruleBlockHide = stylesheet.insertRule('.block.hide{ -webkit-transform:translateY(-'+window.innerHeight+'px); }',stylesheet.cssRules.length);
see: http://jsfiddle.net/PDU7T/
The reason a reference to the rule needs to be kept is that after each screen resize the rule has to be deleted and re-added.
Although this solution gets the job done, there has to be some DOM/CSS combination which would allow this to be done without javascript (something along the lines of a 100%x100% element containing such a block, but I haven't been able to figure out any transform based way).
get the document width. then use a java script trigger to trigger the css3 translation.
function translate(){
var width = document.body.Width;
document.getElementById('whateverdiv').style='translateX(' + width + 'px)';
}
This is simple
add the following to your div
.myDiv {
-webkit-transition-property: left;
-webkit-transition-duration: 0.5s;
-webkit-transition-timing-function: ease-in-out;
-webkit-transition-delay: initial
}
then change the "left" property of it either by adding an additional class or by jQuery
This will animate it along the x-axis
Note: you can change the -webkit-transition-property to any property you want and this will animate it

Categories