【发布时间】:2022-11-21 17:41:12
【问题描述】:
我有一个非常小的问题,但不幸的是我无法解决它,所以我希望有人能帮助我,所以我正在尝试制作滚动动画并使用 css matrix 属性移动一些元素并且矩阵具有此参数
scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY()
所以我使用 scale 和 translateX 和 translateY 来动画和移动元素,
我使用 scrollY 位置值来知道何时开始动画并使用 y 位置值像这样移动元素
matrix(1, 0, 0, 1, ${yPositionValue}, -35)
因此,当用户滚动 y 值递增或递减时,现在我解决问题的第一种方法是对值进行硬编码,如果 yScroll 值为 1000,那么我希望动画开始,所以如果值为 1000 然后从滚动 Y 位置减去 1000 然后我将从 0 开始然后我将移动我的元素直到我希望它们停止,因为你可以看到这是一个愚蠢的方式有很多如果,所以我认为是好的方法是使用滚动 y 位置值并根据从最小值和最大值开始的 y 值生成一个新数字,所以我尝试下一个
所以我的第一个问题是什么时候开始动画,我使用 Observer API 并使用阈值,所以如果元素的 50% 是可见的,那么我开始动画,知道滚动位置我使用最小值和最大值像这样给我一个介于两个值之间的数字
const PositionValue = (Math.min(250, Math.max(0, yOffset)));
所以 yOffset 是 y 滚动位置这个代码工作得很好但是问题是我它不能很好地处理小数字就像如果我想要一个介于 0.55 和 1.0 之间的数字它不会给出我想要的所以而不是这个
const PositionValue = (Math.min(1, Math.max(0.55, yOffset)));
我做了这个
const PositionValue = (Math.min(100, Math.max(55, yOffset))) / 100;
所以我可以得到 0.55、1.0 之间的数字,我想翻转这个数字所以我不想从 0.55 开始到 1.0 我想从 1.0 到 0.55 开始,我试图创建一个变量并分配一个 1,如果 PositionValue 更大,那么0.55 它将递减 0.01,我想要的只是一种根据 y 值生成数字的方法,我知道有一个像 GSAP 这样的库,但我喜欢自己制作它,我使用 React 这是我的完整代码
// observer testing
const [isIntersectionRatioComplete, setisIntersectionRatioComplete] = useState(false);
const observerElement = useRef(null);
const leftSwitchRef = useRef(null);
const centerSwitchRef = useRef(null);
const rightSwitchRef = useRef(null);
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: []
}
let cenetrSwitchScalingValue = 1;
const HandelScrollTriggerAnimation = () => {
const yOffset = window.pageYOffset - 1230;
if (yOffset > 0) {
const SwitchPositionValue = (Math.min(250, Math.max(0, yOffset)));
// const cenetrSwitchScalingValue = (Math.min(100, Math.max(56, yOffset))) / 100; // 0.56, 1
if (cenetrSwitchScalingValue >= 0.56) {
cenetrSwitchScalingValue = cenetrSwitchScalingValue - 0.01;
}
if (leftSwitchRef.current && centerSwitchRef.current && rightSwitchRef.current) {
leftSwitchRef.current.style.transform = `matrix(1, 0, 0, 1, ${-SwitchPositionValue}, -35)`;
centerSwitchRef.current.style.transform = `matrix(${cenetrSwitchScalingValue}, 0, 0, ${cenetrSwitchScalingValue}, 70, ${-SwitchPositionValue})`;
rightSwitchRef.current.style.transform = `matrix(1, 0, 0, 1, ${SwitchPositionValue}, -35)`;
} return
} return
}
const observerCallbackFunction = (entries) => {
const [ entry ] = entries;
if (entry.intersectionRatio >= 0.1) { //0.5
// alert("done")
setisIntersectionRatioComplete(true)
} else {
setisIntersectionRatioComplete(false)
}
}
useEffect(() => {
for(let i = 0; i <= 1.0; i += 0.1) {
observerOptions.threshold.push(i);
}
const observer = new IntersectionObserver(observerCallbackFunction, observerOptions);
if (observerElement.current) observer.observe(observerElement.current);
if (isIntersectionRatioComplete) {
window.addEventListener('scroll', HandelScrollTriggerAnimation, { passive: true });
}
return () => {
if (observerElement.current) {
observer.unobserve(observerElement.current);
window.removeEventListener('scroll', HandelScrollTriggerAnimation);
}
}
}, [isIntersectionRatioComplete])
谢谢你。
【问题讨论】:
标签: javascript reactjs animation math