js如何實現(xiàn)文字跑馬燈效果 跑馬燈動畫的3種實現(xiàn)方案!

JS實現(xiàn)跑馬燈效果主要有三種方案:1.基于css overflow:hidden和js定時器,2.使用css animation動畫,3.利用canvas繪圖。第一種方案通過overflow:hidden隱藏超出容器文字,并用js定時器不斷改變marginleft實現(xiàn)滾動;第二種方案使用css animation定義關(guān)鍵幀動畫,代碼簡潔性能好但靈活性較差;第三種方案使用canvas繪制文字并動態(tài)更新位置,靈活性高但實現(xiàn)復(fù)雜。性能優(yōu)化技巧包括減少dom操作、使用requestanimationframe替代setinterval、節(jié)流控制頻率、使用transform代替left/top屬性、避免復(fù)雜css樣式。要實現(xiàn)文字從左向右循環(huán)滾動,需修改marginleft或x的初始值為負文字寬度,并調(diào)整判斷條件使文字完全移出右側(cè)后重新從左側(cè)開始。要讓跑馬燈滾動到指定位置停止,可在js方案中清除定時器,在css方案中動態(tài)移除動畫class,在canvas方案中取消動畫幀請求,并設(shè)置最終位置確保文字停在目標點。選擇方案應(yīng)根據(jù)需求權(quán)衡實現(xiàn)難度與性能表現(xiàn)。

js如何實現(xiàn)文字跑馬燈效果 跑馬燈動畫的3種實現(xiàn)方案!

跑馬燈效果,簡單來說,就是讓文字像走馬燈一樣滾動起來。JS實現(xiàn)跑馬燈效果,核心在于利用定時器不斷改變文字的位置,造成動態(tài)滾動的視覺效果。

js如何實現(xiàn)文字跑馬燈效果 跑馬燈動畫的3種實現(xiàn)方案!

解決方案

實現(xiàn)跑馬燈效果,主要有三種方案:

js如何實現(xiàn)文字跑馬燈效果 跑馬燈動畫的3種實現(xiàn)方案!

  1. 基于CSS overflow: hidden 和 JS 定時器: 這是最常見的方案,也是比較容易理解的一種。
  2. 使用 CSS animation 動畫: 這種方案性能更好,代碼更簡潔,但需要一定的CSS基礎(chǔ)。
  3. 利用 Canvas 繪圖: 這種方案最靈活,可以實現(xiàn)各種復(fù)雜的跑馬燈效果,但實現(xiàn)起來也最復(fù)雜。

下面分別介紹這三種方案:

方案一:CSS overflow: hidden + JS 定時器

js如何實現(xiàn)文字跑馬燈效果 跑馬燈動畫的3種實現(xiàn)方案!

這種方案的原理是,將需要滾動的文字放在一個容器中,容器設(shè)置 overflow: hidden,然后使用 JS 定時器不斷改變文字容器的 marginLeft 或 marginRight 屬性,使文字滾動起來。

<div id="marquee-container"   style="max-width:90%">   <span id="marquee-text">這是一段需要滾動的文字,長度超過容器寬度才能看到效果。</span> </div>  <script>   const marqueeContainer = document.getElementById('marquee-container');   const marqueeText = document.getElementById('marquee-text');   let marginLeft = 200;    function marquee() {     marginLeft--;     if (marginLeft < -marqueeText.offsetWidth) {       marginLeft = 200; // 從右側(cè)重新開始     }     marqueeText.style.marginLeft = marginLeft + 'px';   }    setInterval(marquee, 20); </script>

這段代碼的關(guān)鍵在于:

  • overflow: hidden:隱藏超出容器寬度的文字。
  • white-space: nowrap:防止文字換行,保證文字在同一行滾動。
  • marginLeft:控制文字的水平位置。
  • setInterval:定時調(diào)用 marquee 函數(shù),不斷改變 marginLeft 的值。

方案二:CSS animation 動畫

這種方案使用 CSS animation 來實現(xiàn)跑馬燈效果,代碼更簡潔,性能更好。

<div id="marquee-container" style="width: 200px; overflow: hidden;">   <span id="marquee-text" style="display: inline-block; padding-left: 100%; animation: marquee 10s linear infinite;">     這是一段需要滾動的文字,長度超過容器寬度才能看到效果。   </span> </div>  <style>   @keyframes marquee {     0% { transform: translateX(0%); }     100% { transform: translateX(-100%); }   } </style>

這段代碼的關(guān)鍵在于:

  • animation: marquee 10s linear infinite:定義了一個名為 marquee 的動畫,持續(xù)時間為 10 秒,線性運動,無限循環(huán)。
  • @keyframes marquee:定義了動畫的關(guān)鍵幀,從 translateX(0%) 到 translateX(-100%),使文字從右向左滾動。
  • padding-left: 100%:讓文字一開始出現(xiàn)在容器的右側(cè)。

這種方案的優(yōu)點是性能好,代碼簡潔,缺點是靈活性稍差,不容易實現(xiàn)復(fù)雜的跑馬燈效果。

方案三:Canvas 繪圖

這種方案使用 Canvas 繪圖來實現(xiàn)跑馬燈效果,最靈活,可以實現(xiàn)各種復(fù)雜的跑馬燈效果,例如文字漸變、文字旋轉(zhuǎn)、文字顏色變化等。

<canvas id="marquee-canvas" width="200" height="30"></canvas>  <script>   const canvas = document.getElementById('marquee-canvas');   const ctx = canvas.getContext('2d');   const text = '這是一段需要滾動的文字,長度超過容器寬度才能看到效果。';   let x = 200;    function marquee() {     ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空畫布     ctx.font = '16px Arial';     ctx.fillStyle = 'black';     ctx.fillText(text, x, 20);     x--;     if (x < -ctx.measureText(text).width) {       x = 200;     }     requestAnimationFrame(marquee); // 使用 requestAnimationFrame 優(yōu)化性能   }    marquee(); </script>

這段代碼的關(guān)鍵在于:

  • canvas.getContext(‘2d’):獲取 Canvas 的 2D 繪圖上下文。
  • ctx.fillText(text, x, 20):在 Canvas 上繪制文字,x 表示文字的水平位置,20 表示文字的垂直位置。
  • ctx.measureText(text).width:獲取文字的寬度。
  • requestAnimationFrame(marquee):使用 requestAnimationFrame 來定時調(diào)用 marquee 函數(shù),可以獲得更好的性能。

這種方案的優(yōu)點是靈活性高,可以實現(xiàn)各種復(fù)雜的跑馬燈效果,缺點是實現(xiàn)起來比較復(fù)雜,需要一定的 Canvas 基礎(chǔ)。

JS跑馬燈性能優(yōu)化有哪些技巧?

性能優(yōu)化對于跑馬燈效果至關(guān)重要,尤其是在處理大量文本或高頻率滾動時。

  1. 減少DOM操作: 避免在循環(huán)中頻繁修改DOM。可以將需要更新的內(nèi)容先在內(nèi)存中處理好,然后一次性更新到DOM上。例如,在方案一中,可以先計算好新的marginLeft值,然后再設(shè)置marqueeText.style.marginLeft。

  2. 使用requestAnimationFrame: requestAnimationFrame 比 setInterval 或 setTimeout 更適合動畫,因為它會在瀏覽器重繪之前執(zhí)行,避免不必要的重繪和卡頓。方案三中已經(jīng)使用了requestAnimationFrame。

  3. 節(jié)流(Throttling): 如果跑馬燈的更新頻率過高,可以考慮使用節(jié)流技術(shù),限制一段時間內(nèi)只執(zhí)行一次更新。這可以減少CPU的負擔(dān),提高性能。

  4. CSS動畫優(yōu)化: 如果使用CSS動畫,盡量使用transform屬性進行位移,而不是left或top。transform通常比改變布局屬性性能更好。

  5. 離屏渲染(Offscreen Rendering): 對于復(fù)雜的跑馬燈效果,可以先在離屏Canvas中渲染,然后再將離屏Canvas的內(nèi)容繪制到屏幕上。這可以避免在每次更新時都重新渲染整個畫面。

  6. 文字預(yù)渲染: 如果跑馬燈的文字內(nèi)容是固定的,可以預(yù)先將文字渲染成圖片,然后滾動圖片,而不是每次都重新渲染文字。

  7. 避免使用復(fù)雜的CSS樣式: 復(fù)雜的CSS樣式會增加瀏覽器的渲染負擔(dān),盡量使用簡單的CSS樣式來實現(xiàn)跑馬燈效果。

如何實現(xiàn)文字從左向右,循環(huán)滾動的跑馬燈效果?

要實現(xiàn)文字從左向右循環(huán)滾動,只需修改一下方案一和方案三中的邏輯即可。

方案一(CSS overflow: hidden + JS 定時器)修改:

<div id="marquee-container" style="width: 200px; overflow: hidden; white-space: nowrap;">   <span id="marquee-text">這是一段需要滾動的文字,長度超過容器寬度才能看到效果。</span> </div>  <script>   const marqueeContainer = document.getElementById('marquee-container');   const marqueeText = document.getElementById('marquee-text');   let marginLeft = -marqueeText.offsetWidth; // 從左側(cè)開始    function marquee() {     marginLeft++;     if (marginLeft > marqueeContainer.offsetWidth) {       marginLeft = -marqueeText.offsetWidth; // 從左側(cè)重新開始     }     marqueeText.style.marginLeft = marginLeft + 'px';   }    setInterval(marquee, 20); </script>

關(guān)鍵修改點:

  • marginLeft 初始值設(shè)置為 -marqueeText.offsetWidth,讓文字從左側(cè)開始。
  • 判斷條件改為 marginLeft > marqueeContainer.offsetWidth,當(dāng)文字完全移出容器右側(cè)時,重新從左側(cè)開始。

方案三(Canvas 繪圖)修改:

<canvas id="marquee-canvas" width="200" height="30"></canvas>  <script>   const canvas = document.getElementById('marquee-canvas');   const ctx = canvas.getContext('2d');   const text = '這是一段需要滾動的文字,長度超過容器寬度才能看到效果。';   let x = -ctx.measureText(text).width; // 從左側(cè)開始    function marquee() {     ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空畫布     ctx.font = '16px Arial';     ctx.fillStyle = 'black';     ctx.fillText(text, x, 20);     x++;     if (x > canvas.width) {       x = -ctx.measureText(text).width; // 從左側(cè)重新開始     }     requestAnimationFrame(marquee); // 使用 requestAnimationFrame 優(yōu)化性能   }    marquee(); </script>

關(guān)鍵修改點:

  • x 初始值設(shè)置為 -ctx.measureText(text).width,讓文字從左側(cè)開始。
  • 判斷條件改為 x > canvas.width,當(dāng)文字完全移出畫布右側(cè)時,重新從左側(cè)開始。

如何讓跑馬燈文字滾動到指定位置后停止?

讓跑馬燈文字滾動到指定位置后停止,需要在代碼中添加一個判斷條件,當(dāng)文字滾動到指定位置時,停止定時器或動畫。

方案一(CSS overflow: hidden + JS 定時器)修改:

<div id="marquee-container" style="width: 200px; overflow: hidden; white-space: nowrap;">   <span id="marquee-text">這是一段需要滾動的文字,長度超過容器寬度才能看到效果。</span> </div>  <script>   const marqueeContainer = document.getElementById('marquee-container');   const marqueeText = document.getElementById('marquee-text');   let marginLeft = 200;   const stopPosition = 50; // 指定停止的位置   let intervalId;    function marquee() {     marginLeft--;     if (marginLeft < -marqueeText.offsetWidth) {       marginLeft = 200;     }      if (marginLeft <= stopPosition) {       clearInterval(intervalId); // 停止定時器       marqueeText.style.marginLeft = stopPosition + 'px'; // 最終位置       return;     }      marqueeText.style.marginLeft = marginLeft + 'px';   }    intervalId = setInterval(marquee, 20); </script>

關(guān)鍵修改點:

  • 添加 stopPosition 變量,指定停止的位置。
  • 添加 intervalId 變量,保存定時器的 ID,方便停止定時器。
  • 在 marquee 函數(shù)中,判斷 marginLeft 是否小于等于 stopPosition,如果是,則停止定時器,并設(shè)置文字的最終位置。

方案二(CSS animation 動畫)修改:

CSS動畫要停止,稍微麻煩一點,需要動態(tài)的添加和移除動畫class。

<div id="marquee-container" style="width: 200px; overflow: hidden;">   <span id="marquee-text" style="display: inline-block; padding-left: 100%;" class="marquee">     這是一段需要滾動的文字,長度超過容器寬度才能看到效果。   </span> </div>  <style>   .marquee {     animation: marquee 10s linear infinite;   }   @keyframes marquee {     0% { transform: translateX(0%); }     100% { transform: translateX(-100%); }   } </style>  <script>   const marqueeText = document.getElementById('marquee-text');   const stopPosition = 50; // 指定停止的位置    // 假設(shè)在某個事件觸發(fā)時停止動畫   setTimeout(() => {     marqueeText.classList.remove('marquee'); // 移除動畫class     marqueeText.style.transform = `translateX(${stopPosition}px)`; // 設(shè)置最終位置   }, 5000); // 假設(shè)5秒后停止 </script>

關(guān)鍵修改點:

  • 給 marquee-text 添加一個 class marquee,該 class 定義了動畫。
  • 使用 setTimeout 模擬某個事件觸發(fā),然后移除 marquee class,停止動畫。
  • 設(shè)置 marqueeText.style.transform,讓文字停留在指定位置。

方案三(Canvas 繪圖)修改:

<canvas id="marquee-canvas" width="200" height="30"></canvas>  <script>   const canvas = document.getElementById('marquee-canvas');   const ctx = canvas.getContext('2d');   const text = '這是一段需要滾動的文字,長度超過容器寬度才能看到效果。';   let x = 200;   const stopPosition = 50; // 指定停止的位置   let animationFrameId;    function marquee() {     ctx.clearRect(0, 0, canvas.width, canvas.height);     ctx.font = '16px Arial';     ctx.fillStyle = 'black';     ctx.fillText(text, x, 20);      if (x <= stopPosition) {       cancelAnimationFrame(animationFrameId); // 停止動畫幀       x = stopPosition; // 最終位置       ctx.fillText(text, x, 20); // 確保最終位置顯示文字       return;     }      x--;     animationFrameId = requestAnimationFrame(marquee);   }    marquee(); </script>

關(guān)鍵修改點:

  • 添加 stopPosition 變量,指定停止的位置。
  • 添加 animationFrameId 變量,保存 requestAnimationFrame 的 ID,方便停止動畫幀。
  • 在 marquee 函數(shù)中,判斷 x 是否小于等于 stopPosition,如果是,則停止動畫幀,并設(shè)置文字的最終位置。

選擇哪種方案取決于具體的需求。如果需要簡單的跑馬燈效果,可以使用 CSS animation;如果需要復(fù)雜的跑馬燈效果,可以使用 Canvas 繪圖。在性能方面,CSS animation 通常比 JS 定時器性能更好,而 Canvas 繪圖的性能則取決于具體的實現(xiàn)方式。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊6 分享