TweenLite animation suddenly changing elements' position? - javascript

First of all, you can find a simplified demo of my code in this JSFiddle and also below the question. I found that my problem happens the way I describe it in Google Chrome, so if you plan to try and fix the bug, please use that browser. I apologize if the code is not very well simplified; please consider that this is a snippet from a bigger project.
I'm working on a webapp that uses JQuery and GreenSock's TweenLite for animations.
This app consists on some menus that control everything, that are transitioned between using the bodyChange() function. This function has two parameters:
nextOrPrev, that runs one animation or another based on the value
provided ("next" or "prev"). Only the "next" animation is done yet, but that is not important for now. The "prev" animation, not yet used, just emits an alert("prev").
bodyFunction. The function provided will fill the body with the elements necessary for that menu, and the wrap them in a #bodyWrap.
In the demo I provide you with there are only two menus: The first one, mainMenu, with only a #playButton. When you click it, the bodyChange() function is called with the following parameters: ("next", playSettingsBody), playSettings being the second menu.
This is the problem: when you click the playButton, the button goes up a on the screen and then executes the TweenLite animation. I can't see, however, why does the button "jump up", instead of staying in the same place and execute the animation. This is probably due to a small mistake. What is it?
Thanks for any help.
mainMenuBody();
function mainMenuBody() {
$("body").append(
//BUTTONS
"<div id='playButton' class='mainButton'><div class='buttonText mainButtonText text'>PLAY</div></div>"
);
//WRAP
$("body").wrapInner("<div id='bodyWrap'></div>");
//BINDS
$("#playButton").bind("click", function() {
bodyChange("next", playSettingsBody);
});
}
function bodyChange(nextOrPrev, bodyFunction) {
switch (nextOrPrev) {
case "next":
//ANIMATION AND BODY CHANGE
TweenLite.to($("#bodyWrap"), .4, {
ease: Power2.easeIn,
transform: "rotateY(90deg)",
onComplete: function(){
$("body").empty();
//NEW STUFF
bodyFunction();
TweenLite.from($("#bodyWrap"), .4, {
ease: Power2.easeOut,
transform: "rotateY(90deg)"
});
}
});
//END OF ANIMATION AND BODY CHANGE
break;
case "prev":
alert("prev");
}
}
function playSettingsBody() {
$("body").append(
"<p class='text' id='CYTText'>This is the second menu!</p>"
);
}
body{
background-image: url("../resources/pics/Vignette2.png");
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
background-color: #02BFC1;
overflow:hidden;
margin: 0;
}
.text {
color: #FFFFFF;
font-family:Bebas Neue;
-webkit-user-select: none;
cursor: default;
text-shadow: 3px 3px 2px rgba(0,0,0,0.2);
}
.mainButton {
-webkit-transform:scale(1);
width: 200px;
height: 200px;
border: 10px solid #F1F2F0;
text-align:center;
background-color: #F37C2B;
/*background:#5F4A21;*/
display: table;
position: absolute;
margin: auto;
top: 150px;
bottom: 0;
-webkit-transition: all 0.5s ease;
cursor: pointer;
box-shadow: 0px 0px 30px rgba(0,0,0,0.4);
}
.mainButtonText {
position: relative;
display:table-cell;
vertical-align:middle;
-webkit-transform:scale(1);
font-size: 90px;
text-shadow: 4px 4px 2px rgba(0,0,0,0.2);
-webkit-transition: all 0.5s ease;
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>

This problem is caused in your .mainButton class. Your code looks a little like this.
.mainButton {
position: absolute;
top: 150px;
bottom: 0;
//rest
}
By removing the line bottom: 0; your JSFiddle now works as expected. However, if you remove the line top: 150px; instead and leave in the bottom: 0 the problem still occurs. Unfortunately, I cannot provide an explanation for this. It might be worth posting a question on the GSAP forums inquiring about why this occurs works when positioning using bottom but not when using top
Edit
Since you need bottom: 0 and I wasn't able to fix your code I wrote an example which works using Timeline, a GSAP plugin. You can see this JSFiddle or the code example below.
var tl = new TimelineMax();
tl.pause();
tl.fromTo($("#click"), 1, {rotationY: 0, ease: Power2.easeOut}, {rotationY: 90, transformOrigin:"right", ease: Power2.easeOut})
.set($("#click2"), {css:{display: "table"}}, "-=0.6")
.fromTo($("#click2"), 1, {rotationY: -90, ease: Power2.easeOut}, {rotationY: 0, transformOrigin:"left", ease: Power2.easeOut}, "-=0.6");
$("#click").click(function() {
tl.play();
});
$("#click2").click(function() {
tl.reverse();
});
* {
margin: 0;
padding: 0;
}
body {
background-image: url("../resources/pics/Vignette2.png");
background-repeat: no-repeat;
background-position: center center;
background-attachment: fixed;
background-color: #02BFC1;
overflow: hidden;
}
div.one, div.two {
position: absolute;
bottom: 0;
height: 200px;
width: 200px;
background: #F37C2B;
text-align: center;
display: table;
cursor: pointer;
border: 10px solid #F1F2F0;
}
div.one .text, div.two .text {
position: relative;
display: table-cell;
vertical-align: middle;
color: #FFFFFF;
font-family: Bebas Neue;
font-size: 90px;
}
div.two {
display: none;
border-color: transparent;
background: none;
}
div.two .text {
font-size: 40px;
}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<div id="click" class="one">
<div class="text">
Play
</div>
</div>
<div id="click2" class="two">
<div class="text">
Second Menu
</div>
</div>

Related

Change transition-duration with add/removeClass

I'm trying to make a simple pen with a button. When "on" is pressed the cover should slide and cover "on". When "off" is pressed the cover should cover "off". It works the way I have it, but when I try to add some transition effects nothing works. I tried adding transition-duration: 1s; to every class in the project but no luck.
Here's my codepen.
https://codepen.io/Alex-Iron/pen/eMORVV
My code is this:
HTML
<div id="switch" class="silver-background">
<div id="wrapper">
<div class="silver-background" id="cover">
<div id="cover-inner"></div>
</div>
<div id="on" class="on-left">on</div>
<div id="off">off</div>
</div>
</div>
SCSS
$radius: 7px;
$height: 100px;
$width: $height*1.5;
#switch{
width: $width*2.1;
height: $height*1.2;
display: grid;
position: relative;
}
.silver-background{
border-radius: $radius;
background: silver;
}
#wrapper{
margin: auto;
display: flex;
}
#on, #off, #cover, #cover-inner{
font-size: $height/3;
height: $height;
width: $width;
line-height: $height;
text-align: center;
text-transform: uppercase;
font-family: sans-serif;
}
#on{
background: radial-gradient(green, green, black);
border-radius: $radius 0 0 $radius;
color: lightgreen;
}
#off{
background: radial-gradient(#A00000, #A00000, black);
border-radius: 0 $radius $radius 0;
color: #EC6666*1.3;
}
#cover{
position: absolute;
border: 1px solid black;
width: $width*2.1/2;
height: $height*1.2;
display: grid;
top: 0;
}
#cover-inner{
width: $width*0.9;
background-color: white;
border-radius: $radius;
margin: auto;
}
.on-left{
left: 0;
}
.on-right{
right: 0;
}
My jQuery code.
$("#off").on('click',()=>{
$('#cover').removeClass('on-left');
$('#cover').addClass('on-right');
});
$('#on').on('click',()=>{
$('#cover').removeClass('on-right');
$('#cover').addClass('on-left');
})
I've updated your pen:
https://codepen.io/anon/pen/geOpgz
You should use the transition property of css:
#cover{
...
left: 0;
transition: 1s left;
}
The transition property can be used to animate a property value change. It is important, that your class only changes a property value f.e. left and not switches from left: 0 to right: 0:
#cover.on-left{
left: 0;
}
#cover.on-right{
left: $width;
}
In your case, the new value of your left property on right position is left: $width*2.1 / 2 cause your wrapper has the following width: width: $width*2.1.
By the way, i yould suggest you to use the toggleClass function of jquery:
$("#wrapper").on('click',()=>{
$('#cover').toggleClass('on-right');
});
Now you can click your wrapper on any position and it toggles the "on" and "off" with only one class .on-right and less javascript code:
https://codepen.io/anon/pen/QmWjwb
Your id="cover" should have on-left from start, and then give that #cover property transition: left 0.2s ease and class .on-right should have left: 150px since you cant transition from left: 0 to right: 0.
Here is the updated pen: https://codepen.io/zmuci/pen/JLjdEb

How do I stop an image at the bottom of the window?

$(".raindrop1").clone().removeClass("raindrop1").addClass("raindropDelete").appendTo("body").css({
left: $(".shape").position().left - 29.50,
top: $(".shape").position().top + 1,
position: "relative"
}).animate({
top: "+=1000"
}, function() {
$(".raindropDelete").remove();
});
body {
background: rgb(0, 0, 0);
}
.shape {
border-radius: 50px;
width: 10px;
height: 10px;
background-color: white;
position: absolute;
left: 50%;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="shape" onclick="curse()"></div>
<img src='http://images.clipartpanda.com/raindrop-clipart-RTGdn5bTL.png' width="15px" class="raindrop1">
I got this bit of code but I just can't seem to get it to work the way I want to. I want to make an image fall down to the bottom of the screen but to delete itself just before a scrollbar appears.
JS:
$(".raindrop1").clone().removeClass("raindrop1").addClass("raindropDelete").appendTo("body").css({
left: $(".shape").position().left - 29.50,
top: $(".shape").position().top + 1,
position: "relative"
}).animate({top :"+=1000"}, function() {
$(".raindropDelete").remove();
});
HTML:
<div class = "shape" onclick = "curse()"></div>
<img src = 'http://images.clipartpanda.com/raindrop-clipart-RTGdn5bTL.png' width = "15px" class = "raindrop1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
and CSS:
body{
background: rgb(0, 0, 0);
}
.shape{
border-radius: 50px;
width: 10px;
height: 10px;
background-color: white;
position: absolute;
left: 50%;
top: 50%;
}
Am I doing anything wrong?
JSFiddle
You are trying to remove your droplet in the function that is used to do something when animation is completed. So droplet animation is still going until it will reach +1000px from the top.
To remove before it falls below the window it's possible to use step option for animate method. What it does is looking what happens during animation and you can remove the droplet if when it falls below the edge.
Step Function
The second version of .animate() provides a step option — a callback
function that is fired at each step of the animation. This function is
useful for enabling custom animation types or altering the animation
as it is occurring. It accepts two arguments (now and fx), and this is
set to the DOM element being animated.
now: the numeric value of the property being animated at each step
fx: a reference to the jQuery.fx prototype object, which contains a number
of properties such as elem for the animated element, start and end for
the first and last value of the animated property, respectively, and
prop for the property being animated.
So what I've done is created a step function that each step looks if droplet is reached the edge of the window. If condition is met - just remove the droplet
$(".raindrop1").clone()
.removeClass("raindrop1")
.addClass("raindropDelete")
.appendTo("body").css({
left: $(".shape").position().left - 29.50,
top: $(".shape").position().top + 1,
position: "relative"
})
.animate({top :"+=100"},
{step: function(now) {
if (now+50 >= $(window).height())
$(".raindropDelete").remove();
}
},
function() {});
body{
background: rgb(0, 0, 0);
}
.shape{
border-radius: 50px;
width: 10px;
height: 10px;
background-color: white;
position: absolute;
left: 50%;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class = "shape" onclick = "curse()"></div>
<img src = 'http://images.clipartpanda.com/raindrop-clipart-RTGdn5bTL.png' width = "15px" class = "raindrop1">
using this css you can stick your image to the bottom of the window in all new browsers
.fix{
position:fixed;
bottom:0px;
left:50%;
}
<img src="yourimagepath" class="fix"/>
and for IE6 you can use
position:absolute; instead of fixed. It will position the image on the bottom of the page but as you scroll up the image will scroll with the page. Unfortunately position:fixed in not supported in IE6
Using this code you can detect if the user has reached to the bottom of the page. Here you can add your code for deleting the image. If you put the code here the image will be deleted automatic if the user reaches to the bottom of the page.
window.onscroll = function(ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
// you're at the bottom of the page
}
};
You can use sticky elements. They are elements on a page that will not be scrolled out of view. In other words it sticks to a visible area (viewport or scrolling box). You can create this with CSS using position: sticky;.
[Ref: http://www.hongkiat.com/blog/useful-css-tricks-you-might-have-overlooked/]
Look at the following code for an example:
https://codepen.io/rpsthecoder/pen/zGYXEX
HTML:
<h4>Scroll to see the sticky element <em>sticking</em></h4>
<div class="extra"></div>
<br />
<div id="wrapper">
<div id="sticky">
sticky
</div>
</div>
<br />
<div class="extra"></div>
CSS:
#sticky {
position: sticky;
background: #F762BC;
width: 100px;
height: 100px;
top: 70px;
left: 10px;
display: flex;
justify-content:center;
align-items:center;
box-shadow: 0 0 6px #000;
text-shadow: 0 0 4px #fff
}
#wrapper {
width: 75%;
margin: auto;
height: 400px;
background-color: #ccc;
}
.extra{
background: #ccc;
width: 75%;
margin: auto;
height: 100px;
}
body {
height: 1000px;
font-family: georgia;
}
h4{
text-align: center;
}

How to set when waypoints triggers

I am trying to figure out how I can trigger a waypoints function. Right now this function starts when my info div is at the very top of the screen. Ideally, I want this to start when the user's bottom of the screen just gets to the info-box section. I am unsure of how I can even modify when the event triggers.
Also, for some reason the info-boxes aren't transitions to the right like I am attempting. They just transition into a fade with now horizontal movement. What is wrong with what I am trying?
var $info_show = $('#info');
$info_show.waypoint(function () {
$('.info-box').addClass("fadeShow");
});
#info {
max-width: 100%;
height: auto;
padding: 300px 20%;
}
.info-box {
border: 1px solid black;
padding: 50px;
background: #00f;
color: #fff;
display: inline;
margin: 0 100px;
transition: 1s;
opacity: 0;
}
.info-box.fadeShow {
opacity: 1;
transform: translateX(150px);
}
<script src="https://leaverou.github.io/prefixfree/prefixfree.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="info">
<div class="info-box">Red</div>
<div class="info-box">Blue</div>
<div class="info-box">Green</div>
</div>

jssor - Sizing and Stability Issue

I am totally new to jssor, and a less than novice coder. I just discovered the jssor carousel slider today, and I have been fooling around with it for probably 10 hours.
I have managed to solve most of my issues by reviewing other questions on this site, but I have been running around is circles for the past several hours.
First off to clarify, I love the Slider and it's ability to scale, but I need it to be more basic, and somewhat stay where I put it. :) I think after many hours I have got it to stay in one place just under my navigation, and it seems to be good there (although I probably did the the worse way possible.
My main issue now is that it seems to work perfect in IE, and on my native android cell browser, but on Chrome and Safari, the carousel won't keep its height. My photos are # 200x180, and in IE11, they appear to be the proper size. In the other browsers, the slider is only showing to be about 1/2" high.
My pages are PHP, and I call the slider page onto my home page with an "Include" statement (sorry, I seriously green). Now the code I pulled off of jssor.com does have some html references, so that could be giving me some issues, as well.
You can check it out live at (SilverScreenCollectibles.com). I've also pasted the code below (that I am using on my PHP page) so that you can see how bad I am at this.
I would really appreciate any assistance that anyone out there could offer.
Thanks,
Bill
<!DOCTYPE html>
<html>
<head>
<div class="span9">
<script src="assets/js/jquery-1.8.2.min.js" type="text/javascript"> </script>
<script src="assets/js/jquery.carouFredSel-6.0.4-packed.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
// create carousel
$('#carousel').carouFredSel({
responsive: false,
items: {
width: 200,
height: '90%',
visible: 8
},
auto: {
items: 1
},
prev: '#prev',
next: '#next'
});
// re-position the carousel, vertically centered
var $elems = $('#wrapper, #prev, #next'),
$image = $('#carousel img:first')
$(window).bind( 'resize.example', function() {
var height = $image.outerHeight( true );
$elems
.height( height )
// .css( 'marginTop', -( height/2 ) );
}).trigger( 'resize.example' );
});
</script>
<style type="text/css">
html, body {
height: 100%;
padding: 0;
margin: 0;
}
body {
min-height: 50px;
position: relative;
}
body h3 {
font-family: Arial, Geneva, SunSans-Regular, sans-serif;
font-size: 20px;
text-align: center;
color: #999;
margin: 0;
padding-top: 50px;
}
body * {
font-family: Arial, Geneva, SunSans-Regular, sans-serif;
font-size: 14px;
color: #333;
line-height: 22px;
}
#wrapper, #prev, #next {
border-top: 1px solid #999;
border-bottom: 1px solid #999;
height: 170px;
position: absolute;
/* top: 35%;*/
margin-top: 0px;
}
#wrapper {
width: 80%;
left: 10%;
overflow: hidden;
box-shadow: 0 0 10px #ccc;
}
#carousel img {
margin: 10px 5px;
border: none;
display: block;
float: left;
}
#prev, #next {
background: center center no-repeat #ccc;
width: 5%;
}
#prev:hover, #next:hover {
background-color: #bbb;
}
#prev {
background-image: url( assets/slide-imgs/form/gui-prev.png );
left: 0;
}
#next {
background-image: url( assets/slide-imgs/form/gui-next.png );
right: 0;
}
</style>
</head>
<body>
<div id="wrapper">
<div id="carousel">
<img src="cw4/images/product_full/LC-ChainedFrt.jpg" alt="Image1" width="212" height="180" onclick="window.location.replace('http://silverscreencollectibles.com/product.php?product=110');" />
</div>
</div>
<a id="prev" href="#"></a>
<a id="next" href="#"></a>
</div>
</body>

Large background images causing lag while scrolling

The website I am building has 4 large background images that take up the entire height and width of the user's browser. They are implemented as CSS background divs. The problem is, when scrolling on larger screen sizes, it is very laggy and choppy. Scrolling between these images is done automatically via JavaScript when the user presses a button, so this is part of the core functionality of my website and I must find a way to prevent lag.
So far, I have tried preloading the images via JS and converting the images from PNG to JPEG (increase compression and decrease quality) server-side. Neither of these worked.
The minimum height of the image can be 630 pixels. How can I prevent lag while scrolling between sections?
Here's my code:
CSS:
body { height: 100%; margin: 0px; font-family: HelveticaNeue, Helvetica, Arial, sans-serif; }
.area { height: 630px; border: 0px solid red; background: repeat-x; margin-bottom: 0px; }
a { text-decoration: none; }
h1, h2, h3, h4, h5, h6 { font-family: Av, Helvetica, Arial, sans-serif; color: #292E37; font-weight: lighter; }
#top { position: fixed; width: 100%; height: 10%; background: #292E37; box-shadow: inset 0px -1px 5px #000; z-index: 1000; }
#navigation { float: right; height: 100%; }
#bottom { width: 100%; position: fixed; bottom: 0px; padding: 10px; background: #292E37; box-shadow: inset 0px 1px 5px #000; text-shadow: 0px 1px 0px #000; color: #fff; }
#sceneSelection { top: 20%; position: fixed; padding: 10px; }
#info { margin-top: 50px; margin-bottom: 50px; }
.box { margin-top: 50px; padding: 75px; background: #292E37; box-shadow: inset 0px 1px 5px #000; text-shadow: 0px 1px 0px #000; color: #fff; }
.nav { position: relative; top: 38%; height: 100%; margin-right: 35px; display: inline-block; color: #fff; text-shadow: 0px 1px #000; }
.nav:hover { color: #EA5555; }
.nimage { float: left; width: 16px; height: 16px; position: relative; top: 5%; left: -20%; }
.home { background: url(site_images/icons/nav/home.png); }
.pricing { background: url(site_images/icons/nav/pricing.png); }
.features { background: url(site_images/icons/nav/features.png); }
.blog { background: url(site_images/icons/nav/blog.png); }
.contact { background: url(site_images/icons/nav/contact.png); }
.about { background: url(site_images/icons/nav/us.png); }
.logo { font-size: 2em; text-shadow: 0px 1px #000; padding-top: 10px; padding-left: 15px; color: #EA5555; font-family: Av, Helvetica, Arial, sans-serif; }
.red { color: #EA5555; }
.white { color: #fff; text-shadow: 0px 1px 0px #000; font-weight: bold; }
.dark { color: #202020; }
.center { text-align: center; }
.left { text-align: left; }
.right { text-align: right; }
.larger { font-size: 1.25em; }
.buttoni { -webkit-border-radius: 2px; -moz-border-radius: 0px; border-radius: 4px; background: #ddd; display: block; color: #ccc; font-size: 14pt; height: 50px; text-align: right; margin: 10px; cursor: pointer; color: #505050; }
.buttoni:hover { background: #EA5555; color: #fff; }
.btext { padding: 15px; position: relative; top: 25%; }
.groundi { background: url(ground_button.png); }
.skyi { background: url(sky_button.png); }
.stratospherei { background: url(stratosphere_button.png); }
.spacei { background: url(space_button.png); }
.image { height: 50px; width: 50px; float: left; border-top-left-radius: 5px; border-bottom-left-radius: 5px; }
li { color: #EA5555; }
li span { color: #505050; }
HTML:
<div class="space area" id="a4">
</div>
<div class="stratosphere area" id="a3">
</div>
<div class="sky area" id="a2">
</div>
<div class="ground area" id="a1">
</div>
JavaScript:
function scroll_to(id, speed, margin) {
$('html, body').animate({
scrollTop: $('#' + id).offset().top - margin
}, speed);
}
function match_height() {
var heights = [11, 630, 693, 756, 819, 882, 945, 1008, 1071, 1134, 1197, 1260, 1323, 1386, 1449, 1512, 1575, 1638, 1701, 1764, 1827, 1890, 1953, 2016, 2079, 2142, 2205, 2268, 2331, 2394, 2457, 2520];
var browsery = $(window).height();
var i = 0;
while(browsery > heights[i]) {
i++;
}
var h = heights[i];
$(".area").css("height", h + "px");
$(".area").css("width", "100%");
$(".ground").css("background", "url(scenes/ground/" + h + ".png)");
$(".sky").css("background", "url(scenes/sky/" + h + ".png)");
$(".stratosphere").css("background", "url(scenes/stratosphere/" + h + ".png)");
$(".space").css("background", "url(scenes/space/" + h + ".png)");
}
match_height();
var pos = 0;
$(".buttoni").click(function() {
var id = $(this).attr("id");
if(pos != id) {
scroll_to("a" + id, 2000, 0);
}
pos = id;
});
OP,
For browsers that support 3d transforms, e.g.: -webkit-transform, you could try the following:
your.div { -webkit-transform: translate3d(0,0,1px); }
Might not look like much, but doing the above causes the div in question to be hardware-accelerated.
Should you run into any flickering issues—they've been known to turn up in some cases—the following should sort you out:
your.div {
-webkit-transform: translate3d(0,0,1px);
-webkit-backface-visibility: hidden;
}
Via David Walsh - http://davidwalsh.name/translate3d
The use of translate3d pushes CSS animations into hardware acceleration. Even if you're looking to do a basic 2d translation, use translate3d for more power! If your animation is still flickering after switching to the transform above, you can use a few little-known CSS properties to try to fix the problem
Hope that helps.
As per my understanding, the issue and the solution drafted in the OP is two-fold:
initially, within the match_height() function, the OP author retrieves the images that best fits the screen height, so that upon completed animation the user sees one full background image.
after initial load, the user can navigate up and down the sections (with their respective background images) with the help of some buttons that trigger the scroll_to() function and its contained animation. Here is where the actual problem resides.
My efforts and the resulting fiddle focus on the scroll_to() function and the associated animation. I applied the following measures that, in conjunction, result in a (as per my subjective observation) 'smoother' scolling experience:
the original animation happened against 'html' and 'body', I'm reducing the jQuery selector to one selector only. In order to be able to use jQuery 1.9 (where jQuery.browser is deprecated) I'm using feature detection to get the 'right' selector:
function getScrollerSelector() {
var $body = $("<body/>");
$body.scrollTop(1);
return $body.scrollTop() == 1 ? "body" : "html";
}
In order to reduce the browser's processing load, I'm applying a logic that, per CSS, sets the background image of invisible sections to none during scrolling:
.scrolldown.scrollto-a2 #a1,
.scrolldown.scrollto-a3 #a1, .scrolldown.scrollto-a3 #a2,
.scrolldown.scrollfrom-a3 #a4,
.scrolldown.scrollfrom-a2 #a4, .scrolldown.scrollfrom-a2 #a3,
.scrollup.scrollto-a3 #a4,
.scrollup.scrollto-a2 #a4, .scrollup.scrollto-a2 #a3,
.scrollup.scrollfrom-a2 #a1,
.scrollup.scrollfrom-a3 #a1, .scrollup.scrollfrom-a3 #a2
{ background: none; }
I played around with linear easing, but that did not necessarily improve anything
All in all, scrolling doesn't seem choppy to me any more, but please take into account that this is also dependent on the client computers processing power.
Here's the scroll_to() function:
function scroll_to(id, speed, margin) {
var currentScrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var scrollTop = $('#' + id).offset().top - margin;
var direction = scrollTop > currentScrollTop ? "down" : "up";
$("body").addClass("scroll"+direction + " scrollto-"+id + " scrollfrom-"+getScrollFrom(direction));
$( scrollerSelector ).animate({
scrollTop: scrollTop
}, {
//easing: 'linear',
duration: speed,
complete: function() {
$("body").removeClass("scrollup scrolldown scrollto-a1 scrollto-a2 scrollto-a3 scrollto-a4 scrollfrom-a1 scrollfrom-a2 scrollfrom-a3 scrollfrom-a4");
}
}
);
}
This is the link to jsfiddle
Since you are Scaling up the image, you can tell the Browser how to handle the rendering of image.
During the animation / scrolling, you can tell browser to Optimize on Speed and on completion of Animation / scrolling, Optimize on Quality.
Here is the CSS Property you can use on img: 'image-rendering' with values as optimizeSpeed / optimizeQuality.
https://developer.mozilla.org/en-US/docs/CSS/image-rendering
One thing you could do to images is smush it using http://www.smushit.com/ysmush.it/
this reduces the size of the image without loosing quality removing all unwanted meta data.
Testing locally it seems like your code should work ok, I have firefox 15 and chrome and don't see any lagging
What if you try this for the scroll to method?
function scroll_to(id, speed, margin) {
$('html, body').animate({
scrollTop: $('#' + id)
}, speed);
}
I had a similar problem with a website I was working on. In the end the problem seemed to be because of the large dimensions of the image that the computer/browser had to compute and render on screen.
My recommendation would be to try and reduce the amount of image that needs to be shown and scrolled on screen if possible.
Most modern browsers now support hardware (graphics card) rendering instead of the traditional (usually slower) software based (CPU) rendering. Hardware based rendering should in theory reduce that lag you're experiencing. However if your PC only has base or average graphics rendering capabilities, you're not going to have much success regardless. I personally had no success with either in Chrome, FireFox or IE until I gave in and removed the images.

Categories

Resources