1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ネイティブJSでサウンドノベル風テキストアニメーション

Posted at

サウンドノベルっぽいテキストアニメーションをJSで実現したい。

どういう動きかというとこんな感じ↓

ライブラリはいくつかあるのだけれども、やりたいことをすべて叶えてくれるものはなかった…ので、書きました。

やりたいこと

  1. 指定したテキストが1文字ずつ表示される
  2. 表示途中でクリックすると全文表示される
  3. 表示完了後にクリックすると次のテキストの表示を開始する
  4. 複数のJSから上記の共通処理を呼び出す

完成形

元はviteで書いていたコードを単純jsっぽく直したので整合性取れていないところがあるかもしれませんが…こんな感じになりました。

TypeWriter.js
/*
  TypeWriter

  呼び出し元で1つインスタンスを生成して使用
 */
export const TypeWriter = class {
  constructor(query) {
    this.charNum = 0
    this.textWriteEnd = false
    this.el = document.querySelector(query)
  }

  print(text) {
    this.textWriteEnd = false
    this.charNum = 0
    this.el.textContent = ''
    const self = this
    self._print(text.split(''))
  }

  _print(chars) {
    const self = this
    const timer = setTimeout(() => { self._print(chars) }, 50)

    if (this.charNum < chars.length) {
      this.el.textContent += chars[this.charNum]
      this.charNum++
      if (this.charNum === chars.length) {
        this.textWriteEnd = true
      }
    } else {
      clearTimeout(timer)
      this.textWriteEnd = true
    }
  }

  printAll(text) {
    this.charNum = text.split('').length + 1
    this.el.textContent = text
  }
}
sample.js
import { TypeWriter } from '/js/typewriter.js'

let page = 0
let tw
let clickable = false

const textList = [
  { txt: 'テキスト1' },
  { txt: 'テキスト2' },
]

window.onload = () => {
    tw = new TypeWriter('#id') // テキスト描画したい要素
  setTimeout(() => {
    tw.print(textList[page].txt)
    clickable = true
  }, 500)
}

// クリックイベント
const goNext = () => {
  if (!clickable) return

  if (tw.textWriteEnd) {
    page++

    if (page < textList.length) {
      tw.print(textList[page].txt)
    } else {
      // URL遷移
    }
  } else {
    tw.printAll(textList[page].txt)
  }
}

おすすめライブラリ

もっとシンプルで良いのなら、iTyped.jsがおすすめです。

今回は「途中クリックで全文表示」という要件が出た時点で使えなくなりました(泣)

参考にさせていただいたサイト

あとがき

jsはなんとなくでずっといじっていて、今回初めてclassを使いました。
多分美しくないコードだと思います。
ご指摘やアドバイスは歓迎いたします。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?