To rotate a gradient you need to understand (and deconstruct) the linear-gradient
(which is, in fact, a background-image
). A good rundown can be found on MDN and the official spec is on CSSWG (W3C).
The first thing to know about it is that you can't move it's center. Since it is the element's background, the center of the gradient will always be the center of the element.
Note: If your design requires different rotation centers, you can always use more than 1 element and size them accordingly.
Now, let's assume you want to rotate the first gradient from 70deg
to 110deg
and the second one from 20deg
to 155deg
.
A quick search for scroll event
will (hopefully) get you on MDN's page, which has an example.
Coupling it with the above, you get something along these lines (I placed the logic for rotating the backgroundImage inside the example's doSomething
function).
I've also specified where I've taken each bit from, to show how to go about documenting your question, step by step. Point here being: every bit you can do yourself, do it and only leave out the bits you don't know.
let last_known_scroll_position = 0;
let ticking = false;
// helpers
const body = document.querySelector('body');
const html = document.querySelector('html');
function doSomething(scroll_pos) {
// from https://stackoverflow.com/a/1147768/1891677 :
const bodyHeight = Math.max( body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight);
// from https://stackoverflow.com/a/8876069/1891677 :
const viewportHeight = Math.max(document.documentElement.clientHeight,
window.innerHeight || 0);
// set scrollPercentage, if we have available scroll (0 otherwise):
const availableScroll = bodyHeight - viewportHeight;
const percentage = availableScroll > 0 ? scroll_pos * 100/availableScroll : 0;
// this is what the question is about:
const fromPercent = (from,to,current) => ((to - from) * current/100) + from;
body.style.backgroundImage = `
linear-gradient(${fromPercent(70, 110, percentage)}deg, #5870cb 20%, rgba(0,0,0,0) 0),
linear-gradient(${fromPercent(20, 155, percentage)}deg, white 85%, #5870cb 2%)
`;
}
// rest of example, from MDN:
window.addEventListener('scroll', function(e) {
last_known_scroll_position = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function() {
doSomething(last_known_scroll_position);
ticking = false;
});
ticking = true;
}
});
body {
font-family: 'Roboto Mono', monospace;
background-image: linear-gradient(70deg, #5870cb 20%, rgba(0,0,0,0) 1%),
linear-gradient(20deg, white 85%, #5870cb 2%);
background-position: center;
background-repeat: no-repeat;
background-size: cover;
background-attachment: fixed;
height: 300vh;
}