Trying to create these kind of screen transitions – a sticky image, that then gets replaced with a similar version but on a different theme colour.
What scroll formula/value is being used to control the height of the white-holder element so that it replaces the dark mode with the light.
I’ve tried to increase the height of the container to test this component.
https://jsfiddle.net/5fprngcL/14/
$( document ).ready(function() {
console.log("ready")
var myElement = $(".white-mode-holder");
function setHeight(yPos, el) {
el.style.height = `${yPos}vh`;
}
$(document).scroll(function(e){
console.log("e", e)
let h = $("body").offset().top;
console.log("h", h)
setHeight(h*2, myElement[0])
});
});
html {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
font-family: sans-serif;
}
body {
color: #fff;
background-color: #000;
font-family: Manrope, sans-serif;
font-size: 14px;
line-height: 1.2;
}
.container {
max-width: 1170px;
margin-left: auto;
margin-right: auto;
padding: 2em;
height: 2000px;
}
img {
overflow-clip-margin: content-box;
overflow: clip;
}
* {
box-sizing: border-box;
}
img {
border: 0;
}
img {
max-width: 100%;
vertical-align: middle;
display: inline-block;
}
.dark-and-light-mode-container {
width: 100%;
height: 100vh;
position: -webkit-sticky;
position: sticky;
top: 0;
}
.dark-and-light-mode-sticky {
width: 100%;
height: 100vh;
flex-direction: column;
justify-content: space-between;
align-items: center;
display: flex;
position: relative;
}
.dark-mode-holder {
z-index: 1;
width: 100%;
height: 100vh;
background-color: #000;
flex-direction: column;
justify-content: flex-start;
align-items: center;
display: flex;
position: relative;
overflow: hidden;
}
.white-mode-holder {
z-index: 1;
width: 100%;
height: 50vh;
background-color: #fff;
flex-direction: column;
justify-content: flex-end;
align-items: center;
display: flex;
position: absolute;
top: auto;
bottom: 0%;
left: 0%;
right: 0%;
overflow: hidden;
}
.white-mode-holder{
will-change: width, height;
height: 0vh;
}
.center-iphone {
width: 100vw;
height: 100vh;
min-height: 100vh;
min-width: 100vw;
text-align: center;
flex-direction: column;
justify-content: center;
align-items: center;
display: flex;
position: relative;
}
.dark-mode-hand-holder {
z-index: 1;
width: 400px;
max-width: 400px;
min-width: 400px;
justify-content: center;
align-items: center;
margin: 80px 0 0;
display: flex;
position: relative;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.dark-mode-hand {
z-index: 1;
width: 400px;
position: relative;
}
.dark-mode-app {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 20px;
}
.dark-mode-app-holder {
padding: 2.6% 26% 26.2% 16%;
position: absolute;
top: 0%;
bottom: 0%;
left: 0%;
right: 0%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="container">
<div class="dark-and-light-mode-container">
<div class="dark-and-light-mode-sticky">
<div class="dark-mode-holder">
<div class="center-iphone">
<div class="dark-mode-hand-holder"><img src="https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand.webp" loading="eager" sizes="(max-width: 479px) 300px, 400px" srcset="https://assets.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand-p-500.webp 500w, https://assets.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand-p-800.webp 800w, https://assets.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand.webp 848w" alt="" class="dark-mode-hand">
<div class="dark-mode-app-holder"><img src="https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b576894fd22717696b9ead_Dark%20Mode.webp" loading="eager" alt="" sizes="232px" srcset="https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b576894fd22717696b9ead_Dark%20Mode-p-500.webp 500w, https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b576894fd22717696b9ead_Dark%20Mode-p-800.webp 800w, https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b576894fd22717696b9ead_Dark%20Mode.webp 1035w" class="dark-mode-app"></div>
</div>
</div>
</div>
<div class="white-mode-holder" style="will-change: width, height; height: 0vh;">
<div class="center-iphone">
<div class="dark-mode-hand-holder"><img src="https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand.webp" loading="eager" sizes="(max-width: 479px) 300px, 400px" srcset="https://assets.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand-p-500.webp 500w, https://assets.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand-p-800.webp 800w, https://assets.website-files.com/63aee5793ca698452efe7f60/63b5761b8fb633b42f3ad6c4_Iphone%20In%20Hand.webp 848w" alt="" class="dark-mode-hand">
<div class="dark-mode-app-holder"><img src="https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b57689b7dd5c5baa9e0780_Light%20Mode.webp" loading="eager" alt="" sizes="232px" srcset="https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b57689b7dd5c5baa9e0780_Light%20Mode-p-500.webp 500w, https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b57689b7dd5c5baa9e0780_Light%20Mode-p-800.webp 800w, https://cdn.prod.website-files.com/63aee5793ca698452efe7f60/63b57689b7dd5c5baa9e0780_Light%20Mode.webp 1036w" class="dark-mode-app"></div>
</div>
</div>
</div>
</div>
</div>
</div>
latest jsfiddle 11th Sep – using clip paths
2
Answers
This is the latest version I have for this - but the codesandbox seems broken
https://codesandbox.io/p/sandbox/plfszv
You can do this by setting up your cards positions to stack on top of each other. The top card would be initially set to absolute so the scroll can control it. Set the hands position to sticky so it sticks to its top position. The bottom card set to fixed with a display of none. Then set up a scroll event on the window and track the parent element, top card and hand image elements positions relative to each other and the window, you can then calculate the percentage of the cards scroll and change a clipPath when the parent containers bottom is with in the cards top and bottom bounds.
You will need to track the scrolling direction as well and affect the clipPath accordingly.
NOTE ON EDIT: I edited the snippet to reflect the images you used in your snippet.
See further comments in the snippet and let me know if anything is not clear.