I have a big button with an icon at the center. When the button is partially scrolled off the screen, I need an icon to be still at the center of the visible part of the button. Is it possible to achieve this with CSS sticky or JavaScript intersectionObserver?
This is what I need:
Here's the source code, https://jsfiddle.net/kasheftin/exjv8s5q/1/
const wrapper = document.querySelector('.wrapper')
const button = document.querySelector('.button')
const icon = document.querySelector('.icon')
wrapper.addEventListener('scroll', () => {
const wrapperBox = wrapper.getBoundingClientRect()
const buttonBox = button.getBoundingClientRect()
const iconBox = icon.getBoundingClientRect()
const my = (Math.max(wrapperBox.top, buttonBox.top) + Math.min(wrapperBox.bottom, buttonBox.bottom)) / 2
const y = Math.min(buttonBox.height - iconBox.height, Math.max(0, my - buttonBox.top - iconBox.height / 2))
icon.style.top = y + 'px'
const mx = (Math.max(wrapperBox.left, buttonBox.left) + Math.min(wrapperBox.right, buttonBox.right)) / 2
const x = Math.min(buttonBox.width - iconBox.width, Math.max(0, mx - buttonBox.left - iconBox.width / 2))
icon.style.left = x + 'px'
})
.wrapper {
width: 400px;
height: 300px;
overflow: scroll;
position: relative;
}
.container {
width: 1000px;
height: 1000px;
position: relative;
}
.button {
position: relative;
top: 300px;
left: 300px;
width: 200px;
height: 100px;
background-color: #dedede;
}
.icon {
position: absolute;
top: 0;
left: 0;
width: 20px;
height: 20px;
background-color: grey;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
<div class="wrapper">
<div class="container">
<div class="button">
<div class="icon">
+
</div>
</div>
</div>
</div>
However, I feel there must be a simpler way to achieve what I want using MutationObserver maybe, or something else, without getBoundingClientRect on every scroll.
