<Animation timing='linear' position='left'>
<h1>Hello world</h1>
</Animation>
import React, {useEffect, ReactDOM} from 'react';
import {makeStyles} from "@material-ui/core/styles";
import clsx from "clsx";
const useStyles = makeStyles({
root: {
overflow: 'hidden'
},
wrapper: {
color: 'red'
}
})
const Animation = (props) => {
const classes = useStyles();
function defineElementPosition(side){
switch(side.position){
case('left'):
return 'translateX(-120%)'
case('right'):
return 'translateX(120%)'
case('top'):
return 'translateY(-120%)'
case('bottom'):
return 'translateY(120%)'
default: return 'translateY(100%)'
}
}
let styles = {
transform: defineElementPosition(props.position),
transition: props.transition,
transitionTimingFunction: props.timing
}
useEffect(() => {
window.addEventListener('scroll', () => {
const elems = document.querySelectorAll('scroll-component');
const clientWindowHeight = document.documentElement.clientHeight || window.innerHeight;
elems.forEach(elem => {
if(elem.getBoundingClientRect().top <= clientWindowHeight){
styles = {
transform: 'translate(0,0)',
}
}
})
})
})
return(
<div className={classes.root}>
<div className={clsx(classes.wrapper, 'scroll-component')} style={styles}>
{props.children}
</div>
</div>
)
}
export default Animation;
import React, {useEffect, useState, useRef} from 'react';
import {makeStyles} from "@material-ui/core/styles";
const useStyles = makeStyles({
root: {
overflow: 'hidden',
display: 'inline-block'
},
wrapper: {
color: 'red',
display: 'inline-block'
}
})
const Animation = (props) => {
const classes = useStyles();
const [styles, setStyles] = useState({
transform: defineElementPosition(props),
transition: props.transition,
transitionTimingFunction: props.timing,
opacity: props.opacityEffect === true ? 0 : 1
})
const elementWrapperRef = useRef(null);
function defineElementPosition(side){
switch(side.position){
case('left'):
return `translateX(${side.deep !== undefined ? side.deep.offset + 'px' : '-120%' })`
case('right'):
return `translateX(${side.deep !== undefined ? side.deep.offset + 'px' : '120%' })`
case('top'):
return `translateY(${side.deep !== undefined ? side.deep.offset + 'px' : '-120%' })`
case('bottom'):
return `translateY(${side.deep !== undefined ? side.deep.offset + 'px' : '120%' })`
default: return 'translateY(100%)'
}
}
function scrollElement(){
const clientWindowHeight = document.documentElement.clientHeight || window.innerHeight;
if(elementWrapperRef.current.getBoundingClientRect().top <= clientWindowHeight){
setStyles({...styles, transform: 'translate(0,0)', opacity: 1})
}
}
useEffect(() => {
window.addEventListener('scroll', scrollElement)
return () => window.removeEventListener('scroll', scrollElement) // Сброс эффекта - исправляет утечку памяти
}, [])
return(
<div className={classes.root}>
<div className={classes.wrapper} style={styles} ref={elementWrapperRef}>
{props.children}
</div>
</div>
)
}
export default Animation;