Issue
I inspected many ways how to do different parts of the task such as change opacity on scroll or change position on scroll but still don't understand how to put it together.
What I need:
There is a container that has 4 words that goes in a row. Only 1 word is visible at one time and then another words has to appear from right on scroll down and vice versa on scroll up and so on with each word. I created visual example of what I want:
Step 1:
User begins scrolling and text starting appearing from right (example shows text 1 and text 2 but it has to be related to each text in the row)
Step 2:
User keeps scrolling and text 2 goes on the position of text 1 one while text 1's transparency becomes less
Next steps:
It's shown on the last 2 images that in the end text 1 disappears with opacity: 0;
and text 2 stands on its place
Example above is shown on scroll down but when user scrolls up it should work in reverse way and it should work so when user scrolled for text 2 and keeps scrolling, text 3 appears and so on
Unfortunately I cannot share the code I tried because I can't even imagine a way how to approach for this task. But I had some ideas such as create 2 slider current and next or something like that.
I hope description with images is clear enough because I'm not even sure if I understand it right
Solution
Increase the height of the <body>
element arbitrarily to introduce a vertical scroll.
body {
height: 9999px;
background-color: #333;
}
Create a container for the words. Use position: fixed
to keep the container on screen when we scroll.
body {
height: 9999px;
background-color: #333;
}
.words {
position: fixed;
width: 300px;
height: 200px;
background-color: white;
}
<div class="words">
</div>
Add in the texts, on top of each other inside the container.
body {
height: 9999px;
background-color: #333;
}
.words {
position: fixed;
width: 300px;
height: 200px;
background-color: white;
}
.word {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: red;
}
<div class="words">
<div class="word">Foo</div>
<div class="word">Bar</div>
<div class="word">Baz</div>
</div>
Have the all words apart from the first to the extreme right of the container. The 170px
is an arbitrary amount that is enough to move both the other words off the screen. Clip them out of visibility by applying overflow: hidden
to the container.
body {
height: 9999px;
background-color: #333;
}
.words {
position: fixed;
width: 300px;
height: 200px;
background-color: white;
overflow: hidden;
}
.word {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: red;
}
.word:nth-child(n + 2) {
transform: translate(calc(170px - 50%), -50%);
}
<div class="words">
<div class="word">Foo</div>
<div class="word">Bar</div>
<div class="word">Baz</div>
</div>
Write JavaScript that updates a CSS variable when we scroll.
const container = document.querySelector('.words');
window.addEventListener('scroll', () => {
container.style.setProperty('--scroll', window.scrollY);
});
body {
height: 9999px;
background-color: #333;
}
.words {
position: fixed;
width: 300px;
height: 200px;
background-color: white;
overflow: hidden;
}
.word {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: red;
}
.word:nth-child(n + 2) {
transform: translate(calc(170px - 50%), -50%);
}
<div class="words">
<div class="word">Foo</div>
<div class="word">Bar</div>
<div class="word">Baz</div>
</div>
Use this CSS variable to apply opacity
and adjust the transform
properties of the .word
elements. This example passes how many pixels the document has been scrolled as-is to --scroll
. You may wish to process this value to adjust the amount this affects the CSS or you could also adjust the maths in the CSS.
const container = document.querySelector('.words');
window.addEventListener('scroll', () => {
container.style.setProperty('--scroll', window.scrollY);
});
body {
height: 9999px;
background-color: #333;
}
.words {
position: fixed;
width: 300px;
height: 200px;
background-color: white;
overflow: hidden;
--segment-length: 200;
}
.word {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: red;
opacity: calc(((var(--opacity-point) * var(--segment-length)) - var(--scroll, 0)) / var(--segment-length));
}
.word:nth-child(n + 2) {
transform: translate(calc(clamp(0%, 170px * ((var(--translate-point) * var(--segment-length)) - var(--scroll, 0)) / var(--segment-length), 170px) - 50%), -50%);
}
.word:nth-child(1) {
--opacity-point: 1;
}
.word:nth-child(2) {
--opacity-point: 2;
--translate-point: 1;
}
.word:nth-child(3) {
--opacity-point: 3;
--translate-point: 2;
}
<div class="words">
<div class="word">Foo</div>
<div class="word">Bar</div>
<div class="word">Baz</div>
</div>
This code transitions between words every 200px
scrolled. This is denoted by our value for --segment-length
.
Answered By - Wongjn
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.