What would be the best way to achieve the following:
I would like to get a big centered logo, to shrink and move to the top left of the page as you scroll down and become part of the nav bar.
I would also like a nav bar to fade down from the top.(I only know how to do this timed not dependent on scroll)
When the site loads it will look like just a logo with a simple background. When you scroll down the logo will shift to the top left and the nav bar will ease in and the background picture will also move up out of sight.
Is there any way that you can do the transformation dependent on how far you have scrolled. So that if you stop half way your transformation will also stop?
If I understand you correctly, you want to make a transition to the nav bar / header and the logo dependent on how much you have scrolled, while you are scrolling? If so, it is not as hard is it might sound.
First we have to find out, how many pixels you have scrolled on the page and how many pixels to scroll before the transition is complete. Se code example below.
$(window).on("scroll", function() {
var yPos = $(this).scrollTop(),
yPer = (yPos / 120);
if (yPer > 1) {
yPer = 1;
}
});
Here the y position of the page is found yPos and the transition is set to complete when scrolled down 120 pixels. With these informations we can then calculate the percentage of scrolled pixels until reaching 120 pixels; yPer.
0px = 0%, 60px = 50%, 120px = 100%
In the if-statement we make sure, that the percentage cannot exceed 100%.
HTML and CSS part
Before we go any further with the JavaScript part, let’s setup the HTML and CSS.
HTML structure:
<header></header>
<img class="logo" src="http://oi68.tinypic.com/2z5m4pu.jpg" />
In this case the logo is not inside the header, since we are going to hide the header by default, which would also hide all the child-elements including the logo, which we do not want.
Hiding the header/nav bar:
header {
width: 100%;
height: 60px;
background: #FFF;
position: fixed;
top: -60px;
opacity: 0;
}
Since you want the header to fade in from the top while scrolling, top is set to the negative height of the header itself and the opacity to 0.
Centering the logo:
img.logo {
height: 200px;
position: fixed;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
}
In this way we are going to center the logo in the middle of the screen, no matter the size and resolution of the browser window. If the values in top, left and translate3d all where set to 0, the logo would be in the top left corner. That's why this is a good way to do it in our situration.
JavaScript part - continued
Now we're ready the continue with the JavaScript part.
Store heights in variables:
var header = $("header"),
headerHeight = header.height(),
logo = $(".logo"),
logoHeight = logo.height();
$(window).on("scroll", function() {
// Rest of our code
});
To make it a lot easier for us self later on, we are going to automatically find the height of both the header and the logo, and store those in variables. By doing this we don’t have to change anything in the JavaScript code, if we later on in the future wants to change the height of our elements. We only have to change it, in the CSS.
We are going to set those variables before our scroll-function since, they do not change while scrolling as seen above.
The Calculations:
var logoPos = ( -1*(yPer * 50) + 50),
logoSize = ((headerHeight * yPer) - (logoHeight * yPer) + logoHeight),
headerPos = ((yPer * headerHeight) - headerHeight);
This is a very important part of our code. These expressions are the once that calculates how the elements should animate as we scroll.
logoPos: Calculating the new position of the logo as we scroll. We know that the top, left and translate3d always has
a value of "50". | Starts on 50, ends on 0.
logoSize: Calculating the size of the logo as we scroll. | Starts on the height of the logo, ends on the height of the
header.
headerPos: Calculating the position of the header as we scroll. | Starts on the negative height of header, ends on 0.
NOTE: If we didn’t stored the heights of your elements like before, we had to manually change them in calculations if we later wanted to change them.
Add the new styles:
logo.css({
top: logoPos + "%",
left: logoPos + "%",
transform: "translate3d(-" + logoPos + "%,-" + logoPos + "%,0)",
height: logoSize
});
header.css({
top: headerPos,
opacity: yPer
});
Here we using all our calculations to style our elements as we scroll. On the logo at translate3d we have to remember to put a minus before the logoPos. Else the logo will start moving from the bottom right instead of the center.
For the opacity, we don't have to calculate anything. We just use the yPer.
Well that’s basically it. Hope this could help you out.
You can se the full code in context and with comments in this fiddle:
Working Fiddle
If I understand your question correctly then you should use $(window).scrollTop().
For example in your javascript file,
$(document).ready(
function () {
setInterval(function () {
if ($(window).scrollTop() >= 650) {
// Move your logo to where you want
}
else{
//Move the logo back to the original position
}
}, 1000);
});
This code will check if the current top of your scroll is past 650px and will trigger that code. If it's less than 650px they it will trigger the other code to move your picture back. The setInterval is used so it will constantly check every 1 second but you can change that to suit your needs.
Change the 650 to whatever you think fits best.
It kind of hard to figure out your problem without providing any code but I hope this helps.
Related
In my app, when viewing a restaurant page, comments are hidden by default. The user can expand them as desired. I want the screen to slide down smoothly behind the bottom edge of the comments window when the comment box is maximized.
When opening the page:
When expanding comments:
That's what I need:
When rolled back, the screen moves smoothly with the bottom edge of the window. I'd like to achieve the same effect when unwrapping.
I implemented folding and expanding in this way:
useEffect(() => {
if (isOpen) {
innerWindowRef.current.setAttribute('style', 'height:' + totalCommentHeight.current + 'px')
outWindowRef.current.setAttribute('style', 'padding: 5px')
} else {
innerWindowRef.current.setAttribute('style', 'height: 0; padding: 0')
setTimeout(() => outWindowRef.current.setAttribute('style', 'padding: 5px 5px 0'), 900)
}
}, [isOpen])
I tried to use the scrollTo() function, but it did not suit me because it only works with elements that have already been drawn, and not with those that are being drawn (expanded) at the moment. Therefore, I was able to implement this option only with a delay, which did not suit me.
The same goes for the scrollIntoView() function.
It is necessary that the screen always scrolls to the bottom of the page at the same speed as the animation of the expanding window. How can I implement this?
This should solves your problem:
window.scrollBy({
top: 100, // this is the amount to be added to the current scroll. it can be negative or positiove number (in px)
left: 0,
behavior: 'smooth'
});
You need to give the height of the expanded comment block to top as value
I'm creating an Chrome Extension, which should add sidebar to all webpages.
This sidebar shouldn't overlap webpage content, it should be placed next to the existing content, essentially shrinking width of body of webpage to initial width - sidebar width.
This is the code I came up with, but I have a problem with some pages like stackoverflow for instance, see how top bar doesn't shrink like the rest of the page does (screenshots attached below the code)
// create sidebar
const sidebar = document.createElement("iframe");
sidebar.src = chrome.extension.getURL("iframe/iframe.html");
sidebar.id = "extensionSidebar";
sidebar.frameBorder = "0";
sidebar.style.height = "100%";
sidebar.style.width = "100px";
sidebar.style.position = "fixed";
sidebar.style.top = "0";
sidebar.style.right = "0";
sidebar.style.zIndex = "2147483646";
// append sidebar to body
document.documentElement.appendChild(sidebar);
// shrink body
document.body.style.width = window.innerWidth - 100 + "px";
Screenshots:
https://prnt.sc/o215x5
https://prnt.sc/o21637
The top bar doesn't shrink as you would like it to do because it is fixed, it will always take 100% of the viewport width. Its CSS properties on your example with stackoverflow are :
...
position: fixed;
top: 0;
left: 0;
width: 100%; /*though it's not "really" 100vw*/
...
Even by changing the html element in CSS, in order to change its maximum size to 80% of the viewport width for instance, the navbar would still take all the viewport's width.
To understand it you can try the following fiddle, it might speak for istelf : https://jsfiddle.net/bcg2vkjm/4/
On it you can "un-comment" the body element inside the CSS and see the result, it might give you some help ! Though it only applies a scale of 1 (so it should not change...), for some reason it makes the fixed element adapt to the body size, which is what you want, you just might have to play along with the translateX and/or scale in the CSS, but it might be a risky solution because it changes quite a lot the way everything is displayed, not only the fixed element, as you can see.
In your javascript you can try the following :
document.querySelector('body').style.transform = "scaleX(something)";
for instance !
I am trying to duplicate the left nav at http://www.kahuna-webstudio.fr/. If you take a look at http://www.kahuna-webstudio.fr/, and scroll down about 50 pixels or so, you will see a div appear off to the left of the screen that has some navigation in it. I have most of it working, thanks to the help of some of you at stackoverflow. But the one part I do not have working is that the content of my div, images, do not stay stationary in place (or always visible) as you scroll down.
So what I want to happen is: when the div appears at the left of the screen, when the user scrolls down, I want the content of the div to appear always in view.
Right now what I have working is: through animate() I set the height of my left nav div to the document height, and the width grows to 80 pixels, and then some images fadeIn(). But the page is fairly long and as the user scrolls down they are also able to scroll down the height of my left nav div; and I always want the content of my left nav to always appear in view to the user.
I think this person posted a similiar question (Keeping a header always in view) but I am finding it difficult to attach if to my example code. Can anyone help? I appreciate it a lot.
Here is my code:
$(window).scroll(function(){
var wintop = $(window).scrollTop();
var docheight = $(document).height();
var winheight = $(window).height();
var newwidthgrow = 80;
var smallheight = 0;
var smallwidth = 0;
if((wintop > 296)) {
$("#slidebottom").stop().animate({height:docheight +"px"},'fast',function(){
$("#slidebottom").stop().animate({width:newwidthgrow + "px"},'slow',function(){
$("#slidebottomContents").fadeIn();
});
});
}
if((wintop < 25))
{
$("#slidebottom").stop().animate({height:docheight +"px"},'fast',function(){
$("#slidebottomContents").fadeOut(function(){
$("#slidebottom").stop().animate({width:smallwidth + "px"});
});
});
}
});
As far as i'm concerned this can be covered by only css.
To keep the div in the same position you can apply the following css:
css:
div id {
position: fixed;
left: 0px
width: 'your width'
}
position fixed freezes the div in the position you want.
left keeps the div positioned on the left side of you page.
does this answer your question and solve your problem?
if not let me know!
I'm building a site with a fluid layout, and therefore need to use percentages in my Jquery sizes and animations. The problem, as I've discovered, is that Jquery doesn't understand percentages. Here's an example of what I'm after:
The page <body> is 100% wide.
<article> is the width of 71% of the page body.
<hgroup> is the width of 33.2% of <article>
I would like <article> to be the same width as <hgroup> on page load (so that only <hgroup> is showing), then expand to 71% of the page width again when <hgroup> is clicked, allowing the rest of the content within <article> to show. At the same time, I'd like <article> to slide left by the width of <hgroup>, hiding <hgroup>.
Is there any way to make this kind of calculation, or will I have to resort to pixels?
Well, you can define
article {
width: 23.6%;
/* that's 33.2% of 71% of 100 */
}
hgroup {
width: 100%;
/* that's in relation to article */
}
plus whatever positioning you need
then
$('article').width($('body').width() / 100 * 71);
$('hgroup').width($('article').width() / 100 * 33.2);
plus whatever effects you need
After much frustration and lamentation, I finally got it sorted out. Here's the code I came up with which, miraculously, works:
$(document).ready(function() {
$('section').hide();
//Capture widths on page load
var bwidth = $('body').width();
var awidth = $('article').width();
var hgwidth = $('hgroup').width();
$('hgroup').width(hgwidth);
$('article').width(hgwidth);
$('hgroup').click(function(){
//Hide open article
var close = $('section:visible').parent();
$(close).children('section').hide().end().width(hgwidth);
$(close).removeClass('active').css('marginLeft', '+=' +hgwidth).detach().appendTo('body');
//Hide last Article
$('body article').last().hide();
//Show current
$(this).parent().addClass('active')
$('.active').animate({
width: awidth,
marginLeft: '-=' + hgwidth
},500);
$(this).next().delay(500).fadeIn(50);
$(this).css('box-shadow','0px 0px 8px #666');
//Show Next Hgroup
$(this).parent().nextAll('article:first').show();
});
});
I think you are looking for slide effect. Take a look at jquery ui slide effect http://docs.jquery.com/UI/Effects/Slide. It might help you without much coding.
I would like to create an interface with 3 columns, each having mixed content (text, image, and video), and would like to have them scroll vertically with different speeds at the same time. Is there a relatively simple way of accomplishing this with html, css, and/or javascript?
PS. I know about the parallax scrolling, but the implementations I came across seem to be mostly about using images as background to create a dimensional illusion.
Something like: http://jsfiddle.net/KVWuS/.
$.fn.makeScroll = function(speed) {
var elem = this,
i = 0;
setInterval(function() {
elem.scrollTop(i++); // increment scroll top
}, speed); // run every 'speed' ms (so lower is faster)
};
You can enable it like:
$('div:eq(0)').makeScroll(75); // moderate speed
You want to actually scroll the content?
$('.column').animate({
scrollTop: $('.column').height() - $(window).height()
}, 1000);
This will scroll your column down in 1 second. Adjust the speed per column.
EDIT:
I was assuming your columns were the height of the window. If not, you'll have to adjust the scrollTop.
I think a simple workaround would be to create 3 div Elements with the following Attributes:
overflow: hidden;
width: x px (fixed width)
height: x px (fixed height)
top: 0px;
left: x px;
Then you have to capture the onscroll event and set the top-Attribute.
E.g.
div1: top: -100px
div2: top: -300px
div3: top: -500px
I hope my description is clear.. :)
That should work