import { useSpring, animated, easings, to, useInView } from '@react-spring/web'; import React, { useEffect, useState } from 'react'; import { PresEffect, PresEffectDirection } from './PresEnums'; import './SlideEffect.scss'; import { Doc } from '../../../../fields/Doc'; import { NumCast } from '../../../../fields/Types'; interface Props { // pass in doc to extract width, height, bg doc?: Doc; dir: PresEffectDirection; presEffect: PresEffect; friction: number; tension: number; mass: number; children: React.ReactNode; infinite?: boolean; } const DEFAULT_WIDTH = 40; const PREVIEW_OFFSET = 60; const ACTUAL_OFFSET = 200; const infiniteOptions = { loop: true, delay: 500, }; // TODO: add visibility detector when the slide comes into view export default function SpringAnimation({ doc, dir, friction, tension, mass, presEffect, children, infinite }: Props) { const [springs, api] = useSpring( () => ({ from: { x: 0, y: 0, opacity: 0, scale: 1, }, config: { tension: tension, friction: friction, mass: mass, }, onStart: () => {}, onRest: () => {}, }), [tension, friction, mass] ); const [ref, inView] = useInView({ once: true, }); // 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: infinite ? -PREVIEW_OFFSET : -ACTUAL_OFFSET, y: 0, }, }; case PresEffectDirection.Right: return { from: { opacity: 0, x: infinite ? PREVIEW_OFFSET : ACTUAL_OFFSET, y: 0, }, }; case PresEffectDirection.Top: return { from: { opacity: 0, x: 0, y: infinite ? -PREVIEW_OFFSET : -ACTUAL_OFFSET, }, }; case PresEffectDirection.Bottom: return { from: { opacity: 0, x: 0, y: infinite ? PREVIEW_OFFSET : ACTUAL_OFFSET, }, }; default: // no movement for center 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, }, }, ], }; const flipConfig = { from: { x: 0, }, to: { x: 180, config: { tension: tension, friction: friction, mass: mass, }, }, }; // only left and right for now const getRollConfigFrom = () => { switch (dir) { case PresEffectDirection.Left: return { from: { opacity: 0, x: -100, y: -120, }, }; case PresEffectDirection.Right: return { from: { opacity: 0, x: 100, y: 120, }, }; case PresEffectDirection.Top: return { from: { opacity: 0, x: -100, y: -120, }, }; case PresEffectDirection.Bottom: return { from: { opacity: 0, x: -100, y: -120, }, }; default: // no movement for center return { from: { opacity: 0, x: 0, y: 0, }, }; } }; const rollConfig = { ...getRollConfigFrom(), to: { opacity: 1, x: 0, y: 0, config: { tension: tension, friction: friction, mass: mass, }, }, }; const lightspeedConfig = { from: { opacity: 0, }, to: [], }; // Switch animation depending on slide effect const startAnimation = () => { let config: any = zoomConfig; switch (presEffect) { case PresEffect.Bounce: config = bounceConfig; break; case PresEffect.Zoom: config = zoomConfig; break; case PresEffect.Rotate: config = rotateConfig; break; case PresEffect.Fade: config = fadeConfig; break; case PresEffect.Flip: config = flipConfig; break; case PresEffect.Roll: config = rollConfig; break; case PresEffect.Lightspeed: break; default: break; } if (infinite) { config = { ...config, ...infiniteOptions }; } api.start(config); }; // const flipRender = () => { // return ( //