Javascript Timer の停止再開インターバル変更など

データベースのデータを読み込んで、飛行機の航跡地図を表示する処理で、録画した航跡の再現速度を速くしたり、遅くしたり、録画位置の変更、一時停止などする必要があるため作ってみました。
調べましたところ、タイマーを解除するのはclearIntervalで出来るのがわかりましたが、一時停止するメソッドがないようなので、タイマーは動かしたままにして、タイマーの処理内でフラグを見て判別してます。
再生速度変更も同じようにして、clearIntervalで解除してインターバルを変えて再開しています。

< コード例 >

HTML
Bootstrap4のモーダルダイアログのタイトル

        <div class="pull-left mt-0 histrangeclass">

          <!-- ポーズ再開ボタン -->
          <button id="histpause" type="button" class="btn btn-sm btn-primary tippyspan histshow pauseresume"
                    title="Pause live"><i class="fa fa-pause"></i></button>
          <button id="histresume" type="button" class="btn btn-sm btn-primary tippyspan histshow pauseresume dsp_none"
                    title="Resume live"><i class="fa fa-play"></i></button>          

          <!-- ヒストリースライダー -->
          <input id="histrange" type="range" class="histshow dsp_none curpo" min="1" max="200" step="1">  
          <span id="range_pos" class="histshow dsp_none">126/200</span>

          <!-- インターバルボタンズ --> 
          <span id="hist_int_buttons">

            <button id="histint_2" type="button" class="btn btn-sm btn-primary tippyspan histshow intbtns"
                    title="Change to 2 sec interval">2</button>
            <button id="histint_3" type="button" class="btn btn-sm btn-primary tippyspan histshow intbtns"
                    title="Change to 3 sec interval">3</button>

            <button id="histint_7" type="button" class="btn btn-sm btn-primary tippyspan histshow intbtns"
                    title="Change to 7 sec interval">7</button>

            <button id="histint_15" type="button" class="btn btn-sm btn-primary tippyspan histshow intbtns"
                    title="Change to 15 sec interval">15</button>

            <button id="histint_22" type="button" class="btn btn-sm btn-primary tippyspan histshow intbtns"
                    title="Change to 22 sec interval">22</button>

            <button id="histint_33" type="button" class="btn btn-sm btn-primary tippyspan histshow intbtns"
                    title="Change to 33 sec interval">33</button>

            <button id="histint_45" type="button" class="btn btn-sm btn-primary tippyspan histshow intbtns"
                    title="Change to 45 sec interval">45</button>

          </span>  

        </div>

タイマー関数


    /**
     * 飛行機マーカー描画タイマー関数
     * @param {type} interval タイマーインターバル (ms)
     * @returns {undefined}
     */
    const timerFunc = (interval) => {

      $("#timerint").removeClass("dsp_none")
      $("#timerint").show()
      $("#timerint").text("T:" + parseInt(interval / 1000))

      HistoryMap.histTimer = setInterval(() => {

        if (!isPaused) {

          const slidepos = eval(recpos) + eval(1)

          // スライダーを動かす //
          $("#histrange").val(recpos)
          $("#range_pos").text(`${slidepos}/${recs.length}`)

          console.log("TimerPos:" + recpos)
          const tmpdata = JSON.parse(recs[recpos]["TXT_JSON"])

          // 時計更新 //
          const currtmtxt = recs[recpos]["TM_ADD"].slice(5, 16).replace("-", "/") + "(JST)"
          const currtmtxtUTC = recs[recpos]["TM_ADD_UTC"].slice(5, 16).replace("-", "/") + "(UTC)"
          const postxt = `${eval(recpos) + eval(1)}/${recs.length}`
          console.log(currtmtxt)

          $("#historymap_time").text(currtmtxt + "  " + currtmtxtUTC + "  " + postxt)

          // 中心、ズーム //
          const clat = recs[recpos]["CLAT"]
          const clon = recs[recpos]["CLON"]
          const zoom = recs[recpos]["ZOOM"]
          //lmap.setView([clat, clon], zoom)
          lmap.flyTo([clat, clon], zoom)
          //lmap.panTo([clat, clon], zoom)


          // 飛行機マーカー描画 //
          const mmp = new MoveMarkerParent("", this.userId, false,
                  false, "", "")
          mmp.setTypeAndVoice("HISTORY", recs[recpos]["MP3_MSG"])
          const mkres = mmp.drawAircraftMarkers(lmap, tmpdata, false, false)
          console.log(mkres)

          recpos++;

          if (recpos === recs.length) {
           
            recpos = 0
          }

        }

      }, interval)

    }

初回読込


    let isPaused = false    // 停止用フラグ
    let recpos = 1          // 再生位置
 
    let intvl = Math.floor(this.firstInterval * 3 / 4 * 1000)

    // 初期インターバルボタン強調 //
    $("#histint_" + parseInt(intvl / 1000)).removeClass("btn-primary")
    $("#histint_" + parseInt(intvl / 1000)).addClass("btn-dark")

    // ライブ受信ランプ 受信コストを常に消す //
    $("#liveramp, #t2scost, #livecost").addClass("dsp_none")
    $("#liveramp, #t2scost, #livecost").hide()

    //alert(intvl)
    // 飛行機マーカー描画タイマー関数 //
    timerFunc(intvl)

停止、再開ボタンのリスナー


    // @@ 停止再開ボタンを押した時 @@ //
    $(".pauseresume").on("click", function (e) {

      const id = $(this).attr("id")
      isPaused = id === "histpause"
      $(this).addClass("dsp_none")
      $(this).hide()

      const opobtnid = isPaused ? "#histresume" : "#histpause"
      $(opobtnid).removeClass("dsp_none")
      $(opobtnid).show()

    })

スライダーでの位置変更


    $("#histrange").off("input")

    // @@ レンジスライダーの値が変わる時 @@ //
    // ユーザーが変えた場合発生、タイマーからは発生しない //
    $("#histrange").on("input", function (e) {

      const val = $(this).val()
      console.log("# input # slider pos is " + val)

      $("#range_pos").text(`${val}/${recs.length}`)

      isPaused = true

    })

再生インターバル変更ボタンのリスナー


    $(".intbtns").off("click")

    // @@ インターバル変更ボタンを押した時 @@ //
    $(".intbtns").on("click", function (e) {

      const val = $(this).text()
      //alert(val)

      $(".intbtns").removeClass("btn-dark")
      $(".intbtns").addClass("btn-primary")
      $(this).addClass("btn-dark")

      // タイマー再セットインターバル変更 //
      try {
        clearInterval(HistoryMap.histTimer)
      }
      catch (e) {
      }

      // 飛行機マーカー描画タイマー関数 //
      timerFunc(val * 1000)


    })

< 画面例 >
ボタンのテキストはインターバルの秒数です。
スライダーはHTMLの標準のを使ってスタイルはここを真似ました。

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

航空情報 2023年 4月号 [雑誌]
価格:1425円(税込、送料無料) (2023/3/3時点)

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

航空ファン 2023年 4月号 [雑誌]
価格:1361円(税込、送料無料) (2023/3/3時点)

コメントを残す