Reputation: 153
I am using the following translateRange
function to calculate the range between multiple factors like this:
function translateRange(
input,
inputMin,
inputMax,
outputMin,
outputMax
) {
let inputMinA = Math.min(inputMin, input);
let inputMaxA = Math.max(inputMax, input);
return (
outputMin +
((outputMax - outputMin) * (input - inputMinA)) /
(inputMaxA - inputMinA)
);
};
let opacity = translateRange(
scrollY, //input
0, //animation start
100, //animation end
0, // from 0
1 // to
);
This works best, but i want to pass multiple values to the function. For e.g. i want to pass x
and y
values for transform
animations at the same time. How can i change the function to get this working? I would like to end with something like this:
let translate3d = translateRange(
scrollY,
0,
100,
[-10, -5], // x values (start and end)
[-4, 1] // y values (start and end)
);
When you scroll, i want to get the calculated values like this:
-10, -4 // x and y start values
Upvotes: 0
Views: 434
Reputation: 2844
I would not recommend doing thin in one single function. It gets quite messy keeping track of all the values.
A cleaner solution would be to calculate it separately for each input as done here:
https://jsfiddle.net/er0zyb4w/
If you want a single function that takes all the inputs: here you go:
(function() {
document.onmousemove = handleMouseMove;
})();
//https://stackoverflow.com/questions/7790725/javascript-track-mouse-position
function handleMouseMove(event) {
var eventDoc, doc, body;
event = event || window.event;
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
// Use event.pageX / event.pageY here
[opacity, rotation] = translateRange(
[event.pageX, event.pageY], //input
[0,0], //animation start
[500, 200], //animation end
[1, 0], // from
[0, 90] // to
);
const el = document.getElementById("test");
el.style.opacity = opacity;
el.style.transform = `rotate(${rotation}deg)`;
}
function translateRange(
inputs, // array of input values, x and y for example
inputsMin, // array of animation start values
inputsMax, // array of animation stop values
outputsMin, // array of output min values
outputsMax // array of output max values
) {
return inputs.map((_, i)=>{
let inputsMinA = Math.min(inputsMin[i], inputs[i]);
let inputsMaxA = Math.max(inputsMax[i], inputs[i]);
return (
outputsMin[i] +
((outputsMax[i] - outputsMin[i]) * (inputs[i] - inputsMinA)) /
(inputsMaxA - inputsMinA)
);
});
};
#test{
position: fixed;
top: 100px;
left: 100px;
width: 100px;
height: 100px;
background: red;
}
<div id="test"></div>
Move your mouse. <br/>
X - axis should change opacity 0 to 500px ==> opacity 1 to 0<br/>
Y - axis should change rotation 0 to 200px ==> rotation 0 to 90 degrees
Upvotes: 1
Reputation: 20699
Why not reuse your function like this?
function translateRange(
input,
inputMin,
inputMax,
outputMin,
outputMax
) {
let inputMinA = Math.min(inputMin, input);
let inputMaxA = Math.max(inputMax, input);
return (
outputMin +
((outputMax - outputMin) * (input - inputMinA)) /
(inputMaxA - inputMinA)
);
};
const translateArray = (input, inputMin, inputMax, outputMin, outputMax) =>
outputMax.map((_, i) => translateRange(input[i] ?? input, inputMin[i] ?? inputMin, inputMax[i] ?? inputMax, outputMin[i] ?? outputMin, outputMax[i] ?? outputMax));
const translate3d_1 = translateArray([0, 50], [0, 0], [100, 100], [-10, -5], [-4, 1]);
const translate3d_2 = translateArray(50, 0, 100, [-10, -5], [-4, 1]);
console.log(translate3d_1);
console.log(translate3d_2);
Upvotes: 1