見出し画像

ポモドーロタイマー作ってみた(chatGPTにWEBアプリ作らせた)

ポモドーロタイマー入門

ポモドーロタイマーめっちゃいいです。
これに集中したい!というときにこのタイマーを使うとすごく捗る。
仕事で朝のルーティーンに使ったり、資料作成のときに使っていますよ。

パソコンで作業することが多いのでWEBアプリを自作しました。
ブラウザのタブのところでカウントダウンするタイプです。
作成にはAIを使ってます。

小さいので邪魔にならない

リンクはこちら


ポモドーロタイマーの解説

ポモドーロタイマー(ポモドーロテクニック)は時間管理および作業効率を向上させるための時間管理法です。フランチェスコ・シリロが1980年代に開発しました。

このテクニックでは、作業を25分の「ポモドーロ」と呼ばれる単位で区切ります。各ポモドーロの後には5分の短い休憩があります。4つのポモドーロを終えた後には長めの休憩(通常は15〜30分)を取ります。

ポモドーロタイマーの基本的な手順は次の通りです。

  1. タスクを選択する:取り組むべきタスクを選びます。

  2. タイマーをセットする:ポモドーロの長さを25分に設定し、タイマーを開始します。

  3. 集中して作業する:タイマーが動いている間、選んだタスクに集中して取り組みます。他のタスクや中断は避けます。

  4. タイマーが終了したら休憩する:25分が経過すると、タイマーが終了します。その後、5分間の短い休憩を取ります。

  5. 休憩後に再び作業する:休憩が終わったら、再び25分のポモドーロを開始し、作業に取り組みます。

  6. 4つのポモドーロ後に長めの休憩を取る:4つのポモドーロ(25分×4)を終えると、長めの休憩(通常は15〜30分)を取ります。

  7. サイクルを繰り返す:上記の手順を繰り返し、作業を進めます。

ポモドーロタイマーは、時間の区切りと集中力の維持を通じて、効率的な作業を促すことができます。また、短い休憩を取ることで疲労を軽減し、集中力を回復させる効果もあります。タイマーが動いている間、選んだタスクに集中しましょう。他のタスクや中断は避けます。この方法は、時間管理や作業スケジュールのプランニングに役立つとされています。

↑(この文章はAIに書いてもらいました)


AIに作らせる

AIに作らせる 最初の指示

「JavascriptとHTMLでポモドーロタイマーを作って」とAIに指示しました。

出来上がりの一部が下のコードなのですが、
このままだと全然ダメなのです。
タイマーがズレます。

こちらです↓HTMLファイル(index.html):

<!DOCTYPE html>
<html>
<head>
  <title>Pomodoro Timer</title>
  <style>
    body {
      text-align: center;
      font-family: Arial, sans-serif;
    }
    h1 {
      margin-top: 50px;
    }
    #timer {
      font-size: 48px;
      margin-top: 20px;
    }
    #buttons {
      margin-top: 30px;
    }
    button {
      font-size: 18px;
      padding: 10px 20px;
      margin-right: 10px;
    }
  </style>
</head>
<body>
  <h1>Pomodoro Timer</h1>
  <div id="timer">25:00</div>
  <div id="buttons">
    <button onclick="startTimer()">Start</button>
    <button onclick="resetTimer()">Reset</button>
  </div>

  <script src="script.js"></script>
</body>
</html>

JavaScriptファイル(script.js):

var seconds;
var timerInterval;

function startTimer() {
  var workMinutes = 25; // 作業時間(分)
  seconds = workMinutes * 60; // タイマーの初期値(秒)

  // タイマーを表示する要素
  var timerElement = document.getElementById("timer");

  timerInterval = setInterval(function() {
    var minutes = Math.floor(seconds / 60); // 分
    var remainingSeconds = seconds % 60; // 秒

    // タイマーの表示を更新
    timerElement.innerHTML = minutes + ":" + (remainingSeconds < 10 ? "0" : "") + remainingSeconds;

    if (seconds <= 0) {
      clearInterval(timerInterval);
      alert("Time's up!"); // タイマー終了時のアラート

      // 休憩時間を設定(例: 5分)
      var breakMinutes = 5;
      seconds = breakMinutes * 60;
      timerInterval = setInterval(startBreakTimer, 1000);
    } else {
      seconds--;
    }
  }, 1000);
}

function resetTimer() {
  clearInterval(timerInterval);
  document.getElementById("timer").innerHTML = "25:00"; // タイマーをリセット
}


AIに作らせる 専門用語で指示

専門用語を使って指示しました。
「setInterval関数を使うと動作が不安定になるのでsetTimeout関数を使って書き直して」

「〇〇関数」と専門用語が出てますが「もっと正確にして」とかでもOKだと思います。


下がコード
JavaScriptファイル(script.js):

var seconds;
var timerTimeout;

function startTimer() {
  var workMinutes = 25; // 作業時間(分)
  seconds = workMinutes * 60; // タイマーの初期値(秒)

  // タイマーを表示する要素
  var timerElement = document.getElementById("timer");

  timerTimeout = setTimeout(countdown, 1000);

  function countdown() {
    var minutes = Math.floor(seconds / 60); // 分
    var remainingSeconds = seconds % 60; // 秒

    // タイマーの表示を更新
    timerElement.innerHTML = minutes + ":" + (remainingSeconds < 10 ? "0" : "") + remainingSeconds;
    
    if (seconds <= 0) {
      clearTimeout(timerTimeout);
      alert("Time's up!"); // タイマー終了時のアラート

      // 休憩時間を設定(例: 5分)
      var breakMinutes = 5;
      seconds = breakMinutes * 60;
      timerTimeout = setTimeout(startBreakTimer, 1000);
    } else {
      seconds--;
      timerTimeout = setTimeout(countdown, 1000);
    }
  }
}

function resetTimer() {
  clearTimeout(timerTimeout);
  document.getElementById("timer").innerHTML = "25:00"; // タイマーをリセット
}

だいぶマシになりました。これでも少しズレます。
ざっくりタイマーでよければこれでOKです。

AIに作らせる 人の言葉で具体的に

専門用語を出さずに人の言葉で具体的にAIに指示してみました。
「ちょっと時間がずれるのでStartボタンを押したときの現在時間を保存して、その現在時間との差分でカウントダウンするように書き換えて」

下がコード
JavaScriptファイル(script.js):

var startTime;
var currentTime;
var remainingTime;
var timerTimeout;
var isRunning = false;

function startTimer() {
  if (isRunning) {
    return; // タイマーが既に実行中の場合は処理を終了
  }

  var workMinutes = 25; // 作業時間(分)
  var endTime = Date.now() + workMinutes * 60 * 1000; // 終了時刻(ミリ秒)

  isRunning = true;

  requestAnimationFrame(updateTimer);

  function updateTimer() {
    currentTime = Date.now();
    remainingTime = endTime - currentTime;

    if (remainingTime <= 0) {
      isRunning = false;
      alert("Time's up!"); // タイマー終了時のアラート
    } else {
      var minutes = Math.floor(remainingTime / (1000 * 60)); // 分
      var seconds = Math.floor((remainingTime / 1000) % 60); // 秒

      // タイマーを表示する要素
      var timerElement = document.getElementById("timer");
      timerElement.innerHTML = minutes + ":" + (seconds < 10 ? "0" : "") + seconds;

      requestAnimationFrame(updateTimer);
    }
  }
}

function resetTimer() {
  isRunning = false;
  cancelAnimationFrame(timerTimeout);
  document.getElementById("timer").innerHTML = "25:00"; // タイマーをリセット
}

この修正版では、requestAnimationFrameを使用してタイマーを正確に更新します。startTimer関数が呼び出されると、現在時刻を取得し、endTimeを計算してタイマーを開始します。updateTimer関数内で現在時刻と終了時刻との差分を計算し、タイマーを表示します。タイマーが終了した場合はアラートを表示し、タイマーの実行を停止します。

以上の修正版を使用してポモドーロタイマーを作成してください。これにより、より正確なタイミングでタイマーが動作するはずです。

↑AIの解説

requestAnimationFrame関数を使う方法を提示してきました。

やるやん

俺は知ってたけどね、知ってたrequestAnimationFrame関数。

AIが気づくか試したんよ(知らんかった)


AIに作らせる タイマーがズレないように

前項で作ったタイマーでも時間表示がズレてしまう場合があります。
他のタブを開くと、ブラウザの仕組みで表示されていないタブの中の処理が遅くなるのでズレるのです。
次はズレないように決定的な指示をしました。
「今書いたプログラムをマルチスレッドを使って書き直して」

index.html:

<!DOCTYPE html>
<html>
<head>
  <title>Pomodoro Timer</title>
  <style>
    body {
      text-align: center;
      font-family: Arial, sans-serif;
    }
    h1 {
      margin-top: 50px;
    }
    #timer {
      font-size: 48px;
      margin-top: 20px;
    }
    #buttons {
      margin-top: 30px;
    }
    button {
      font-size: 18px;
      padding: 10px 20px;
      margin-right: 10px;
    }
  </style>
</head>
<body>
  <h1>Pomodoro Timer</h1>
  <div id="timer">25:00</div>
  <div id="buttons">
    <button onclick="startTimer()">Start</button>
    <button onclick="resetTimer()">Reset</button>
  </div>

  <script>
    var timerWorker;
    var isRunning = false;
    var workMinutes = 25;
    var breakMinutes = 5;
	//ローカル環境で動作させるときの対策
	let newWorkerViaBlob = function(relativePath) {
	  let baseURL = window.location.href.replace(/\\/g, '/').replace(/\/[^\/]*$/, '/');
	  let array = ['importScripts("' + baseURL + relativePath + '");'];
	  let blob = new Blob(array, {type: 'text/javascript'});
	  let url = window.URL.createObjectURL(blob);
	  return new Worker(url);
	};

    function startTimer() {
      if (isRunning) {
        return; // タイマーが既に実行中の場合は処理を終了
      }

      isRunning = true;

      // Web Workerを生成してタイマー処理を開始
      timerWorker = new newWorkerViaBlob("timerWorker.js");
      timerWorker.onmessage = function(event) {
        var timerElement = document.getElementById("timer");
        timerElement.innerHTML = event.data;
        document.title = event.data;
        if (event.data === "00:00") {
          isRunning = false;
          alert("Time's up!"); // タイマー終了時のアラート

          //if (breakMinutes > 0) {
          //  startTimer();
          //}
        }
      };

      // タイマー開始メッセージをWeb Workerに送信
      timerWorker.postMessage(workMinutes);
    }

    function resetTimer() {
      if (timerWorker) {
        timerWorker.terminate(); // Web Workerを停止
        timerWorker = null;
      }

      document.getElementById("timer").innerHTML = "25:00"; // タイマーをリセット
      isRunning = false;
    }
  </script>
</body>
</html>

timerWorker.js:

var remainingSeconds;
var timerInterval;

// メッセージの受信イベントハンドラ
onmessage = function(event) {
  var workMinutes = event.data;
  remainingSeconds = workMinutes * 60;

  startCountdown();
};

function startCountdown() {
  var minutes = Math.floor(remainingSeconds / 60);
  var seconds = remainingSeconds % 60;

  var formattedTime = formatTime(minutes, seconds);

  postMessage(formattedTime);

  if (remainingSeconds <= 0) {
    clearInterval(timerInterval);
  } else {
    timerInterval = setInterval(function() {
      remainingSeconds--;
      var minutes = Math.floor(remainingSeconds / 60);
      var seconds = remainingSeconds % 60;

      var formattedTime = formatTime(minutes, seconds);

      postMessage(formattedTime);

      if (remainingSeconds <= 0) {
        clearInterval(timerInterval);
      }
    }, 1000);
  }
}

function formatTime(minutes, seconds) {
  var formattedMinutes = String(minutes).padStart(2, "0");
  var formattedSeconds = String(seconds).padStart(2, "0");
  return formattedMinutes + ":" + formattedSeconds;
}

上のコードはAIが提出したものを、ちょっと修正しました。
 (タブにタイマーを表示、ローカルでも動作する修正)

5分休憩の処理が未完成とか、表示と動作が混じってるとか、
まだ変なところがあるんですが、AI作品として、ひとまず完成とします。
完璧を目指すより、完成を優先です。

AIを使うと楽なのは間違いないです。AIは人の目的を理解するところまでには到達していないので具体的に細かく指示しないと使いこなすのは難しい。

このような
「ちょっと時間がずれるのでStartボタンを押したときの現在時間を保存して、その現在時間との差分でカウントダウンするように書き換えて」
こういう指示は開発経験がないとできない。


最後に

ポモドーロタイマー、すごくいいですよ。
仕事で朝のルーティーンに使ったり、資料作成のときに使っています。
いろいろな仕事術を見るんですが、一番良かった。

他の人が作ったタイマーアプリはあるんですが、タイマーがデカく主張して使いにくかったので自作しました。
メモ程度の簡易なTODOリストがついてたら良さそうなので、また作って公開したいと思います。



この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?