點燈坊

失くすものさえない今が強くなるチャンスよ

實作字幕動態向上捲動

Sam Xiao's Avatar 2024-05-26

當字幕不斷動態地增加時,字幕會向上捲動,需使用一些 JavaScript 與 CSS 技巧才能實現。

Version

Vue 3.4
CSS 3

Page

caption01

  • 隨著字幕不斷地增加,最多只顯示 4 筆字幕,會持續向上捲動

Template

<template>
  <main class="main">
    <section class="row" v-for="(item, i) in captions" :key="i">
      <div class="col1">{{ item.name }}:</div>
      <div class="col2">{{ item.text }}</div>
    </section>
  </main>
  <nav>
    <button @click="onAddText">Add Text</button>
  </nav>
</template>

<script setup>
import { ref } from 'vue'

let captions = ref([])
let count = ref(0)

let onAddText = () => {
  count.value++

  captions.value.unshift({
    name: 'Mary',
    text: `Hi, Guys ${count.value}!`
  })

  if (captions.value.length >= 5) {
    captions.value.pop()
  }
}
</script>

<style scoped>
.main {
  width: 300px;
  height: 80px;
  word-wrap: break-word;
  display: flex;
  flex-direction: column-reverse;

  .row {
    display: flex;

    .col1 {
      width: 15%;
    }

    .col2 {
      width: 85%;
    }
  }
}
</style>

Line 2

<main class="main">
  <section class="row" v-for="(item, i) in captions" :key="i">
    <div class="col1">{{ item.name }}:</div>
    <div class="col2">{{ item.text }}</div>
  </section>
</main>
  • 字幕區塊:將字幕從 captions array 顯示其 nametext

Line 8

<nav>
  <button @click="onAddText">Add Text</button>
</nav>
  • 控制區塊:將輸入的字加入 captions array

Line 16

let captions = ref([])
let count = ref(0)
  • captions:收集所輸入的字
  • count:人為的 counter,主要目的讓輸入的字有所不同加以辨識

Line 22

captions.value.unshift({
  name: 'Mary',
  text: `Hi, Guys ${count.value}!`
})
  • 因為字幕要向上捲動,所以將使用 flex-direction: column-reverse,也就是 column 除了 垂直顯示 外,還 由下往上 顯示,因此新的資料不能使用 push()最後 新增,要改用 unshift()最前 新增

Line 27

if (captions.value.length >= 5) {
  captions.value.pop()
}
  • 由於最多只顯示 4 筆,因此第 5 筆時將從 最後 移除一筆資料

Line 34

.main {
  width: 300px;
  height: 80px;
  word-wrap: break-word;
  display: flex;
  flex-direction: column-reverse;
}
  • display: flex:使用 flexbox 排版
  • flex-direction: column-reverse:使用 垂直 排版,並 由下往上
  • word-wrap: break-word:為了換行將拆掉一個完整的字

Line 41

.row {
  display: flex;
 }
  • display: flex:使用 flexbox 排版

Line 44

.col1 {
  width: 15%;
}
  • width: 15%:寬度為 15%

Line 48

.col2 {
  width: 85%;
}
  • width: 85%:寬度為 85%

Conclusion

  • 為了能向上捲動,有兩個關鍵:CSS 使用了 flex-direction: column-reverse 垂直由下往上,且 JavaScript 使用了 unshift() 由 array 的 最前 新增資料