UNPKG

framer-motion-ticker

Version:

A React component that acts like a ticker, or marquee.

92 lines (91 loc) 2.89 kB
import React from 'react'; import { useAnimate, useInView } from 'framer-motion'; var TICKER_DIRECTION_LEFT = -1; var TICKER_DIRECTION_RIGHT = 1; var noop = () => {}; var Ticker = props => { var { children, duration = 10, onMouseEnter = noop, onMouseLeave = noop, isPlaying = true, direction = TICKER_DIRECTION_LEFT } = props; var tickerRef = React.useRef(null); var tickerContentsRef = React.useRef(null); var [tickerContentWidth, setTickerContentWidth] = React.useState(2); var [numDupes, setNumDupes] = React.useState(1); var [scope, animate] = useAnimate(); var [animationControls, setAnimationControls] = React.useState(undefined); var isInView = useInView(scope); React.useEffect(() => { if (tickerRef.current && tickerContentsRef.current) { var contentWidth = tickerContentsRef.current.getBoundingClientRect().width; setTickerContentWidth(contentWidth); setNumDupes(Math.max(Math.ceil(2 * tickerRef.current.clientWidth / contentWidth), 1)); } }, [tickerRef.current, tickerContentsRef.current]); React.useEffect(() => { if (isInView && !animationControls) { var controls = animate(scope.current, { x: tickerContentWidth * direction }, { ease: 'linear', duration, repeat: Infinity }); controls.play(); setAnimationControls(controls); } }, [isInView]); React.useEffect(() => { if (animationControls) { if (!isInView || !isPlaying) { animationControls.pause(); } else { animationControls.play(); } } }, [isInView, isPlaying]); return /*#__PURE__*/React.createElement("div", { className: "FMT__container", ref: tickerRef, style: { width: '100%', height: '100%', overflow: 'hidden' }, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }, /*#__PURE__*/React.createElement("div", { ref: scope, className: "FMT__container__contents", style: { display: 'flex', width: 'max-content', marginLeft: "-" + tickerContentWidth * numDupes + "px" } }, /*#__PURE__*/React.createElement("div", { style: { display: 'flex' } }, [...Array(numDupes)].map(_ => children.map((item, index) => /*#__PURE__*/React.createElement(React.Fragment, { key: index }, item)))), /*#__PURE__*/React.createElement("div", { ref: tickerContentsRef, style: { display: 'flex' } }, children.map((item, index) => /*#__PURE__*/React.createElement(React.Fragment, { key: index }, item))), /*#__PURE__*/React.createElement("div", { style: { display: 'flex' } }, [...Array(numDupes)].map(_ => children.map((item, index) => /*#__PURE__*/React.createElement(React.Fragment, { key: index }, item)))))); }; export default Ticker; export { TICKER_DIRECTION_LEFT, TICKER_DIRECTION_RIGHT };