Chrome拡張機能でタイマーを作った

## 背景

集中していると時間忘れがちだな…。
スマホのアラームでもいいけど、chromeから即設定出来ないかな…。
一定時間ごに画面が揺れたら気づけそうだな…。


# 作ってみました。



   



## 以下のコードを1つのフォルダに纏めてください

また、別途icon.pngを各自で用意をお願いします。
拡張機能用のアイコンですが、ないとchromeへのimport時にエラーになります。

## ソースコード

```js background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'setAlarm') {
    const minutes = message.minutes;
    const alarmName = `shakeAlarm_${Date.now()}`;

    chrome.alarms.create(alarmName, { delayInMinutes: minutes });
    chrome.alarms.onAlarm.addListener(alarm => {
      if (alarm.name === alarmName) {
        chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
          chrome.tabs.sendMessage(tabs[0].id, { action: 'shakeScreen' });
        });
      }
    });
  }
});

```

```js content.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'shakeScreen') {
    shakeScreen();
  }
});

function shakeScreen() {
  const shakeIntensity = 20;
  const shakeDuration = 500;
  const shakeInterval = 50;
  const originalStyles = document.body.style.cssText;

  let elapsed = 0;

  const shake = setInterval(() => {
    const x = (Math.random() - 0.5) * shakeIntensity;
    const y = (Math.random() - 0.5) * shakeIntensity;
    document.body.style.transform = `translate(${x}px, ${y}px)`;
    elapsed += shakeInterval;

    if (elapsed >= shakeDuration) {
      clearInterval(shake);
      document.body.style.cssText = originalStyles;
    }
  }, shakeInterval);
}

```


```json manifest.json
{
  "manifest_version": 3,
  "name": "Screen Shaker",
  "version": "1.0",
  "description": "Shake the screen after a selected interval.",
  "permissions": ["alarms", "activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "icon.png",
      "48": "icon.png",
      "128": "icon.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "icons": {
    "16": "icon.png",
    "48": "icon.png",
    "128": "icon.png"
  },
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ]
}

```


```html popup.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Screen Shaker</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      width: 200px;
    }
    .button {
      display: block;
      width: 100%;
      padding: 10px;
      margin: 5px 0;
      text-align: center;
      background-color: #007bff;
      color: white;
      border: none;
      cursor: pointer;
    }
    .button:hover {
      background-color: #0056b3;
    }
  </style>
</head>
<body>
  <h3>Select time to shake the screen:</h3>
  <button class="button" data-time="0.083">5 seconds</button>
  <button class="button" data-time="0.167">10 seconds</button>
  <button class="button" data-time="0.25">15 seconds</button>
  <button class="button" data-time="1">1 minutes</button>
  <button class="button" data-time="5">5 minutes</button>
  <button class="button" data-time="10">10 minutes</button>
  <button class="button" data-time="15">15 minutes</button>
  <script src="popup.js"></script>
</body>
</html>
```

```js popup.js

document.addEventListener('DOMContentLoaded', function () {
  const buttons = document.querySelectorAll('.button');
  buttons.forEach(button => {
    button.onclick = () => {
      const minutes = parseFloat(button.getAttribute('data-time'));
      chrome.runtime.sendMessage({ action: 'setAlarm', minutes: minutes });
    };
  });
});

```

## import手順

- chromeの右上をクリックし「拡張機能を管理」を選択。
- 右上の「ディベロッパーモード」をonに。
- 左上の「パッケージ化されていない機能を取り込む」を選択し、上記で用意したファイル群のフォルダを選択。
- 右上の設定時間をクリック

![スクリーンショット 2024-07-01 12.02.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327773/9753d8c5-862e-7a6f-835c-ee85a1b71128.png)


## 実際の挙動

![ScreenShaker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327773/20e9e179-59c2-a507-846b-c9f8afbc17eb.gif)