Javascript/jQuery slowdown when switching to full screen - javascript

I have some strange behavior from firefox, I'm building a single page portfolio and as a graphic designer the coding has been hard. I wanted to smoothly control the navigation and then later added scaling to all the elements (designed for 1920x1080 full screen initially). The lecturer dropped a bomb that it needed to scroll vertically as well, I am in the process of trying to get the vertical navigation to work.
The issue is when I switch to full screen most of the navigation code seems to take a long pause before it executes. This only happens when I switch to full screen. If I switch and refresh then it's ok. I really want to know whats slowing the whole thing down.
I have tried safe mode with no plugins. I'm using Firefox 24.0 with Firebug to get at the bits an pieces.
I have created a code fiddle (my first and it's already broken):
http://jsfiddle.net/jeffreyknipe/xfjmC/1/
The code for the scrolling is as follows:
function navTo(horizontal, vertical) {
browserWidth = $(window).innerWidth();
browserHeight = $(window).innerHeight();
newRatio = browserWidth / 1920;
$('html body div#full_site section#pages_section').animate({
marginLeft: '-' + browserWidth * horizontal,
marginTop: (browserWidth / 16 * 9) * vertical
}, 1000);
if (horizontal == 0) {
$('#menuspace #floating_topbar #menuzone').animate({
marginRight: 0
});
} else {
$('#menuspace #floating_topbar #menuzone').animate({
marginRight: (newRatio * (-340))
});
};
};
I know the coders out there will frown on how inefficient the code is but any advice will be appreciated. The biggest thing is the full screen code slow down.
Thanks.

The issue came in when animating the changes in items or location when going to and from full screen. I switched to setting the new values with .css rather than .animate (I did want it to animate to the new location) but since animation here wasn't a deal breaker and it solved the issue I'm a happy camper.
I have to assume that it wants to animate but the java script engine or some thing in Firefox get too busy during the change, it's almost a bug but I can't isolate whats happening while the script is jammed so I can't report it.

Related

Problem with scrolldown in slow manner using javascript

I needed JavaScript for automatic scroll down in a smooth/slow manner.
I have a form with many radio buttons which is quite similar to survey form.
I used script from the below mentioned link. This link works fine smoothly for scrolling downwards.
But problem comes when you reach the bottom of page and cannot scroll upwards.
I am not so good in JavaScript. Does anyone here has solution or fix to this?
Link to Stack Overflow thread:
Slow down onclick window.scrollBy
function scrollByRate(y, rate)
{
//calculate the scroll height
var scrolling = Math.max( document.getElementsByTagName('html')[0].scrollTop, document.body.scrollTop);
//save the old value as "static" var
arguments.callee.tmp = arguments.callee.tmp || scrolling + y;
//make a little scrolling step
window.scrollBy(0, (arguments.callee.tmp - scrolling) / rate);
//are we arrived? if no, keep going recursively, else reset the static var
if(arguments.callee.tmp - scrolling > 100) setTimeout(function() { scrollByRate(y, rate); }, 10);
else arguments.callee.tmp = undefined;
}
Scrolling down slowly
I can see your approach having a negative impact on performance. It looks like the browser will block until the target scroll destination has been reached.
My suggestion is to use what is out there for smooth scrolling already. The scrollTo method of any scrollable pane (e.g. window object but also a scrollable div for example) has a "behavior" property that you can set to "smooth", e.g.:
window.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});
Keep in mind that the compatibility at the time of writing is limited to Chrome, Firefox, Edge and Opera which means you'll have problems on Internet Explorer and Safari (so all Apple products). I myself use a polyfill to get the smooth scrolling back on my application, this one in particular: https://github.com/iamdustan/smoothscroll

jQuery's scrollTop() behaving strange on Android browsers including Chrome

I'm having trouble with an animated scrollbar. The intended behaviour should be on clicking the nav-button, scroll with ease to the end of the page(and a little break near the end).
Now the problem on PC works perfect. On android device (I tried my phone), the scrollTop value and the ($(document.body).height() - $(window).height()) do not match. There is exactly 55px less with the scrollTop thus acting all sorts of strange... Also sometimes it works sometimes it doesn't. I've figured it has something to do with the browser bar collapsing and upsetting the value...but i can't figure it out.
I've tried the following: initializing the variables on scroll event, i've tried vanilla js that didn't work. Need help :) for reference http://www.developer.morningmood.org , also i've printed out the values on bottom of the page if it helps. Here's the code.
contactF = Math.floor($(document.body).height() - $(window).height());
$("#cont").click(function(){
if ($(document).scrollTop() < contactF && flagScroll==true){ //flag stops other buttons from beying pushed
flagScroll = false;
var inter = setInterval(function(){
var doc = $(document).scrollTop();
if (doc == contactF){ // this is the final desired position
clearInterval(inter);
flagScroll = true;
pix = 10; //pixels to jump
return;
}
if (doc >= contactF-50){ // this is a break on aproach
pix = 1;
}
$(document).scrollTop(doc + pix);
}, 10);
}
})
EDIT: also to find the bug, you nedd to scroll from the top of the page all the way to the bottom, if from the top of the page you just push the contact button it works. but if you scroll it doesn't, it upsets the value...
Had the same exact problem and spent a whole day to figure it out.
You are right about the address bar collapse on Android chrome messing it up. Turns out the jQuery function $(window).height() always reports the viewport height that is before the address bar collapses. To get the correct value, use window.innerHeight instead. You can find more information about URL bar resizing here https://developers.google.com/web/updates/2016/12/url-bar-resizing
You can also find people asking similar questions regarding the safari address bar auto-hide, the solutions are similar. Mobile Safari $(window).height() URL bar discrepancy

JavaScript scroll based animation is choppy on mobile

I have 2 divs (left and right) and i want to scroll the left based on the right.
https://jsfiddle.net/3jdsazhg/2/
This works fine on desktop, but when i change to mobile, it's not smooth anymore...
This can be noticed very easily, by changing
_left.style.top = _content.scrollTop - (_content.scrollTop * ratioLeftRight) + 'px';
to
_left.style.top = _content.scrollTop + 'px';
Where it should act as a fixed positioned div
I would like to know the exact reason why this isn't smooth... I know that it's not the animation. Simple animation on the div is smooth, the issue comes up when it's based on scroll.
How can i make this animation smooth?
It's probably choppy because it's being fired ALOT when being scrolled, in fact i'm pretty sure IOS mobile pauses the javascript execution whilst the user is scrolling.
Instead I'd suggest using an interval, you could tweak the time between each interval to what feels good for your use-case.
Although it may seem intensive that it's firing this logic every X millisecond when using the scroll event you could be firing the event off hundreds of times per second, which is going to be far more intensive and noticeable to a user using a device with limit processing power.
(function () {
var interval = null,
//Currently set at 0.4 seconds, play with the code
//and change this value to see what works best for
//this use-case
time_between_interval = 400;
setInterval(scrollLogic, time_between_interval);
function scrollLogic () {
//The function body of what you're assigning
//to the scroll event.
}
//I have omitted clearing the interval but you would want to do that, perhaps on page change, or something.
//clearInterval(interval);
})();
I finally managed to think out a solution.
From my point of view, i'm guessing the mobile view fires the scroll event less often and because we are scrolling the wrapper, we first scroll the whole page and then scroll back with js the left part and because it's different from the desktop version, this issue becomes visible...
The solution was to change the left side to fixed position, and substract from the top instead of adding to it.
_left.style.top = -(_content.scrollTop * ratioLeftRight) + 'px';

CSS/JS scrolling glitch effect (performance)

I am trying to achieve a "crt-like" scrolling glitch effect using Javascript and CSS. I have come up with the following code which clones the content and applies clip to make it look like it scrolls while adding random horizontal offset.
function scanglitch() {
var e = $('#wrapper').clone().appendTo('#glitchcontainer');
var i = 0;
e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
e.css("z-index",200);
var interval = setInterval(function () {
e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
e.css({"left": Math.round(Math.random() * 10) + "px"});
i+=4;
if (i > window.innerHeight) {
e.remove();
window.clearInterval(interval);
}
}, 40);
}
Fiddle (Click on the text to see the effect)
I am actually quite pleased with the effect, but the implementation is obviously a hack. As a result the performance is unacceptably low (chrome cpu usage spikes from 5% to 50% when the effect is triggered).
Could someone help me figure out a way to achieve this effect in a more elegant and less performance-heavy way?
UPDATE:
I have implemented your suggestions: Using translate instead of left, scrolling with translate instead of a js loop, calculations outside of the css tag and using requestAnimationFrame(). The code is nicer and more predictable now, but the animations are still very taxing.
New fiddle
You can try using requestAnimationFrame (it is available in almost all browsers). Seems to make a big difference in Chrome.
JSFiddle
EDIT
Here's a transition-only version, and while it doesn't even implement the jitter, it's useful for comparison. Surprisingly(?) it shows about the same, if not more, CPU usage. (You can check the Profile and Timeline tabs in Chrome)
CSS3 Transition-Only JSFiddle
Here's some information about why that should be expected. Essentially, CSS transitions and requestAnimationFrame work very similarly under the hood.
I would delegate as much as possible to css transitions. So instead of moving the clip with js in the interval callback, transition it from top to bottom (example of transitioning).
You could try something similar with the left property, there's no random easing function but maybe you could achieve something similar with one of the bounce functions. Maybe change the easing function with an interval that's less frequent than your current one.
Also, just by slowing the interval of your current solution you'd get visually ok results with less CPU usage.
Side-note: for a completely different route you can replicate your html in a canvas and apply some effects to that. Google has plenty of results for "canvas glitch".
Update: here's my version of your latest fiddle
I get about 10 % less cpu usage with it when comparing to yours. Key differences are:
uses a timeout instead of requestAnimationFrame. requestAnimationFrame is meant to keep framerate high and the animation smooth but we don't need that for the random offsetting. Timeout is also better than an interval since the loop function is quaranteed to finish before next iteration starts.
removed the transparent background, since transparency has a rendering cost

Slideshow Script Centering Issue on Images of Varying Width

I'm trying to build a slideshow script will work with images of any width. Not too surprisingly, I'm having some centering issues that cause the portrait mode images to start off on the left when they initially display and then immediately move to the center after a short delay (giving it a bit of a "shooting ducks at a carnival" feel) .
I think that the solution is to get the image width right before it displays and then use that to center it, but I've been having some trouble finding reliable code that does that correctly. I've seen some examples that get the dimensions on load, but since the page (obviously) only loads once before the slideshow starts, that doesn't help much. I put it into CodePen for anyone to view that is kind enough to try and assist me:
http://codepen.io/Realto619/pen/fhdwK
I'm also having a problem with the getPrev() and getNext() functions not working on the first click, They work fine after that, and they seem to be firing on those first clicks, but they don't do what they're designed to until the second click.
Thanks in advance...
As I suspected, the problem was due to the image dimensions / image container not changing for each slide, so the css couldn't center it without having an accurate width for margin:0 auto; to work properly.
I created the following function and then called it in each of the other functions:
function getDim() {
iW = $(window).innerWidth();
iH = $(window).innerHeight();
natW = $(".fadein img").get(0).naturalWidth;
natH = $(".fadein img").get(0).naturalHeight;
natR = natW/natH;
adjH = iH*0.98;
adjW = adjH * natR;
$(".fadein").css('width',adjW);
$(".fadein img").css('width',adjW);
$(".fadein img").css('height',adjH);
}
Hopefully this will help someone else with a similar issue that comes here.

Categories