HTML5ではなくなった「marquee」タグをvue(Nuxt)で実装し直す

みなさんこんにちは!
このブログの記事の更新は久しぶりですね。
レイアウトの調整はちょこちょこ行っていましたが...
最近まで、社会と資格試験と戦っておりましたw
プラスでコロナでのストレス...
だいぶ疲れが溜まってきてます...
コロナだけでも早く収まって、ストレスから解放されたいです。
 
さて話も変わりまして、今回は、HTML5ではなくなった「marquee」タグをvue(Nuxt)で実装してみたので、記事にしてみました!
本ブログの「ブログトップページ」に実装したものを加えましたので、実際の動きを確認したい方はリンク先へ!

「marquee」タグとは?

そもそも「marquee」タグとは何?と思う方もいらっしゃるかも知れません。
(私も実装する前まで、知りませんでしたw)
よく電車の入り口付近にある、文字がスクロールする電光掲示板のようなものが作りたかったので、調べていたら
「marquee」タグにたどり着きました。
「marquee」は文字や画像などを上下左右にスクロールさせたい場合に利用するみたいですね。
HTMLクイックリファレンスを参照してみると、
Internet Explorerが独自で開発したタグで、HTML4までは使えますが、
HTML5ではタグが廃止されているみたいで、代わりにCSSを使って実装するみたいです。

「marquee」を実装できるライブラリはあるのか?

調べてみたら、結構ありました。

  • https://github.com/megasanjay/vue3-marquee
  • https://github.com/EvodiaAut/vue-marquee-text-component/
  • ect

ライブラリはありましたが、今回はCSSを使って実装してみたいと思います。
また、Vueの「transition」タグを利用しようかとも考えましたが、
どうやら、CSS「animation-iteration-count: infinite;」のように、繰り返しができないみたいなので、
タグの利用は諦めました...
ですので、ほとんどCSSのみで「marquee」タグのような動きを実装しています。

CSSにて実装

以下、CSS実装内容です。


p.marquee-text {
  margin: 0;
  padding-left: 100vw;
  display: inline-block;
  white-space: nowrap;
  animation-name: marquee;
  animation-timing-function: linear;
  animation-duration: 5000ms;
  animation-iteration-count: infinite;
}

@keyframes marquee {
  from {
    transform: translate(0%);
  }
  99%,
  to {
    transform: translate(-100%);
  }
}

まず「padding-left: 100vw;」で、画面の右外に要素を配置しております。
右外に配置した要素に、アニメーションをあてて、「@keyframes」と「transform」を使い、
要素の位置を左にスクロールする処理を記載しております。
※値などはご自身のお好みで調整してください。
今回Vueで実装した全体のコードは以下の通りです。


<template>
  <div id="marquee-box" :style="durationTime">
    <div class="marquee d-flex flex-row">
      <div class="marquee-title text-center">
        <v-chip color="primary" label>
          <v-icon left> mdi-information-outline </v-icon>
          {{ title }}
        </v-chip>
      </div>
      <div class="marquee-text-box">
        <p class="marquee-text">
          <nuxt-link :to="this.list[0].link">
            {{ this.showText }}
          </nuxt-link>
        </p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    propsTextList: {
      type: Array,
      required: true,
    },
    time: {
      type: Number,
      required: false,
      default: 10000,
    },
    title: {
      type: String,
      required: true,
    },
  },
  data() {
    return {
      list: this.propsTextList,
      showText: this.propsTextList[0].title,
      nextShowText: "",
    };
  },
  mounted() {
    setInterval(() => {
      this.showText = this.nextShowText;
      const tmp = this.list.shift();
      this.nextShowText = tmp.title;
      this.list.push(tmp);
    }, this.time);
  },
  computed: {
    durationTime() {
      return {
        "--duration-time": this.time + "ms",
      };
    },
  },
};
</script>

<style lang="scss" scoped>
#marquee-box {
  width: 100%;

  div.marquee {
    div.marquee-title {
      height: 32px;
      margin: auto 0;
    }
    div.marquee-text-box {
      overflow: hidden;
      p.marquee-text {
        margin: 0;
        padding-left: 100vw;
        display: inline-block;
        white-space: nowrap;
        animation-name: marquee;
        animation-timing-function: linear;
        animation-duration: var(--duration-time);
        animation-iteration-count: infinite;
        color: black;
      }
    }
  }
}

@keyframes marquee {
  from {
    transform: translate(0%);
  }
  99%,
  to {
    transform: translate(-100%);
  }
}
</style>

配列を受け取って、一要素ずつ表示させるようにしたり、アニメーションの時間もpropsとして受け取れるように改造しております。
※「Vuetify」も利用しております。
※実際の動きを確認したい場合は「ブログトップページ」へ!

まとめ

今回は「marquee」をVueにて実装しましたが、
ネットにもソースが載ってましたし、結構楽に実装できました。
みなさんもぜひ実装してみてください!
それではまた次回の記事でお会いしましょう!

関連記事(AI判定作成中)