Reputation: 35
I have a simple inline SVG logo, it is all black, in my CSS I can tweak the colours, however, I would like to know how to dynamically change the colour of the logo as the user scrolls down the page. Let me elaborate...
So I have a simple site that conists of two sections on any given page, the order varies, one section has a black background with white text, the other, you guessed it, a white background with black text. I have a class of dark and light assigned to each section respectively. When a user scroll from a dark section to a light section (and vice versa), I would like the appropriate logo colour to switch.
I wondered if somebody could set me on the right track with how to do this using vanilla JS?
Update: it is not specically how to edit an SVG colour, it's more about how to use JS to determine when a region has been scrolled to and to change the colour of the SVG at the point at which the section changes from dark to light or vice versa.
Thanks
Upvotes: 2
Views: 787
Reputation: 122085
If you are able to select the sections and you know which ones are dark or light then you could use scroll event to check if the target element (svg) is inside the specific section and based on the background (class) of that section you change the class of the svg element.
function offset(element) {
const bodyRect = document.body.getBoundingClientRect()
const elemRect = element.getBoundingClientRect()
return elemRect.top - bodyRect.top;
}
function handler(event) {
const header = document.querySelector('.logo');
const dark = document.querySelectorAll('.dark-section');
const headerOffset = offset(header)
const headerHeight = header.clientHeight;
const check = [...dark].some(section => {
const sectionOffset = offset(section);
const sectionHeight = section.clientHeight;
const topCheck = headerOffset + headerHeight / 2 >= sectionOffset;
const bottomCheck = headerOffset + headerHeight / 2 < sectionOffset + sectionHeight
if (topCheck && bottomCheck) {
return true
}
})
if (check) {
header.classList.add('light')
header.classList.remove('dark')
} else {
header.classList.add('dark')
header.classList.remove('light')
}
}
['scroll', 'resize'].forEach(function(e) {
window.addEventListener(e, handler);
});
body,
html {
margin: 0;
padding: 0;
}
header {
height: 50px;
position: fixed;
background: rgba(51, 51, 5, 0.25);
left: 0;
top: 0;
width: 100%;
}
svg {
height: 50px;
width: 50px;
}
section {
min-height: 100vh;
}
section.dark-section {
background: black;
}
.light circle {
fill: white;
transition: all 0.2s ease-in;
}
.dark circle {
fill: black;
transition: all 0.2s ease-in;
}
<header>
<svg class="logo">
<circle fill="white" cx="50%" cy="50%" r="15"/>
</svg>
</header>
<section class="dark-section"></section>
<section></section>
<section class="dark-section"></section>
<section></section>
You could also do something similar using mix-blend-mode: difference
in css but the color of the svg will depend on the color of the section so you cannot just set it to change to specific color.
body,
html {
margin: 0;
padding: 0;
}
section {
height: 100vh;
background-color: white;
}
section.dark-section {
background-color: black;
}
header {
mix-blend-mode: difference;
width: 100%;
position: fixed;
background: none;
border: none;
padding: 0;
top: 0;
left: 0;
}
svg {
position: absolute;
top: 0;
left: 0;
width: 50px;
height: 50px;
}
.light-svg {
display: block;
}
.dark-svg {
display: none;
}
<header>
<svg class="logo">
<circle fill-rule="nonzero" fill="#FFFFFF" cx="50%" cy="50%" r="15"/>
</svg>
</header>
<section class="dark-section"></section>
<section></section>
<section class="dark-section"></section>
<section></section>
Upvotes: 2