Создайте индикатор заряда батареи с помощью React (работает только в Chrome)
В этой статье мы собираемся создать интересный проект — компонент индикатора заряда батареи с использованием React. Этот компонент покажет вам текущий уровень заряда батареи и заряжается ли ваше устройство.
Однако наш индикатор батареи будет использовать метод Navigator.getBattery() для получения информации о батарее, которая не поддерживается браузерами Mozilla и Safari. Кроме того, он доступен только в безопасном контексте (HTTPS).
Это означает, что наш компонент будет работать только в Chrome и других браузерах на базе Chromium, таких как Edge.
Вот почему это скорее развлекательный проект, чем практический.
Давайте начнем!
1. Создайте новый проект React, используя Vite и шаблон React
Выполните следующие команды, чтобы создать новый проект React с использованием Vite и шаблона React.
npm create vite@latest battery-indicator - - template react
cd battery-indicator
npm install
2. Установите CSS Tailwind
Мы будем использовать CSS Tailwind для оформления нашего компонента индикатора заряда батареи. Выполните следующие команды, чтобы установить Tailwind CSS и его зависимости.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Обновите файл Tailwind.config.js
, включив в него следующее:
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx}'],
theme: {
extend: {},
},
plugins: [],
}
Затем добавьте директивы @tailwind
поверх файла src/index.css
.
@tailwind base;
@tailwind components;
@tailwind utilities;
3. Создайте компонент индикатора заряда батареи
Создайте новый файл с именем BatteryIndicator.jsx
в папке src/comComponents
. Этот файл будет содержать компонент индикатора заряда батареи.
Начнем с состояния информации о батарее и функции обновления информации о батарее.
// Initial battery info: battery level: 0-100, charging status: true/false, supported by the browser: true/false
const initialBatteryInfo = { level: 0, charging: false, supported: true };
// Battery info state
const [batteryInfo, setBatteryInfo] = useState(initialBatteryInfo);
// Update the battery info
const updateBatteryInfo = (battery) => {
setBatteryInfo({ level: battery.level * 100, charging: battery.charging, supported: true });
};
Мы должны быть уверены, что браузер поддерживает API состояния батареи, прежде чем мы сможем его использовать. Для этого мы можем проверить, доступен ли метод getBattery
в объекте навигатора с помощью navigator.getBattery
. Если он доступен, мы можем использовать его, чтобы узнать состояние батареи. Если это не так, мы устанавливаем для поддерживаемого свойства состояния информации о батарее значение false
.
Затем мы используем перехватчик useEffect
, чтобы проверить, поддерживает ли браузер API состояния батареи, и настроить прослушиватели событий для изменения состояния батареи.
Функция, которая предоставляет статус батареи, — navigator.getBattery()
. Это асинхронная функция, поэтому для ее разрешения нам нужно использовать await
.
useEffect(() => {
// Check if the browser supports the Battery Status API and setup the event listeners
const checkBatteryAPIAndSetup = async () => {
if (navigator.getBattery) {
try {
// Get the battery status
const battery = await navigator.getBattery();
updateBatteryInfo(battery);
// Setup the event listeners for the battery status changes
battery.addEventListener('chargingchange', () => updateBatteryInfo(battery));
battery.addEventListener('levelchange', () => updateBatteryInfo(battery));
} catch (error) {
console.error('Battery status is not supported.');
setBatteryInfo((prev) => ({ ...prev, supported: false }));
}
} else {
console.error('Battery status is not supported.');
setBatteryInfo((prev) => ({ ...prev, supported: false }));
}
};
checkBatteryAPIAndSetup();
}, []);
Теперь давайте создадим пользовательский интерфейс для компонента индикатора батареи. Он будет состоять из шкалы уровня заряда батареи, текста об уровне заряда батареи и значка зарядки.
// Component to display the battery info
const BatteryInfo = ({ batteryInfo }) => (
<div className={`w-32 h-14 border-2 ${batteryInfo.charging ? 'border-green-500' : 'border-gray-500'} rounded-lg flex items-center justify-start overflow-hidden relative`}>
{/* Battery level bar */}
<div
className={`${batteryInfo.level > 20 ? 'bg-green-300' : 'bg-red-500'} h-full`}
style={{ width: `${batteryInfo.level}%` }}
></div>
{/* Battery level text */}
<div className="absolute w-full h-full flex items-center justify-center text-lg font-semibold">
{batteryInfo.level.toFixed(0)}%
</div>
{batteryInfo.charging && <ChargingIcon />}
</div>
);
Полоса уровня заряда батареи имеет ширину, соответствующую уровню заряда батареи. Мы используем атрибут style
, чтобы установить ширину полосы в зависимости от уровня заряда батареи. Мы используем метод toFixed
для округления уровня заряда батареи до ближайшего целого числа.
Простая логика используется для определения цвета шкалы уровня заряда батареи в зависимости от уровня заряда батареи. Если уровень заряда батареи превышает 20%, полоса будет зеленой, в противном случае — красной.
Мы также показываем значок зарядки, если устройство заряжается:
const ChargingIcon = () => (
<svg className="absolute right-0 mr-[-6px] w-6 h-6 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 7L6 12h4v8l5-5h-4v-8z" />
</svg>
);
Теперь давайте объединим все это в компоненте BatteryIndicator
:
import { useState, useEffect } from 'react';
// Initial battery info: battery level: 0-100, charging status: true/false, supported by the browser: true/false
const initialBatteryInfo = { level: 12, charging: true, supported: true };
export function BatteryIndicator() {
const [batteryInfo, setBatteryInfo] = useState(initialBatteryInfo);
// Update the battery info
const updateBatteryInfo = (battery) => {
setBatteryInfo({ level: battery.level * 100, charging: battery.charging, supported: true });
};
useEffect(() => {
// Check if the browser supports the Battery Status API and setup the event listeners
const checkBatteryAPIAndSetup = async () => {
if (navigator.getBattery) {
try {
// Get the battery status
const battery = await navigator.getBattery();
updateBatteryInfo(battery);
// Setup the event listeners for the battery status changes
battery.addEventListener('chargingchange', () => updateBatteryInfo(battery));
battery.addEventListener('levelchange', () => updateBatteryInfo(battery));
} catch (error) {
console.error('Battery status is not supported.');
setBatteryInfo((prev) => ({ ...prev, supported: false }));
}
} else {
console.error('Battery status is not supported.');
setBatteryInfo((prev) => ({ ...prev, supported: false }));
}
};
checkBatteryAPIAndSetup();
}, []);
return (
<div className="flex items-center justify-center h-screen">
<div className="text-center">
{batteryInfo.supported ? (
<div className="flex flex-col items-center justify-center space-y-2">
<BatteryInfo batteryInfo={batteryInfo} />
</div>
) : (
<div className="p-4 rounded-md bg-gray-200 text-gray-700">
Battery status is not supported in this browser.
</div>
)}
</div>
</div>
);
}
Итак, наш компонент готов. Теперь давайте импортируем его в компонент приложения, удалим все остальное и посмотрим в действии.
import { BatteryIndicator } from './components/BatteryIndicator';
function App() {
return (
<div>
<BatteryIndicator />
</div>
);
}
export default App;
Теперь выполните следующую команду, чтобы запустить сервер разработки, и откройте приложение в браузере.
npm run dev
Откройте localhost:5173 в своем браузере. Вы должны увидеть компонент индикатора батареи, показывающий текущий уровень заряда батареи и то, заряжается ли ваше устройство.
Если ваше устройство заряжается, вы должны увидеть значок зарядки в правой части панели уровня заряда батареи.
Если уровень заряда батареи менее 20 %
, полоса уровня заряда батареи будет красной:
Если состояние батареи не поддерживается вашим браузером, вы должны увидеть сообщение «Состояние батареи не поддерживается в этом браузере».
Вот и все! Вы создали компонент индикатора заряда батареи с помощью React. Это забавный проект, который работает только в Chrome и других браузерах на базе Chromium
, таких как Edge
. Это непрактично, но это интересный способ узнать об API состояния батареи и о том, как его использовать в приложении React.