import { useSpring, animated, easings, to } from '@react-spring/web'; import React, { useEffect, useState } from 'react'; import { PresEffect, PresEffectDirection } from './PresEnums'; import './SlideEffect.scss'; interface Props { dir: PresEffectDirection; presEffect: PresEffect; friction: number; tension: number; mass: number; children: React.ReactNode; } // TODO: add visibility detector when the slide comes into view export default function SpringAnimation({ dir, friction, tension, mass, presEffect, children }: Props) { const [springs, api] = useSpring( () => ({ from: { x: 0, y: 0, opacity: 0, scale: 1, }, config: { tension: tension, friction: friction, mass: mass, }, onStart: () => { console.log('started'); }, onRest: () => { console.log('resting'); }, }), [tension, friction, mass] ); // Whether the animation is currently playing const [animating, setAnimating] = useState(false); const zoomConfig = { from: { scale: 0, x: 0, y: 0, opacity: 1, }, to: { scale: 1, x: 0, y: 0, opacity: 1, config: { tension: tension, friction: friction, mass: mass, }, }, }; const fadeConfig = { from: { opacity: 0, scale: 1, x: 0, y: 0, }, to: { opacity: 1, scale: 1, x: 0, y: 0, config: { tension: tension, friction: friction, mass: mass, }, }, }; const rotateConfig = { from: { x: 0, }, to: { x: 360, config: { tension: tension, friction: friction, mass: mass, }, }, }; const getBounceConfigFrom = () => { switch (dir) { case PresEffectDirection.Left: return { from: { opacity: 0, x: -200, y: 0, }, }; case PresEffectDirection.Right: return { from: { opacity: 0, x: 200, y: 0, }, }; case PresEffectDirection.Top: return { from: { opacity: 0, x: 0, y: -200, }, }; case PresEffectDirection.Bottom: return { from: { opacity: 0, x: 0, y: 200, }, }; default: return { from: { opacity: 0, x: 0, y: 0, }, }; } }; const bounceConfig = { ...getBounceConfigFrom(), to: [ { opacity: 1, x: 0, y: 0, config: { tension: tension, friction: friction, mass: mass, }, }, ], }; // Flip // const flipConfig = { // from: { // // opacity: 0, // transform: `perspective(600px) rotateX(0deg)`, // }, // to: { // // opacity: 1, // transform: `perspective(600px) rotateX(180deg)`, // config: { // tension: tension, // friction: friction, // mass: mass, // }, // }, // }; const flipConfig = { from: { x: 0, }, to: { x: 180, config: { tension: tension, friction: friction, mass: mass, }, }, }; // Switch animation depending on slide effect const startAnimation = () => { switch (presEffect) { case PresEffect.Bounce: api.start(bounceConfig); break; case PresEffect.Zoom: api.start(zoomConfig); break; case PresEffect.Rotate: api.start(rotateConfig); break; case PresEffect.Fade: api.start(fadeConfig); break; case PresEffect.Flip: api.start(flipConfig); break; case PresEffect.Roll: break; case PresEffect.Lightspeed: break; default: break; } }; // const flipRender = () => { // return ( //
// 1 - o), transform }} /> // // {children} // //
// ); // }; const getRenderDoc = () => { switch (presEffect) { case PresEffect.Rotate: return `rotate(${val}deg)`) }}>{children}; case PresEffect.Flip: return (
`perspective(600px) rotateX(${val}deg)`) }} /> `perspective(600px) rotateX(${val}deg)`), rotateX: '180deg' }}> {children}
); default: return ( {children} ); } }; useEffect(() => { // TODO: Control start with slide visibility instead setTimeout(() => { startAnimation(); }, 200); }, []); return
{getRenderDoc()}
; }