您好,登錄后才能下訂單哦!
這篇文章主要介紹“基于React.js如何實現簡單的文字跑馬燈效果”,在日常操作中,相信很多人在基于React.js如何實現簡單的文字跑馬燈效果問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”基于React.js如何實現簡單的文字跑馬燈效果”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
我想到的最簡單的方法,就是定位啦,定時移動這個文字塊不就跑起來了。
需要注意的是,要判斷文字的寬度,當文字超出屏幕的寬度的時候再動起來,我用的是hook的寫法,要在銷毀頁面的時候清掉定時器。定時器要放在useRef里面。
const timer = useRef<any>(null); const [left, setLeft] = useState(0); const contentRef = useRef<any>(null); useEffect(() => { // 當監聽到文字變化時,一定要先清掉定時器,如果文字較短的話就不會再啟動 if (timer.current) { clearInterval(timer.current); } const contentDom = contentRef.current; if (contentDom) { const obj = contentDom.getBoundingClientRect(); // 判斷文字框長度 if (obj.width > props.width) { timer.current = setInterval(() => { // 注意state是負數,?當數字移動到最后的時候,下一次從父元素的寬度開始,看起來就是一直在向左移動 // 文字框的寬度要時時獲取 // setLeft要從回調里面獲取,不然不能時時更新 setLeft((state) =>-state >= contentDom.getBoundingClientRect().width ? props.width : state - 1, ); }, 100); } else { setLeft(0); } } }, [props.children]); useEffect(() => { // 注銷時,清空定時器 return () => { if (timer.current) { clearInterval(timer.current); } }; }, []); return (<div className={styles.noticeCompWrapper} style={{ width: props.width, ...props.style }}> <div ref={contentRef} className={styles.noticeContent} style={{ left }}> {props.children} </div> </div> ); .noticeCompWrapper { height: 40px; line-height: 40px; overflow: hidden; position: relative; .noticeContent { white-space: nowrap; position: absolute; } }
這移動效果還可以吧,時間間隔一定要小,不然就會一卡一卡的
第一種很容易吧,其實最開始是想用純css來寫的,考慮到css沒法獲取自適應寬度,咋判斷文字移動到末尾了?但是我覺得,css肯定是可以辦到,于是我繼續探索...
animation走起,,,咱們假設外邊框長120px,文字長240px
@keyframes run { 0% { transform: translateX(0); } 50% { transform: translateX(-240px); } 50% { transform: translateX(120px); } 100% { transform: translateX(-240px); } }
總感覺有啥不對,這個字咋往回跑,這感覺跑來跑去的。。。
平心靜氣~沒事沒事,不就是個小bug么~
仔細思考一下,這只要寫兩個動畫就解決了,因為其實除了第一次不同,后面都是從右邊進入視角的有木有。
@keyframes run { from { transform: translateX(0); } to { transform: translateX(-240px); } } @keyframes loop { from { transform: translateX(120px); } to { transform: translateX(-240px); } }
咱們用的時候,第一個走一遍就好了,循環后面那個:
.textContent { white-space: nowrap; animation-name: run, loop; animation-duration: 5s; animation-iteration-count: 1, infinite; animation-timing-function: linear; position: relative; }
look,是不是好多了~
接下來就是文字長度的問題了~咋們咋控制他要不要動啊?還有移動的時間和距離咋控制??
首先動畫時間,less肯定是算不出來了,那我們就在js外面計算一下哈~方法和上面類似,要取元素的寬度。
const contentRef = useRef<any>(null); const [duration, setDuration] = useState(''); useEffect(() => { const dom = contentRef.current; if (dom) { const { width } = dom.getBoundingClientRect(); if (width > props.width) { // 我這邊取的速度是按一個字的大小 setDuration(width / 16 + 's'); } else { // 小于寬度的時候清掉時間 setDuration(''); } } else { setDuration(''); } }, [props.children]); return (<div style={{ width: props.width, ...props.style }} className={styles.wrapper} > <div className={styles.textContent} ref={contentRef} // 計算好動畫時間傳過去 style={{ animationDuration: duration, // 第二個動畫等第一個執行之后執行 animationDelay: duration? `0s, ${duration}` :'', }} > {props.children} </div> </div> );
完整的樣式
// 設置父元素的寬度 @width: 120px; .wrapper { position: relative; overflow: hidden; width: @width; height: 40px; line-height: 40px; .textContent { white-space: nowrap; animation-name: run, roop; animation-iteration-count: 1, infinite; animation-timing-function: linear; // 這個很重要,不然寬度就和父元素一樣 position: absolute; } } @keyframes run { from { transform: translateX(0); } to { // 這個100% 是文字的 transform: translateX(-100%); } } @keyframes roop { from { transform: translateX(@width); } to { transform: translateX(-100%); } }
這個父元素的寬度是不是寫死了,要是要使用的話只能手動改@width,咱有木有辦法通過js傳過來?你知道怎么改更好么?
哈哈,咱們基本上已經完成了這種簡單的從左向右移動的文字跑馬燈(為自己鼓掌),接下來就是升級版的了,跑馬燈plus。實現一個向上滾動的跑馬燈。
咱們在第一步的基礎上來做一個向上滾動的跑馬燈plus。
我們加一個向上的按鈕,可以控制文字跑動的方向,當然向右向下同理~這里就不做了
<> <div className={styles.noticeCompWrapper} style={{ width: props.width, ...props.style, marginBottom: 10 }} > <div ref={contentRef} className={styles.noticeContent} style={{ left, top, // 換行的邏輯一定要加上,上下移動的需要換行 whiteSpace: direction == DirectionEnum.左 ? 'nowrap' : 'initial', }} > {props.children} </div> </div> <Space> <Button onClick={() => { setDirection(DirectionEnum.左); setTop(0); }}> 向左</Button> <Button onClick={() => { setDirection(DirectionEnum.上); setLeft(0); }}> 向上</Button> </Space> </>
判斷下移動方向
useEffect(() => { // 當監聽到文字變化時,一定要先清掉定時器,如果文字較短的話就不會再啟動 if (timer.current) { clearInterval(timer.current); } const contentDom = contentRef.current; if (contentDom) { const obj = contentDom.getBoundingClientRect(); if (direction == DirectionEnum.左) { // 同上... } else if (direction == DirectionEnum.上) { // 向上 if (obj.height > 40) { timer.current = setInterval(() => { setTop(state =>-state >= contentDom.getBoundingClientRect().height ? 40 : state - 1); }, 30); } } else { setLeft(0); setTop(0); } } }, [props.children, direction]);
看一下成果:
這種單行滾動的效果,能不能實現一下?就是滾動一行停留一段時間再繼續滾動
這個也比較簡單,我用我上面的方法在引申一下,你們也可以用其他方法,animatioin也可以。
我在定時器里面在加一個延時timeout
timer.current = setInterval(() => { setTop(state => { // 當行數是40的整倍數的時候延遲執行移動 if ((state - 1) % 40 == 0) { setTimeout(() => { setTop(state1 => -state1 >= contentDom.getBoundingClientRect().height ? 40 : state1 - 1); }, 500); return state; } else { return -state >= contentDom.getBoundingClientRect().height? 40 : state - 1; } }); }, 30);
效果:
到此,關于“基于React.js如何實現簡單的文字跑馬燈效果”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。