Locomotive Scroll - switching from horizontal to vertical and back - javascript

I am using Locomotive-Scroll (https://locomotivemtl.github.io/locomotive-scroll/) for smooth and horizontal scrolling, it's easy and works well. However, I'd like to integrate a section of vertical scrolling as well.
Visual Explanation
I've tried lots of things, none of which works entirely. I face mostly three issues:
I don't understand why my solution works to a certain extent and I cannot find any tutorial on locomotive-scroll going further than adding the data-scroll property
I didn't find a way to change the vertical scroll direction from downwards to upwards
If I resize the window, locomotive scroll brakes and can only be restored by a reload
My current solution (I would consider myself a beginner):
const scroller = new LocomotiveScroll({
el: document.querySelector('#scrollable'),
smooth: true,
direction: 'horizontal'
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Helvetica Neue', sans-serif;
font-size: 2vh;
}
.section {
height: 100vh;
}
#section-one {
width: 100vw;
}
#section-two {
width: 400vh;
background-color: blanchedalmond;
}
#section-three {
width: 100vw;
}
.heading {
font-size: 5rem;
font-weight: 500;
text-transform: uppercase;
}
.home__statement {
width: 100vw;
position: relative;
}
.heading.one {
position: absolute;
left: 10vw;
top: 25vh;
}
.heading.two {
position: absolute;
left: 10vw;
top: 35vh;
}
.heading.three {
position: absolute;
left: 10vw;
top: 45vh;
}
#sticky-container{
width: 100vw;
height: 100vh;
background-color: cadetblue;
}
.vertical-canvas {
position: absolute;
top: -300vh;
height: 400vh;
width: 100vw;
background-image: linear-gradient(red, yellow);
}
.example-1 {
height: 50%;
width: 100vw;
background-color:rgba(175, 18, 18, 0.3);;
}
.elem {
width: 100px;
height: 100px;
background-color: cornsilk;
}
.example-2 {
height: 25%;
width: 100vw;
background-color: rgba(46, 165, 46, 0.3);
}
.example-3 {
height: 25%;
width: 100vw;
background-color: rgba(75, 92, 168, 0.3);
}
<div id="scrollable" data-scroll-container>
<section class="section" id="section-one" data-scroll-section>
<div class="home__statement">
<span class="heading one" id="statement__line-one">Some text blabla</span>
<div>
</section>
<section class="section" id="section-two" data-scroll-section>
<div id="sticky-container"
data-scroll
data-scroll-sticky
data-scroll-target="#section-two"
data-scroll-speed="-1">
<div class="vertical-canvas"
data-scroll
data-scroll-sticky
data-scroll-target="#section-two"
data-scroll-direction="vertical">
<div class="example-1" id="ex1">
<div class="elem"></div>
</div>
<div class="example-2"></div>
<div class="example-3"></div>
</div>
<div>
</section>
<section class="section" id="section-three" data-scroll-section>
<div class="home__statement">
<span class="heading one" id="statement__line-one">Some text blabla</span>
<div>
</section>

You Can't initialize both Horizontal Scroll and Vertical Scroll within the same
[data-scroll-container]
For the things you want to achieve, you can do with gsap scrollTrigger
but you have to implement scrollTrigger with locmotive
Than You can do whatever effect you want

Related

Content in header moving when i scrolling

I need to make the sticky header in css.
But I got a problem. When I scroll through the google chrome browser page the content in the sticky section jerks. This is annoying. Moves literally 1 pixel but catches the eye.
I have the same task as in this example which I found on stack overflow. You may not notice this bug right away.
But this is clearly visible if you zoom in on the element or look at a monitor with a low expansion. The elements are literally jumping around. I want the elements not to move when the page is scrolled.
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: 'Roboto', sans-serif;
position:relative;
}
#import url("https://fonts.googleapis.com/css?family=Roboto:100");
h1 {
letter-spacing: 3px;
margin: 0;
padding-left: 10px;
padding-top: 10px;
color: #fff;
font-weight: 100;
}
.header {
width: 100%;
height: 50px;
position: sticky;
top: 0px;
}
.header:nth-of-type(1){
background-color: dodgerblue;
}
.header:nth-of-type(2){
background-color: rebeccapurple;
}
.header:nth-of-type(3){
background-color: chartreuse;
}
.content {
width: 100vw;
height: 100vh;
background: linear-gradient(70deg, orange, crimson);
padding-top: 50px;
}
.header-2{
top: 50px;
}
.header-3{
top: 100px;
}
<section>
<header class="header"><h1>HEADER 1</h1></header>
<div class="content"><h1>CONTENT</h1></div>
<header class="header header-2"><h1>HEADER 2</h1></header>
<div class="content"><h1>CONTENT</h1></div>
<header class="header header-3"><h1>HEADER 3</h1></header>
<div class="content"><h1>CONTENT</h1></div>
</section>

How do I Re-position HTML elements when new ones load in (js)?

I'm just building out this UI for a mod I'm making that starts off completely invisible and elements pop in to provide information based on usage in-game.
Here's an image for example:
I want each element to remain invisible with the only permanent one being the microphone. Each other element will fade in on use and fade back out when the bar is full.
I was just wondering how I would get each box to push to the left as they fade in so the UI operates smoothly and I don't get any large gaps in between each element if one is showing and another isn't.
How would I make them reposition based on which are active/being used?
body {
background: linear-gradient(#e66465, #9198e5);
background-repeat: no-repeat;
background-size: 1920px 1080px;
}
.box1 {
position: absolute;
right: 170px;
bottom: 37.5px;
width: 50px;
height: 50px;
background: rgba(0, 0, 0, 0.4);
z-index: 1;
}
.box2 {
position: absolute;
background: rgba(0, 0, 0, 0.4);
right: 230px;
bottom: 37.5px;
width: 50px;
height: 50px;
}
.box3 {
position: absolute;
background: rgba(0, 0, 0, 0.4);
right: 290px;
bottom: 37.5px;
width: 50px;
height: 50px;
}
<body>
<div class="container">
<div class="box1">
</div>
<div class="box2">
</div>
<div class="box3">
</div>
</div>
</body>
You better make use of reusable css classes and then binding your toggling boxes with some js event.
If you do it right, the elements will place themselves at the right spot everytime.
Take a look at this example:
const togglingBoxes = document.querySelectorAll('.js-toggle');
setInterval(() => togglingBoxes.forEach(box => box.style.display = Math.random() > 0.5 ? 'inline-block' : 'none'), 500)
body {
background: linear-gradient(#e66465, #9198e5);
background-repeat: no-repeat;
background-size: 1920px 1080px;
}
.container {
position: absolute;
right: 170px;
bottom: 37.5px;
}
.box {
display: inline-block;
width: 50px;
height: 50px;
background: rgba(0, 0, 0, 0.4);
margin-left: 10px;
}
<body>
<div class="container">
<div class="box js-toggle">
1
</div>
<div class="box js-toggle">
2
</div>
<div class="box">
3
</div>
</div>
</body>

jsx css sizing issue, possible flex conversion

I'm creating a simple web page using React.
I have an outer div with an <img /> tag and a <div /> tag with other divs and things like that inside of it.
The <img /> doesn't resize (so if I zoom in and out, it just stays the same size really). The <div /> tag does (the resizing gets kind of weird when I zoom in past 90% though).
I'm just curious as to why this is happening? There are 3 images within the <div /> and text overlaying each image. Then the <img /> tag is really just more of a large logo. Any advice? Beneath is the JSX
<div className='container'>
<img src="logo.png" alt='Logo Large' className='logo' />
<div className='container1'>
<div alt='cc' className='container2'>
<div className='cc'>
asd
</div>
</div>
<div alt='cc1' className='container3'>
<div className='cc1'>
asdddd
</div>
</div>
<div alt='cc2' className='container4'>
<div className='cc2'>
123124
</div>
</div>
</div>
</div>
Beneath this is the related CSS
html,
body,
#app {
height: 100%;
width: 100%;
}
body {
background: #2aa9e0;
user-select: none;
color: #fff;
overflow: hidden;
font-family: 'Courier New';
}
.container {
display: flex;
align-items: center;
height: 97%;
width: 100%;
}
.container1 {
display: flex;
flex-direction: column;
align-items: inherit;
height: 80%;
width: 50%;
}
.container1 .container2 {
background-image: url("...");
width: 628px;
height: 324px;
position: relative;
}
.container1 .container2 .cc {
font-size: 52px;
position: absolute;
width: 100%;
text-align: center;
top: 15%;
}
.container1 .container3 {
background-image: url("...");
width: 213px;
height: 139px;
position: relative;
}
.container1 .container3 .cc1 {
font-size: 52px;
position: absolute;
width: 100%;
text-align: center;
top: 30%;
}
.container1 .container4 {
background-image: url("...");
width: 628px;
height: 336px;
position: relative;
}
.container1 .container4 .cc2 {
font-size: 52px;
position: absolute;
width: 100%;
text-align: center;
bottom: 15%;
}
.container .logo {
height: 70%;
width: 50%;
}
Any help would be greatly appreciated. I started using flexbox in the beginning, but kind of moved away from it to get everything properly aligned and organized in container1
The <img /> doesnt resize, since its width is set to 50% of the WIDTH of the surrounding container. The container keeps its width on zoom in/out, so the logo does as well.
If you want the logo to change its size on zoom in/out, you could use sth like:
.container .logo {
width: 25em;
}
This way its using a width relative to pixel size (1em = 16px)

Trying to get horizontal touchpad scrolling working in Sly library on a Mac

I am trying to get the Sly library to scroll the FRAME div just from the trackpad of a Macbook Pro. To be clear, I am specifically looking for scrolling the items in my frame (inside the .slidee element) using the two finger gesture -- I am not interested in click-and-drag.
I have the following:
<div id="frame" class="frame">
<ul class="slidee">
<li>dkfsjdsakjf</li>
<!-- ... other items -->
</ul>
</div>
<div class="scrollbar-container">
<div id="scrollbar" class="scrollbar">
<div class="handle"></div>
</div>
</div>
<script>
var options = {
horizontal: 1,
itemNav: 'basic',
scrollBar: '#scrollbar',
dragHandle: true,
speed: 300,
mouseDragging: 1,
touchDragging: 1
};
$('#frame').sly(options);
</script>
The SCSS for these is here:
.frame { width: 100%; height: 160px; padding: 0; }
.frame .slidee { margin: 0; padding: 0; height: 100%; list-style: none; }
.frame .slidee li { float: left; margin: 0 5px 0 0; padding: 0; width: 120px; height: 100%; }
.scrollbar { width: 100%; height: 30px; }
.scrollbar .handle {
width: 100px; /* overriden if dynamicHandle: 1 */
height: 100%;
background: #222;
border-radius: 1em;
cursor: pointer;
}
.scrollbar-container {
background-color: lightgrey;
opacity: .5;
bottom: 1em;
padding: 1em;
width: inherit;
}
However, I am not able to horizontally scroll the #frame nor am I sure if that is a supported feature. Any help is greatly appreciated!

Website with a tricky structure with JS

Here is my tricky problem. I'm trying to do this:
http://www.hostingpics.net/viewer.php?id=767312test.gif
(More clear than an explication I think).
My structure :
<header></header>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img1.png"/></div>
</div>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img2.png"/></div>
</div>
<div class="section">
<div class="text"></div>
<div class="content"></div>
<div class="img"><img src="img3.png"/></div>
</div>
<footer></footer>
Important informations :
"Header" is fix
"Content" fit to the screen less the height of header
Every "section" are the same but with different content
When the image comes to an end, the "content" div is unfixed.
I am using "section" for implementing a next and previous button in the header (with anchors).
My problem is the scrolling part. I am really lost when I try to fix the "content" div. I don't know how to fix everything except the scroll of the image in the active "img" div when the active "content" div hits the header. (Everyone follows? Look here : http://www.hostingpics.net/viewer.php?id=767312test.gif
For the scrolling part in the "img" div, I was thinking use a sort of "overflow:scroll" but the scrollbar is really awful.
I don't know if it's enough clear. If there is any problem I can complete my problem. I am not very comfortable with complex structures in html with JS.
Thanks for your help!
This is pretty close to what you're asking for (using CSS only).
This relies on the fact that the backgrounds are solid colors. It uses various specifically-defined height properties as well that match some padding properties.
The .top-bar and .bottom-bar elements can probably be changed to pseudo elements if you don't want the extra HTML.
HTML:
<header>Header</header>
<div class="top-bar"></div>
<div class="bottom-bar"></div>
<div class="section">
<div class="text">Section 1 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/100/1000"/></div>
</div>
</div>
<div class="section">
<div class="text">Section 2 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/200/2000"/></div>
</div>
</div>
<div class="section">
<div class="text">Section 3 Text</div>
<div class="content">
<div class="img"><img src="http://placekitten.com/300/3000"/></div>
</div>
</div>
<footer>Footer</footer>
CSS:
body {
margin: 0;
padding: 100px 0 0;
}
header {
background-color: red;
height: 100px;
position: fixed;
top: 0;
width: 100%;
z-index: 10;
}
footer {
background-color: blue;
height: 100px;
}
.section {
min-height: 400px;
}
.text {
background-color: aqua;
height: 50px;
}
.content {
background-color: green;
min-height: 100%;
padding: 40px 0;
position: relative;
}
.img {
background-color: yellow;
min-height: 70%;
margin: 0 auto;
padding: 40px 0;
text-align: center;
width: 80%;
}
.img > img {
vertical-align: middle;
}
.top-bar, .bottom-bar {
background-color: green;
height: 40px;
position: fixed;
width: 100%;
z-index: 5;
}
.top-bar {
top: 100px;
}
.bottom-bar {
bottom: 0;
}
footer, .text {
position: relative;
z-index: 6;
}
JSFiddle here.
For an almost completely correct solution, here is one with some jQuery involved.
New CSS:
body {
margin: 0;
padding: 100px 0 0;
}
header {
background-color: red;
height: 100px;
position: fixed;
top: 0;
width: 100%;
z-index: 10;
}
footer {
background-color: blue;
height: 100px;
}
.section {
min-height: 400px;
}
.text {
background-color: aqua;
height: 50px;
}
.content {
background-color: green;
min-height: 100%;
padding: 40px 0;
position: relative;
}
.img {
background-color: yellow;
min-height: 70%;
margin: 0 auto;
padding: 40px 0;
text-align: center;
width: 80%;
}
.img > img {
vertical-align: middle;
}
.top-bar, .bottom-bar {
background-color: green;
height: 40px;
position: fixed;
width: 100%;
}
.top-bar {
top: 100px;
z-index: 5;
}
.bottom-bar {
bottom: 0;
z-index: 7;
}
footer, .text {
position: relative;
z-index: 8;
}
.img-fix {
bottom: 40px;
height: 400px;
overflow: hidden;
position: absolute;
width: 100%;
z-index: 6;
}
jQuery:
$(document).ready(function(){
$(".content").each(function(){
$(this).append($(this).html());
$(this).find(".img + .img").wrap("<div class='img-fix'></div>");
});
$(window).resize(function() {
resizeImgFix();
});
resizeImgFix();
});
function resizeImgFix() {
$(".img-fix").height($(window).height() - $("header").height() - $(".top-bar").height() - $(".bottom-bar").height());
$(".img-fix").each(function(){
$(this).scrollTop($(this).prop("scrollHeight"));
});
}
JSFiddle here.
Note: It duplicates the .img element and its children. This could be memory intensive depending. However, it does make it work as intended without any visual lag or artifacts.

Categories

Resources