import React, { useState, useRef } from "react";
import { render } from "react-dom";
import styled from "styled-components";
import { useScrollData } from "scroll-data-hook";
const Menu = () => {
const ref = useRef('myRef');
const datas = ["Sao Paulo", "New-York", "Lisbonne", "Milan", "Paris"];
const { direction } = useScrollData({
onScrollEnd: () => {
if (ref.current){
Array.from(ref.current.children).forEach(el => {
el.style.transform = `translate3d(0,0,0)`;
el.style.transition = "transform 1s";
})
}
}
})
const setTransformMatrix3d = ( matrix3d ) => {
if (ref.current){
Array.from(ref.current.children).forEach(el => {
el.style.transition = "transform 1s";
el.style.transform = matrix3d;
})
}
};
if (direction.y) {
console.log(direction.y);
let matrix =
direction.y === "up"
? `matrix3d(1,0.09,0,0,0,1.1,0,0,0,0,1,0,0,0,0,1)`
: `matrix3d(1,-0.09,0,0,0,1.1,0,0,0,0,1,0,0,0,0,1)`;
setTransformMatrix3d({ matrix });
}
return (
<Wrapper>
<Ul ref={ref}>
{datas.map((value, index) => (
<Item key={index} value={value} />
))}
</Ul>
</Wrapper>
);
};
export default Menu;
const Item = ( {...props} ) => {
const [isHover, setIsHover] = useState(false);
return (
<Li>
<Link>
<ContainerMatrix
onMouseOver={() => setIsHover(!isHover)}
onMouseLeave={() => setIsHover(!isHover)}
>
<ContainerSpan>
<Span isHover={isHover}>
{ props.value }
<Mask className="mask" isHover={isHover} dataMask={props.value} />
</Span>
</ContainerSpan>
</ContainerMatrix>
</Link>
</Li>
);
};
const Wrapper = styled.section`
transition: transform 100ms;
will-change: transform;
display: flex;
flex-direction: column;
justify-content: center;
align-content: center;
align-items: center;
width: 100vw;
height: 140vh;
margin: auto;
background-color : black;
`
const Link = styled.a`
text-decoration: none;
color: inherit;
background-color: transparent;
`
const Ul = styled.ul`
display: flex;
flex-direction: column;
align-items: center;
align-content: center;
`
const ContainerMatrix = styled.div`
transform: translate3d(0px, 0px, 0px);
transition: transform 100ms;
will-change: transform;
`
const Li = styled.li`
transition: transform 2s;
list-style: none;
text-transform: uppercase;
`
const ContainerSpan = styled.span`
position: relative;
display: inline-block;
margin: 0;
color: hsla(0, 0%, 100%, 0.2);
text-align: center;
padding: 0 0.15em;
line-height: 1.15;
// background-color : red;
`
const Span = styled.span`
line-height: 1.15;
font-size: 8.5675vw;
display: inline-block;
transform: scaleY(${props => (props.isHover ? "1.1" : "1")}) translateY(${props => (props.isHover ? "-0.1em" : "0em")});
transition: transform 1.25s cubic-bezier(0.23, 1, 0.32, 1),
-webkit-transform 1.25s cubic-bezier(0.23, 1, 0.32, 1);
`
const Mask = styled.span.attrs({
"aria-hidden": "true"
})`
transform: translate3d(0, ${props => (props.isHover ? "0%" : "100%")}, 0);
display: block;
overflow: hidden;
transition: transform 1.5s cubic-bezier(.23,1,.32,1),opacity .75s linear,-webkit-transform 1.5s cubic-bezier(.23,1,.32,1);
will-change: transform,opacity;
position:absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: block;
pointer-events: none;
&::before{
content: '${props => props.dataMask}';
transform: translate3d(0,${props => (props.isHover ? "0%" : "-100%")}, 0);
color: #fff;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: block;
pointer-events: none;
transition: opacity .75s linear,-webkit-transform 1.5s cubic-bezier(.23,1,.32,1);
transition: transform 1.5s cubic-bezier(.23,1,.32,1),opacity .75s linear;
will-change: transform,opacity;
}
`
这是我关于stackoverflow的第一篇文章。我正在与react一起工作,并且试图在此页面上找到一种(正确的)方法来重现效果:https://www.rudolfson.com/。我已经使字体颜色显示出来了,但是我不知道如何使用在滚动时使用bindind的“ transform:matrix3d”属性在文本容器上重现“波动效果”。自3天以来我一直在努力,但我需要帮助!我认为它使用滚动速度,但我不确定。非常感谢您的回答和建议。
要使之正常工作的粗糙补丁。将变换放在每个li
元素上会使事情变得更加困难。只需将其应用到我已修改的外部ul
上,就容易得多。
您需要填写高度计算(并替换为-200,代码可能会更干净。但在大多数情况下,它是有效的。我使用了鲁道夫使用的matrix3d作为基础。
此处为codesandbox演示:https://codesandbox.io/s/lucid-sky-hg2of
const setTransformMatrix3d = matrix => {
Array.from([ref.current]).map((el, index) => {
el.style.transition = "transform 1s";
el.style.transform = matrix;
});
};
if (direction.y) {
console.log(direction.y);
let matrix =
direction.y === "up"
? `matrix3d(1, 0.000174533, 0, 0, -0.000174533, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)`
: `matrix3d(1, 0.000174533, 0, 0, -0.000174533, 1, 0, 0, 0, 0, 1, 0, 0, -200, 0, 1)`;
setTransformMatrix3d(matrix);
}
useEffect(() => {
window.addEventListener("scroll", setTransformMatrix3d);
return () => {
window.removeEventListener("scroll", setTransformMatrix3d);
};
}, []);