LERP Smooth Scrolling - javascript

I have been wanting to implement smooth scrolling in vanilla JS for some time, but could not find any adequate implementations or methods. However, I recently came across the concept of linear interpolation (LERP), which seems adequate unlike every other method.
Although content about LERP smooth scrolling seems scarce on the web, I just found two great articles (one, two) about LERP in general and an example of LERP being used for smooth scrolling on codepen.
The example, notably, seems unnecessarily complex due to a seemingly unnecessary amount of nested containers, so I created a minimal version of it shown below. The minimal version seems to be working, but I still have a few concerns and questions.
const
b = document.body,
m = document.querySelector('main'),
p = document.querySelector('p')
let
state = {
scroll: {
height: 0,
offset: 0,
speed: 0.075,
}
},
direction
document.addEventListener('DOMContentLoaded', () => {
state.scroll.height = m.getBoundingClientRect().height
b.style.height = `${Math.floor(state.scroll.height)}px`
})
b.addEventListener('wheel', (e) => {
direction = e.deltaY > 0 ? 'scrollDown' : 'scrollUp'
// renderLoop()
})
function renderLoop() {
// const
// difference = 'scrollDown' ? pageYOffset - state.scroll.offset : state.scroll.offset - pageYOffset
state.scroll.offset += Math.floor((pageYOffset - state.scroll.offset) * state.scroll.speed)
m.style.transform = `translateY(-${ state.scroll.offset }px)`
// if (difference > 20) requestAnimationFrame(renderLoop)
requestAnimationFrame(renderLoop)
}
renderLoop()
html, body {
width: 100%;
height: 100%;
margin: 0;
font-size: 48px;
}
main {
width: 100%;
position: fixed;
left: 0;
top: 0;
border: solid green 3px; box-sizing: border-box;
}
p {
width: 100%;
max-width: 500px;
position: relative;
left: 50%;
transform: translateX(-50%);
margin: 0;
border: solid red 3px; box-sizing: border-box;
}
<main>
<p>One<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Two<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Three<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
</main>
One concern is that for some reason it breaks unless I call renderLoop from the global scope and let requestAnimationFrame run indefinitely without a killswitch, which, instinctively, does not seem like a good idea?
I am also confused by the fact that, although I am offsetting the content container via translate, there still appears to be a scrollbar that scrolls. And yet, notably, this does not appear to interfere with the effect at all. However, should LERP smooth scrolling via translate not bypass scrollbars and scrolling altogether?
Additionally, it seems as though the only purpose of setting the height of body to that of main is to make use of pageYOffset. I suspect there are better ways to approach the problem that do not involve using pageYOffset. Further, you would think that the combination of offsetting with translate and the page being scrolled would increase the rate at which the content is scrolled?
Anyways, I have just started coding again after an almost year-long absence, and I am not sure if I ever familiarized myself with requestAnimationFrame, so any information, guidance, or solutions would be greatly appreciated.
[ edit + update ]
Here is a codepen of a "working" (?) version, which can be seen below, that I created in attempt to address and solve some concerns or issues present in the version above. However, it clearly does not have the same effect due to, I believe, the offset value being a percentage instead of pixels, which was chosen in an attempt to standardize the "speed" at which it scrolls across "platforms" (i.e. devices, browsers, etc).
const
b = document.body,
m = document.querySelector('main')
let
scrollState = {
overflow: 0,
target: 0,
position: 0,
rate: 10,
speed: 0.2
}
b.addEventListener('wheel', (e) => {
scrollState.target -= scrollState.rate * (e.deltaY / 100)
if (scrollState.target > 0) scrollState.target = 0
else if (scrollState.target < -100) scrollState.target = -100
renderLoop()
})
function renderLoop() {
const
rawDiff = Math.abs(scrollState.position - scrollState.target),
direction = scrollState.position - scrollState.target < 0 ? -1 : 1,
diff = rawDiff * scrollState.speed * direction,
newPosition = scrollState.position - diff
m.style.transform = `translateY(${newPosition}%)`
scrollState.position = newPosition
if (Math.floor(rawDiff)) requestAnimationFrame(renderLoop)
}
html, body {
width: 100%;
height: 100%;
margin: 0;
font-size: 48px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
border: solid blue 4px; box-sizing: border-box;
}
main {
width: 100%;
position: fixed;
left: 0;
top: 0;
border: solid green 2px; box-sizing: border-box;
}
p {
width: 100%;
max-width: 500px;
position: relative;
left: 50%;
transform: translateX(-50%);
margin: 0;
border: solid red 2px; box-sizing: border-box;
}
<main>
<p>One<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Two<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
<p>Three<br>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Error soluta, quidem voluptatibus quo iusto iure adipisci, ullam quis unde dolore, nisi impedit in. Veniam, suscipit? Atque aut et incidunt aliquid. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Exercitationem labore dolore aut atque harum, quo necessitatibus molestias laborum fuga beatae explicabo laudantium asperiores doloremque optio iure, assumenda voluptate unde voluptates? Lorem ipsum dolor sit amet consectetur adipisicing elit. Amet inventore, voluptates corrupti illo impedit in. Recusandae, praesentium temporibus tempore totam cupiditate ratione maxime numquam corporis repudiandae. Veniam ullam rerum quo?</p>
</main>

#oldboy, I'm having the same issue regarding the scarcity of LERP + smooth scrolling on the web. Nevertheless, here is a slightly different approach involving smooth vertical scroll + LERP with a kill switch. It might not be perfect yet but it could be the building block to expand upon.
const slider = document.querySelector('.slider');
const track = document.querySelector('.slider-track');
let startY = 0;
let endY = 0;
let raf;
const lerp = (start,end,t) => start * (1-t) + end * t;
function update() {
startY = lerp(startY,endY,0.05);
track.style.transform = `translateY(-${startY}px)`;
raf = requestAnimationFrame(update);
if (startY.toFixed(1) === slider.scrollTop.toFixed(1)) cancelAnimationFrame(raf);
}
function move() {
endY = slider.scrollTop;
cancelAnimationFrame(raf);
raf = requestAnimationFrame(update);
}
window.addEventListener('load',update,false);
slider.addEventListener('scroll',move,false);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.slider {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
width: min(600px,90vw);
height: 90vh;
border: 1px solid rgba(0,0,0,0.5);
overflow-y: scroll;
}
.slider-track {
position: absolute;
width: 100%;
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
}
.slider-item {
width: inherit;
height: 70vh;
border: 0.5px solid rgba(0,0,0,0.5);
display: grid;
place-items: center;
font: 900 0.85rem helvetica,sans-serif;
}
::-webkit-scrollbar { width: 1rem; }
::-webkit-scrollbar-track { border-left: 0.5px solid rgba(0,0,0,0.5); }
::-webkit-scrollbar-thumb {
border: 0.5px solid rgba(0,0,0,0.5);
border-right: none;
border-left: none;
}
<main class='slider'>
<div class='slider-track'>
<div class='slider-item'>1</div>
<div class='slider-item'>2</div>
<div class='slider-item'>3</div>
<div class='slider-item'>4</div>
<div class='slider-item'>5</div>
<div class='slider-item'>6</div>
<div class='slider-item'>7</div>
<div class='slider-item'>8</div>
<div class='slider-item'>9</div>
</div>
</main>
Overview:
create a function to run the LERP formula
const lerp = (start,end,t) => start * (1-t) + end * t;
when our project "load", do the following:
a) invoke the callback "update" & update the starting y-position aka "startY" with "lerp". "0.05" is the "easing" which can range from "0.01 to "0.99"
startY = lerp(startY,endY,0.05);
b) move our slider's "track" vertically with "translateY" + negative "startY" in pixels
track.style.transform = translateY(-${startY}px);
c) invoke "update" recursively with "requestAnimationFrame" and store it in "raf"
raf = requestAnimationFrame(update);
d) if "startY" is equal to "slider.scrollTop" to the nearest tenths then cancel "raf" (kill switch)
if (startY.toFixed(1) === slider.scrollTop.toFixed(1)) cancelAnimationFrame(raf);
lastly, whenever the "scroll" event is trigged on "slider" then:
a) invoke the callback "move" & track the current y-position aka "endY" with the "scrollTop" property on "slider"
endY = slider.scrollTop;
b) cancel "raf" (kill switch)
cancelAnimationFrame(raf);
c) invoke "update" recursively with "requestAnimationFrame"
cancelAnimationFrame(raf);
Please do drop me a comment when you improve upon this approach or your own code, I like to check'em out :)

Related

why is this tetx not overflowing on the x axis even though I have a fixed width and the <p tag is set to display: block?

I need the text to overflow on the X axis just to reproduce some issue that I'm having on a bigger project. I leave a simple snippet, so you can tell me where I'm doing it wrong. Thanks!
.article {
background-color: rgb(236, 161, 161);
width: 20em;
}
.article p {
display: block;
}
<article class="article">
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Perferendis deleniti iure quidem distinctio officia voluptates similique molestiae culpa? Perferendis, velit maiores nobis maxime aut facere eaque quis voluptas accusamus commodi.</p>
</article>
If you want the p tag to overflow on the x-axis, you simply need to tell it not to wrap using the white-space property:
article{
width: 20em;
background-color: rgb(236, 161, 161);
}
article p{
display: block;
/* Do NOT break the text onto a new line when it reaches the container bounds. */
white-space: nowrap;
}
<article>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Perferendis deleniti iure quidem distinctio officia voluptates similique molestiae culpa? Perferendis, velit maiores nobis maxime aut facere eaque quis voluptas accusamus commodi.
</p>
</article>

Javascript: automatical horizontal scrolling

I have a simple javascript code that automatically scrolls the div element horizontaly.
Is there any option how to make it smoother and more effective? I have code where same parts are repeating and that's not good.
I'm trying to make smooth scrolling without any cuts.
setTimeout(function() {
document.querySelector("div").scrollLeft = 50;
},2000);
setTimeout(function() {
document.querySelector("div").scrollLeft = 100;
},4000);
setTimeout(function() {
document.querySelector("div").scrollLeft = 150;
},6000);
p {
width: 2000px;
}
div {
overflow: scroll;
}
<div>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque consequuntur quas libero voluptatem recusandae necessitatibus inventore, velit aperiam, incidunt ut eos distinctio, ducimus magnam veritatis tenetur autem debitis iusto dolorum?</p>
</div>
You could use a short setInterval() to smoothly scroll the div:
var boo = document.getElementById("boo");
function move() {
boo.scrollLeft += 1;
}
setInterval(move, 20)
p {
width: 2000px;
}
div {
overflow: scroll;
}
<div id="boo">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Atque consequuntur quas libero voluptatem recusandae necessitatibus inventore, velit aperiam, incidunt ut eos distinctio, ducimus magnam veritatis tenetur autem debitis iusto dolorum?</p>
</div>

Changing text in page div

im trying to make something like text rotator.
When i click on About tab i want to show only about info, when i click on projects i want to delete about text and replace it with project text and same with other depending which i actually press.
I can make it to appear one under another. But that's not what i want. Hope you guys understand what i want to do.
DON'T WRITE IT FOR ME! Just please tell me where i should look for it, should i use loop?
HTML:
<main>
<div class="menuContainer">
<ul>
<li class="about" id="about">
<h2>O mnie</h2>
</li>
<li class="projects" id="projects">
<h2>Projekty</h2>
</li>
<li class="empty">
<div class="circle"></div>
</li>
<li class="technology" id="technology">
<h2>Technologie</h2>
</li>
<li class="contact" id="contact">
<h2>Kontakt</h2>
</li>
</ul>
</div>
<div class="poleDoZmiany">
<p id="doZmiany" class="zmiana">
Welcome Lorem ipsum dolor, sit amet consectetur adipisicing elit. Suscipit culpa labore temporibus fugiat eum error hic illo perspiciatis dignissimos, corporis, aut sapiente sint numquam!
</p>
</div>
<p id="Tekst1">Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur, natus nam! Excepturi ipsam voluptates magni odio adipisci, officia consequuntur praesentium eos cumque exercitationem soluta, eveniet dolor sed reiciendis asperiores modi pariatur placeat animi, debitis ratione. Hic illo incidunt, praesentium excepturi vero perspiciatis corrupti maxime accusamus, iusto repellendus quam id. </p>
<p id="Tekst2">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Possimus sint modi quisquam autem perferendis maxime impedit sed. Doloremque, reprehenderit neque perspiciatis facere quia saepe architecto odio aspernatur, voluptas nobis blanditiis, quisquam beatae?
</p>
<p id="Tekst3">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, facilis. Deserunt, in.
</p>
<p id="Tekst4">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Iure fugiat sequi accusantium inventore asperiores magnam impedit sit maiores praesentium! Ea exercitationem, veritatis placeat blanditiis vitae iste, cupiditate asperiores voluptate cumque quisquam ipsam repellat accusamus debitis omnis aliquid! Iste rerum consectetur impedit porro molestias numquam. Facere eveniet at dolorum deleniti! Facilis nisi ut beatae laudantium nulla culpa amet neque inventore at minus. Reiciendis distinctio ab voluptas! Earum excepturi corporis odit?
</p>
CSS:
main {
width: 80%;
position: absolute;
left: 10%;
top: 35vh;
background: white;
-webkit-box-shadow: 0px 0px 34px 2px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 0px 34px 2px rgba(0,0,0,0.75);
box-shadow: 0px 0px 34px 2px rgba(0,0,0,0.75);
}
main p {
margin-top: 90px !important;
margin: 25px;
padding: 25px;
text-align: center;
}
.media {
text-align: center;
}
.media > img {
padding: 10px;
}
p {
display: none;
}
#doZmiany {
display: block;
}
JAVASCRIPT:
let tekst1 = document.getElementById('Tekst1');
let tekst2 = document.getElementById('Tekst2');
let tekst3 = document.getElementById('Tekst3');
let tekst4 = document.getElementById('Tekst4');
var zmiana = document.getElementById('doZmiany');
const oMnie = document.getElementById('about');
const projekty = document.getElementById('projects');
oMnie.addEventListener('click', function(){
tekst1.classList.add('zmiana');
})
projekty.addEventListener('click', function(){
tekst2.classList.add('zmiana');
})
You're almost there. Keep in mind, that you need to hide all the paragraphs you don't want to show with every click. So a loop is a good idea.
And then show the one and only.
Here is a code snippet that does something like that a little different from your approach in case you get stuck. Go on with your solution!
document.getElementById('tablist').addEventListener('click', function(e){
const tabs = ['tab1', 'tab2'];
const ti = tabs.indexOf(e.target.id);
if(ti !== false){
for(let i = 0; i < tabs.length; i += 1) {
if(ti !== i){
document.getElementById(tabs[i]+'Txt').style.display = 'none';
}
}
document.getElementById(tabs[ti]+'Txt').style.display = 'block';
}
});
.hiddenText {
display: none;
}
<ul id="tablist">
<li id="tab1">tab1</li>
<li id="tab2">tab2</li>
</ul>
<p id="tab1Txt" class="hiddenText">
This is tab1Txt.
</p>
<p id="tab2Txt" class="hiddenText">
This is tab2Txt.
</p>
For your tabs, add a class called tab and for all of your content paragraphs, give them a class of tab-content.
Then create a click event for the class of tab. In the click event get the ID of what is being clicked on and use that to determine the content to be shown. First, hide ALL of tab-content paragraphs, then only show the paragraph based on the passed ID.

How to automatically cut text to fit fixed block size?

I have block with width in % and height in rem and I need to fill it with random-length text. I need the number of visible lines (block has overflow:hidden) to be integer and the last line to end with "...read full text" link. Of course, this must work for every font/line size and any page scale.
How to realize this?
https://jsfiddle.net/2go48yum/
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tenetur distinctio tempore porro voluptatum iste, pariatur. Nam ea alias aliquam nesciunt, tenetur autem nisi laborum officiis voluptatibus laudantium esse, ut reiciendis? ipsum dolor sit amet,
consectetur adipisicing elit. Illum quisquam, natus in similique consequatur officia aperiam vel voluptatibus, beatae possimus. Vero ab rerum ratione doloremque veritatis totam quas facere porro. ipsum dolor sit amet, consectetur adipisicing elit. Delectus
est dolorem laborum eius quia architecto, adipisci tempora blanditiis, nisi aliquid expedita numquam debitis. Commodi perspiciatis, inventore accusantium animi quas</div>
.content {
width: 50%;
height: 15rem;
overflow: hidden;
}
p { margin: 0; padding: 0; font-family: sans-serif;}
.ellipsis {
overflow: hidden;
height: 200px;
line-height: 25px;
margin: 20px;
border: 1px solid #AAA;
}
.ellipsis:before {
content:"";
float: left;
width: 5px; height: 200px; }
.ellipsis > *:first-child {
float: right;
width: 100%;
margin-left: -5px; }
.ellipsis:after {
content: "\02026";
box-sizing: content-box;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
float: right; position: relative;
top: -25px; left: 100%;
width: 3em; margin-left: -3em;
padding-right: 5px;
text-align: right;
background-size: 100% 100%;
}
<div class="ellipsis"><div>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tenetur distinctio tempore porro voluptatum iste, pariatur. Nam ea alias aliquam nesciunt, tenetur autem nisi laborum officiis voluptatibus laudantium esse, ut reiciendis? ipsum dolor sit amet,
consectetur adipisicing elit. Illum quisquam, natus in similique consequatur officia aperiam vel voluptatibus, beatae possimus. Vero ab rerum ratione doloremque veritatis totam quas facere porro. ipsum dolor sit amet, consectetur adipisicing elit. Delectus
est dolorem laborum eius quia architecto, adipisci tempora blanditiis, nisi aliquid expedita numquam debitis. Commodi perspiciatis, inventore accusantium animi quas</p>
</div></div>
For infos and not reliable.
With CSS you could try using mix-blend-mode and position:sticky. But most of the browser will not play it (At this time, FF&Chrome understand both mix-blend-mode and sticky ).
.content {
float: left;
border: solid;
margin: 1%;
width: 45%;
height: 11rem;
overflow: hidden;
background: yellow;
text-align: justify;
/*text-align-last:justify;for test purpose only */
}
.content:after {
position: sticky;
bottom: 0;
float: right;
margin-left: -1em;
width: 1em;
content: '...';
display: inline-block;
background: inherit;
mix-blend-mode: screen;
z-index: 1;
}
.disclaimer {
mix-blend-mode: difference;
}
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tenetur distinctio tempore porro voluptatum iste, pariatur. Nam ea alias aliquam nesciunt, tenetur autem nisi laborum officiis voluptatibus laudantium esse, ut reiciendis? ipsum dolor sit amet,
consectetur adipisicing elit. Illum quisquam, natus in similique consequatur officia aperiam vel voluptatibus, beatae possimus. Vero ab rerum ratione doloremque veritatis totam quas facere porro. ipsum dolor sit amet, consectetur adipisicing elit. Delectus
est dolorem laborum eius quia architecto, adipisci tempora blanditiis, nisi aliquid expedita numquam debitis. Commodi perspiciatis, inventore accusantium animi quas</div>
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tenetur distinctio tempore porro voluptatum iste, pariatur. Nam ea alias aliquam nesciunt, tenetur autem nisi laborum officiis voluptatibus laudantium esse, ut reiciendis? <br/>
<b class="disclaimer">If you see this text, mix-blend-mode is not supported</b></div>

ScrollMagic element is being triggered on page load automatically

I have a graphic element positioned at the bottom center of my page that is supposed to fade-in when you start scrolling down.
I am using ScrollMagic JS
The problem is that element is being displayed automatically whenever I reload the page and then fades out. And after I start scrolling down, it fades back in again and starts working normally.
I need to hide on initial page load.
How may I achieve that? Because adding display: none to the element simply hides it all together.
I would also like to use a different kind of animation, instead of ease-out in CSS, I would like to use something that makes the graphic element to look like as it is rising up and rising down.
Similar to this site here: http://lempens-design.com/
DEMO https://jsfiddle.net/jtLo27op/3/
HTML
<div class="intro">
<div class="background_image"></div>
<div class="container-fluid height100">
<div class="row height100">
<div class="col-md-12 text-center height100">
<img src="assets/img/logo.png" alt="Logo" class="logo">
<div id="animate" class="city-vector">
<img src="assets/img/skyline.png" alt="Skyline" class="skyline">
</div>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut!</h1>
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut!</h1>
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut!</h1>
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut!</h1>
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut!</h1>
<h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur distinctio facilis fugit quasi quisquam quos recusandae rerum sunt temporibus voluptates? A, ipsa labore laudantium non recusandae suscipit vel voluptas. Aut!</h1>
</div>
</div>
CSS
html, body {
width: 100%;
height: 100%;
}
body {
background-color: #191617;
}
.height100 {
height: 100%;
}
.logo {
width: 220px;
margin-top: 10em;
}
.skyline {
display: block;
max-width: 100%;
position: absolute;
bottom:0;
left:50%;
transform:translateX(-50%);
}
.city-vector {
opacity: 1;
transition: all 3s ease-out;
}
.city-vector.fade-in {
opacity: 0;
}
.intro {
height: 100%;
position: relative;
overflow: hidden;
}
.intro::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: url('../img/bg/bg5.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
height: 100%;
-webkit-filter: blur(3px);
-moz-filter: blur(3px);
-o-filter: blur(3px);
-ms-filter: blur(3px);
filter: blur(3px);
transform: scale(1.01);
}
Javascript
$(document).ready(function() {
var controller = new ScrollMagic.Controller();
var ourScene = new ScrollMagic.Scene({
triggerElement: '#animate',
duration: 361
})
.setClassToggle('#animate', 'fade-in')
.addTo(controller);
});
You have to change your CSS code:
.city-vector {
opacity: 0;
transition: all 3s ease-out;
}
.city-vector.fade-in {
opacity: 1;
}
Updated JSfiddle
UPDATE: Okay, for the function you want, you don't need any external libraries. I don't have any experience with ScrollMagic, so I just didn't use it. I've also added the animation that makes it "rise out of the page" through CSS.
JSfiddle
jQuery
$(document).ready(function() {
$(window).scroll(function() { //run function every time window is scrolled
var scroll = $(window).scrollTop(); //find how much is scrolled from top
if (scroll > 0) { // if the scroll from top is greater than zero...
$("#animate").addClass("fade-in"); //then add class
} else { // if the scroll from top is not greater than zero...
$("#animate").removeClass("fade-in"); //then remove class
}
});
});
CSS animation:
.skyline {
display: block;
max-width: 100%;
position: absolute;
bottom: 0;
opacity: 0; /* I removed this in update */
transition: all 3s ease-out; /* Changed animation duration to 0.5s */
left: 50%;
transform: translate(-50%, 100%);
}
.city-vector.fade-in .skyline {
transform: translate(-50%);
opacity: 1; /* and this */
}
UPDATE: New JSfiddle with "snappish" effect.

Categories