我一直在进行副项目,要求我建立一个网站,周围有一些动画。我选择从React开始(以学习新框架并扩展我的知识)。
我要关注(或试图复制)的一个重要动画来自苹果公司website。
当您启动网页并向下滚动时,通过移动60px并更改不透明度可以使文本平滑显示。一旦进入视口。
我试图通过类来做到这一点。但是,我会遇到类问题,因为它们有时会重新渲染我的元素,或者刷新时该组件将不可见。
我还尝试将fadeIn
与setInterval
一起使用,但是,每次激活它的方式都不同。
我使用动画的组件:
import React, { Component } from "react";
import "./SuccessStory.css";
class SuccessStory extends Component {
state = {
componentAppearsScrollUp: false,
componentDisappearsScrollUp: false,
componentAppearsScrollDown: false,
componentDisappearsScrollDown: false,
showComponent: false,
translateMove: 60,
opacity: 0
};
fadingIn() {
const timer = setInterval(() => {
if (this.state.opacity >= 1) {
clearInterval(timer);
return;
}
this.setState({
opacity: this.state.opacity + 0.05
});
}, 100);
}
fadingOut() {
const timer = setInterval(() => {
if (this.state.opacity <= 0) {
clearInterval(timer);
}
this.setState({
opacity: this.state.opacity - 0.05
});
}, 100);
}
componentDidUpdate(prevProps, prevState) {
if (this.props.currentY < prevProps.currentY) {
if (
this.props.intersectionRatio > prevProps.intersectionRatio &&
this.props.isIntersecting
) {
if (this.props.intersectionRatio > 0.6) {
console.log("Scrolling down enter");
this.fadingIn();
this.setState({
componentAppearsScrollUp: false,
componentDisappearsScrollUp: false,
componentAppearsScrollDown: true,
componentDisappearsScrollDown: false,
showComponent: true
});
}
} else {
if (
this.props.intersectionRatio < 0.8 &&
this.props.intersectionRatio > 0.6
) {
console.log("Scrolling down leave");
this.setState({
componentAppearsScrollUp: false,
componentDisappearsScrollUp: false,
componentAppearsScrollDown: false,
componentDisappearsScrollDown: true,
showComponent: true
});
this.fadingOut();
}
}
} else if (
this.props.currentY > prevProps.currentY &&
this.props.isIntersecting
) {
if (this.props.intersectionRatio < prevProps.intersectionRatio) {
if (this.props.intersectionRatio < 0.9) {
console.log("Scrolling up leave");
this.fadingOut();
this.setState({
componentAppearsScrollUp: false,
componentDisappearsScrollUp: true,
componentAppearsScrollDown: false,
componentDisappearsScrollDown: false,
showComponent: true
});
}
} else {
if (
this.props.intersectionRatio > 0.6 &&
this.props.intersectionRatio < 0.8
) {
console.log("Scrolling up enter");
this.setState({
componentAppearsScrollUp: true,
componentDisappearsScrollUp: false,
componentAppearsScrollDown: false,
componentDisappearsScrollDown: false,
showComponent: true
});
this.fadingIn();
}
}
} else if (
this.props.isIntersecting &&
this.props.intersectionRatio > 0.9
) {
this.fadingIn();
}
}
render() {
return (
<div
className={
(this.state.componentAppearsScrollDown
? " story-appear-scroll-down "
: "") +
(this.state.componentDisappearsScrollDown
? " story-disappear-scroll-down "
: "") +
(this.state.componentAppearsScrollUp
? "story-appear-scroll-up "
: "") +
(this.state.componentDisappearsScrollUp
? " story-disappear-scroll-up "
: "")
}
style={{
opacity: this.state.opacity
}}
>
<h1 className="success-story">The success story</h1>
<h2
className="success-story-text-one"
// style={
// this.props.isIntersecting && this.props.intersectionRatio > 0.8
// ? { opacity: 1 }
// : { opacity: 0 }
// }
>
MobileLife brought together over 100 dedicated people based in
Copenhagen and Vilnius to deliver innovative mobile solutions to the
banking customers in Nordic markets.
</h2>
</div>
);
}
}
export default SuccessStory;
我的父组件将交点观察器值传递给子组件:
import React, { Component } from "react";
import "./SecondPage.css";
import SuccessStory from "./SuccessStory";
import { InView } from "react-intersection-observer";
// import SuccessStoryText1 from "./SuccessStoryText1";
import SuccessStoryText2 from "./SuccessStoryText2";
class SecondPage extends Component {
state = {
isIntersecting: false,
intersectionRatio: "",
currentY: "",
isIntersectingSecondText: false,
intersectionRatioSecondText: "",
currentYSecondText: ""
};
render() {
return (
<div className="second-page">
<div className="navigation-second" style={{ position: "sticky" }} />
<div style={{ paddingTop: "25%", height: "60vh" }}>
<InView
threshold={[0.1, 0.2, 0.3, 0.4, 0.6, 0.75, 0.8]}
onChange={(inView, ref) => {
this.setState({
currentY: ref.boundingClientRect.y,
isIntersecting: ref.isIntersecting,
intersectionRatio: ref.intersectionRatio
});
// console.log("Inview:", inView, ref);
}}
>
{({ inView, ref }) => (
<div ref={ref} style={{ position: "sticky", top: "30%" }}>
<SuccessStory
isIntersecting={this.state.isIntersecting}
intersectionRatio={this.state.intersectionRatio}
currentY={this.state.currentY}
/>
</div>
)}
</InView>
</div>
<InView
threshold={[0.1, 0.2, 0.3, 0.4, 0.6, 0.75, 0.8]}
onChange={(inView, ref) => {
if (ref.intersectionRatio > 0.1) {
this.setState({
currentYSecondText: ref.boundingClientRect.y,
isIntersectingSecondText: ref.isIntersecting,
intersectionRatioSecondText: ref.intersectionRatio
});
}
// console.log("Inview:", inView, ref);
}}
>
{({ inView, ref }) => (
<div ref={ref}>
<SuccessStoryText2
isIntersecting={this.state.isIntersectingSecondText}
intersectionRatio={this.state.intersectionRatioSecondText}
currentY={this.state.currentYSecondText}
/>
</div>
)}
</InView>
</div>
);
}
}
//
export default SecondPage;
这是我用来制作动画的CSS:
.story-appear-scroll-down {
animation: successStoryTextAppearScrollDown 0.3s linear;
animation-fill-mode: forwards;
}
@keyframes successStoryTextAppearScrollDown {
from {
transform: translate3d(0, 60px, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
.story-disappear-scroll-down {
animation: successStoryTextDisappearScrollDown 0.3s linear;
animation-fill-mode: forwards;
}
@keyframes successStoryTextDisappearScrollDown {
from {
transform: translate3d(0, 0, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
.story-appear-scroll-up {
animation: successStoryTextAppearScrollUp 0.3s linear;
animation-fill-mode: forwards;
}
@keyframes successStoryTextAppearScrollUp {
from {
transform: translate3d(0, 0, 0);
}
to {
transform: translate3d(0, 0, 0);
}
}
.story-disappear-scroll-up {
animation: successStoryTextDisappearScrollUp 0.3s linear;
animation-fill-mode: forwards;
}
@keyframes successStoryTextDisappearScrollUp {
from {
transform: translate3d(0, 0, 0);
}
to {
transform: translate3d(0, 60px, 0);
}
}
我在想激活这种动画的正确方法是什么,我试图复制这种动画,并且每次激活它的外观都一样(如Apple网页所示)。但是,由于我已经花了太多时间在此上,所以我无法获得想要的结果。
感谢您的帮助,我们欢迎您提出任何建议或提示,因为这是我的第一篇帖子。