Espruino:Примеры/Циферблаты Bangle.js: различия между версиями
Myagkij (обсуждение | вклад) (Новая страница: «{{Espruino/Панель перехода}} {{Перевод от Сubewriter}} {{Myagkij-редактор}} =<ref>[ www.espruino.com - ]</ref>= <syntaxhighligh...») |
Myagkij (обсуждение | вклад) Нет описания правки |
||
Строка 3: | Строка 3: | ||
{{Myagkij-редактор}} | {{Myagkij-редактор}} | ||
=<ref>[ www.espruino.com - ]</ref>= | =Циферблаты Bangle.js<ref>[https://www.espruino.com/Bangle.js+Clock www.espruino.com - Bangle.js Clock Faces]</ref>= | ||
Это руководство подразумевает, что вы уже прошли [https://www.espruino.com/Bangle.js+Development руководство «Разработка под Bangle.js»] и понимаете, с чего начать. | |||
Если да, то вы уже должны быть подключены и умеете писать простой код. Поэтому давайте попробуем сделать простенький циферблат! | |||
Для этого лучше использовать правую часть IDE – после загрузки кода мы, если захотим, сможем менять значения и вызывать функции при помощи REPL в левой части IDE. | |||
== Отрисовка линии == | |||
Скопируйте код ниже в правую часть IDE и кликните на кнопку загрузки кода: | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
function draw() { | |||
// Задаём, как будем показывать текущее время: | |||
var d = new Date(); | |||
var h = d.getHours(), m = d.getMinutes(); | |||
var time = h + ":" + ("0"+m).substr(-2); | |||
// Сбрасываем состояние графической библиотеки: | |||
g.reset(); | |||
// Очищаем область, где хотим нарисовать время: | |||
g.clearRect(50,50,100,120); | |||
// Рисуем текущее время: | |||
g.drawString(time, 50, 50); | |||
} | |||
// Очищаем экран один раз (на запуске): | |||
g.clear(); | |||
// Сначала сразу рисуем: | |||
draw(); | |||
var secondInterval = setInterval(draw, 1000); | |||
</syntaxhighlight> | |||
Теперь в середине экрана должен быть маленький текст со временем. | |||
Немного странный код ("0"+m).substr(-2) добавляет нули к минутам (то есть в результате формат времени будет "12:01", а не "12:1"). | |||
Почему код отформатирован именно так? Читайте об этом в [https://www.espruino.com/Code+Style статье о стилях кода], в которой также есть несколько советов на эту тему. | |||
== Изменение шрифта == | |||
Во-первых, давайте сделаем текст побольше и нормально его отцентрируем. Большой ассортимент шрифтов можно найти на [https://www.espruino.com/Fonts этой странице]. | |||
Мы воспользуемся кастомным 7-сегментным шрифтом под названием Font7x11Numeric7Seg при помощи строчки g.setFont("7x11Numeric7Seg"). | |||
<syntaxhighlight lang="javascript" enclose="div"> | <syntaxhighlight lang="javascript" enclose="div"> | ||
// Загружаем шрифты: | |||
require("Font7x11Numeric7Seg").add(Graphics); | |||
// Позиция на экране: | |||
const X = 160, Y = 140; | |||
function draw() { | |||
// Задаём, как будем показывать текущее время: | |||
var d = new Date(); | |||
var h = d.getHours(), m = d.getMinutes(); | |||
var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2); | |||
// Сбрасываем состояние графической библиотеки: | |||
g.reset(); | |||
// Рисуем текущее время (7-сегментный шрифт, увеличенный в 4 раза) | |||
g.setFont("7x11Numeric7Seg",4); | |||
g.setFontAlign(1,1); // выравниванием справа снизу | |||
g.drawString(time, X, Y, true /*очищаем фон*/); | |||
// рисуем секунды (7-сегментный шрифт, увеличенный в 2 раза) | |||
g.setFont("7x11Numeric7Seg",2); | |||
g.drawString(("0"+d.getSeconds()).substr(-2), X+30, Y, true /*очищаем фон*/); | |||
} | |||
// Один раз очищаем экран (при запуске): | |||
g.clear(); | |||
// Сначала сразу рисуем: | |||
draw(); | |||
var secondInterval = setInterval(draw, 1000); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
[Картинка] | |||
Примечание: Чтобы избежать мерцания, в drawString() используется четвёртый аргумент, который очищает фон (по умолчанию рисуется только сам текст). | |||
Наконец, добавляем дату. Мы можем воспользоваться для этого библиотекой locale – это значит, что дата будет адаптирована под любого пользователя, независимо от его языка. | |||
Просто добавьте под функцией draw() вот этот код: | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
// Рисуем дату (обычным шрифтом): | |||
g.setFont("6x8"); | |||
g.setFontAlign(0,1); // выравниваем по центру снизу | |||
// Добавляем отступы к дате. | |||
// Это очистит фон, если у даты изменится размер. | |||
var dateStr = " "+require("locale").date(d)+" "; | |||
g.drawString(dateStr, g.getWidth()/2, Y+15, true /*очищаем фон*/); | |||
</syntaxhighlight> | |||
== Дополнительные функции часов == | |||
Теперь у нас есть нечто, показывающее дату, но перед тем, как это станет циферблатом, нам нужно добавить ещё кое-что. | |||
=== Виджеты === | |||
У большинства циферблатов есть виджеты. Чтобы их мог показывать и наш циферблат, нам нужно добавить в конец кода следующее: | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
Bangle.loadWidgets(); | |||
Bangle.drawWidgets(); | |||
</syntaxhighlight> | |||
Вы можете вызывать Bangle.drawWidgets() при каждом очищении экрана плюс виджетам нужно постоянно себя перерисовывать – но лучше делать это как можно реже, чтобы избежать мерцания. | |||
В нашем примере мы очистим экран лишь один раз (при запуске), поэтому и функцию Bangle.drawWidgets() мы тоже вызовем только один раз. | |||
=== Использование кнопки BTN2 для запуска лаунчера === | |||
В каждом циферблате должна быть возможность запустить лаунчер, и по умолчанию за это отвечает кнопка BTN2. Чтобы добавить эту возможность в свой циферблат, просто поместите код ниже в конец всего кода (не в функцию): | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
// Показываем лаунчер после нажатия на среднюю кнопку: | |||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); | |||
</syntaxhighlight> | |||
=== Энергосбережение === | |||
Прямо сейчас мы перерисовываем экран каждую секунду – независимо от того, включен он или нет. Очевидно, что для заряда батареи это плохие новости. | |||
Чтобы оптимизировать этот момент, мы можем отслеживать то, когда экран выключается, и следом выключать интервал secondInterval, а затем снова включать его, когда экран снова включат (и сразу же перерисовывать циферблат): | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
// Останавливаем обновление экрана после его выключения, | |||
// а затем возобновляем, когда он снова будет включен: | |||
Bangle.on('lcdPower',on=>{ | |||
if (secondInterval) clearInterval(secondInterval); | |||
secondInterval = undefined; | |||
if (on) { | |||
secondInterval = setInterval(draw, 1000); | |||
draw(); // сразу же рисуем | |||
} | |||
}); | |||
</syntaxhighlight> | |||
=== Итог === | |||
В результате наш код должен выглядеть вот так: | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
// Загружаем шрифты: | |||
require("Font7x11Numeric7Seg").add(Graphics); | |||
// Позиция на экране: | |||
const X = 160, Y = 140; | |||
function draw() { | |||
// Задаём, как будем показывать текущее время: | |||
var d = new Date(); | |||
var h = d.getHours(), m = d.getMinutes(); | |||
var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2); | |||
// Сбрасываем состояние графической библиотеки: | |||
g.reset(); | |||
// Рисуем текущее время (7-сегментный шрифт, увеличенный в 4 раза): | |||
g.setFont("7x11Numeric7Seg",4); | |||
g.setFontAlign(1,1); // выравниваем справа внизу | |||
g.drawString(time, X, Y, true /*очищаем фон*/); | |||
// Рисуем секунды (7-сегментный шрифт, увеличенный в 2 раза): | |||
g.setFont("7x11Numeric7Seg",2); | |||
g.drawString(("0"+d.getSeconds()).substr(-2), X+30, Y, true /*очищаем фон*/); | |||
// Рисуем дату обычным шрифтом: | |||
g.setFont("6x8"); | |||
g.setFontAlign(0,1); // выравниваем по центру снизу: | |||
// Добавляем отступы к дате. | |||
// Это очистит фон, если у даты изменится размер. | |||
var dateStr = " "+require("locale").date(d)+" "; | |||
g.drawString(dateStr, g.getWidth()/2, Y+15, true /*очищаем фон*/); | |||
} | |||
// Очищаем экран один раз (при запуске): | |||
g.clear(); | |||
// Сперва сразу рисуем: | |||
draw(); | |||
var secondInterval = setInterval(draw, 1000); | |||
// Останавливаем обновление экрана после его выключения, | |||
// а затем возобновляем, когда он снова будет включен: | |||
Bangle.on('lcdPower',on=>{ | |||
if (secondInterval) clearInterval(secondInterval); | |||
secondInterval = undefined; | |||
if (on) { | |||
secondInterval = setInterval(draw, 1000); | |||
draw(); // сразу же рисуем | |||
} | |||
}); | |||
// Загружаем виджеты: | |||
Bangle.loadWidgets(); | |||
Bangle.drawWidgets(); | |||
// Показываем лаунчер после нажатия на среднюю кнопку: | |||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); | |||
</syntaxhighlight> | |||
== Создание приложения == | |||
Теперь, когда код готов, нам нужно превратить его в приложение для смарт-часов. Для этого нам нужно создать два основных файла: | |||
* Код приложения в JS-файле. | |||
* JSON-файл, описывающий приложение (название и т.д.) для лаунчера. | |||
Во-первых, придумайте уникальный ID для своего приложения. Не используйте пробелы, используйте строчные символы и старайтесь сделать его покороче (в разумных пределах – лучше всего в пределах 10 символов). | |||
В [https://github.com/espruino/BangleApps/tree/master/apps этот список] его лучше не помещать, чтобы оно не пересекалось с другими приложениями, которые у вас, возможно, уже установлены. | |||
=== Код приложения: «myclock.app.js» === | |||
Мы используем название myclock. Теперь кликните на стрелочку под кнопкой загрузки кода, выберите Storage, затем New File, впишите «myclock.app.js» и кликните на OK. | |||
Теперь кликните на кнопку загрузки кода. Приложение будет загружено на часы, а затем выполнено из заданного вами файла. Теперь вы можете спокойно продолжать разрабатывать своё приложение, как если бы оно было на часах. | |||
=== Информация о приложении: «myclock.app.info» === | |||
Итак, приложение у нас есть, но в лаунчере оно отображаться не будет, потому что у нас нет файла с информацией о приложении. Чтобы исправить этот недостаток, просто скопируйте и вставьте код ниже в левую часть IDE Espruino. | |||
Это запишет в файл «myclock.info» информацию о нашем приложении: | |||
<syntaxhighlight lang="javascript" enclose="div"> | |||
require("Storage").write("myclock.info",{ | |||
"name":"My Clock", | |||
"type":"clock", | |||
"src":"myclock.app.js" | |||
}); | |||
</syntaxhighlight> | |||
Теперь, если зажать на часах кнопку BTN3, чтобы перейти к циферблату, затем нажать BTN2, чтобы зайти в меню, и прокрутить вниз, можно увидеть пункт My Clock. Если выбрать его, это выполнит ваше приложение! | |||
Вы также можете перейти в настройки (Settings) и в Select Clock задать, чтобы этот циферблат стал циферблатом по умолчанию. | |||
Примечание: [https://banglejs.com/apps/ Загрузчик приложений Bangle.js] генерирует этот файл автоматически – мы сделали всё это здесь, чтобы вы научились создавать приложение без использования загрузчика. | |||
== Что дальше == | |||
Итак, циферблат готов! | |||
Как насчёт добавить его в [https://banglejs.com/apps/ загрузчик приложений Bangle.js]? О том, как это сделать, можно почитать в [https://www.espruino.com/Bangle.js+App+Loader этой статье]. | |||
=См.также= | =См.также= |
Версия от 21:56, 5 марта 2021
Циферблаты Bangle.js[1]
Это руководство подразумевает, что вы уже прошли руководство «Разработка под Bangle.js» и понимаете, с чего начать.
Если да, то вы уже должны быть подключены и умеете писать простой код. Поэтому давайте попробуем сделать простенький циферблат!
Для этого лучше использовать правую часть IDE – после загрузки кода мы, если захотим, сможем менять значения и вызывать функции при помощи REPL в левой части IDE.
Отрисовка линии
Скопируйте код ниже в правую часть IDE и кликните на кнопку загрузки кода:
function draw() {
// Задаём, как будем показывать текущее время:
var d = new Date();
var h = d.getHours(), m = d.getMinutes();
var time = h + ":" + ("0"+m).substr(-2);
// Сбрасываем состояние графической библиотеки:
g.reset();
// Очищаем область, где хотим нарисовать время:
g.clearRect(50,50,100,120);
// Рисуем текущее время:
g.drawString(time, 50, 50);
}
// Очищаем экран один раз (на запуске):
g.clear();
// Сначала сразу рисуем:
draw();
var secondInterval = setInterval(draw, 1000);
Теперь в середине экрана должен быть маленький текст со временем.
Немного странный код ("0"+m).substr(-2) добавляет нули к минутам (то есть в результате формат времени будет "12:01", а не "12:1").
Почему код отформатирован именно так? Читайте об этом в статье о стилях кода, в которой также есть несколько советов на эту тему.
Изменение шрифта
Во-первых, давайте сделаем текст побольше и нормально его отцентрируем. Большой ассортимент шрифтов можно найти на этой странице.
Мы воспользуемся кастомным 7-сегментным шрифтом под названием Font7x11Numeric7Seg при помощи строчки g.setFont("7x11Numeric7Seg").
// Загружаем шрифты:
require("Font7x11Numeric7Seg").add(Graphics);
// Позиция на экране:
const X = 160, Y = 140;
function draw() {
// Задаём, как будем показывать текущее время:
var d = new Date();
var h = d.getHours(), m = d.getMinutes();
var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2);
// Сбрасываем состояние графической библиотеки:
g.reset();
// Рисуем текущее время (7-сегментный шрифт, увеличенный в 4 раза)
g.setFont("7x11Numeric7Seg",4);
g.setFontAlign(1,1); // выравниванием справа снизу
g.drawString(time, X, Y, true /*очищаем фон*/);
// рисуем секунды (7-сегментный шрифт, увеличенный в 2 раза)
g.setFont("7x11Numeric7Seg",2);
g.drawString(("0"+d.getSeconds()).substr(-2), X+30, Y, true /*очищаем фон*/);
}
// Один раз очищаем экран (при запуске):
g.clear();
// Сначала сразу рисуем:
draw();
var secondInterval = setInterval(draw, 1000);
[Картинка]
Примечание: Чтобы избежать мерцания, в drawString() используется четвёртый аргумент, который очищает фон (по умолчанию рисуется только сам текст).
Наконец, добавляем дату. Мы можем воспользоваться для этого библиотекой locale – это значит, что дата будет адаптирована под любого пользователя, независимо от его языка.
Просто добавьте под функцией draw() вот этот код:
// Рисуем дату (обычным шрифтом):
g.setFont("6x8");
g.setFontAlign(0,1); // выравниваем по центру снизу
// Добавляем отступы к дате.
// Это очистит фон, если у даты изменится размер.
var dateStr = " "+require("locale").date(d)+" ";
g.drawString(dateStr, g.getWidth()/2, Y+15, true /*очищаем фон*/);
Дополнительные функции часов
Теперь у нас есть нечто, показывающее дату, но перед тем, как это станет циферблатом, нам нужно добавить ещё кое-что.
Виджеты
У большинства циферблатов есть виджеты. Чтобы их мог показывать и наш циферблат, нам нужно добавить в конец кода следующее:
Bangle.loadWidgets();
Bangle.drawWidgets();
Вы можете вызывать Bangle.drawWidgets() при каждом очищении экрана плюс виджетам нужно постоянно себя перерисовывать – но лучше делать это как можно реже, чтобы избежать мерцания.
В нашем примере мы очистим экран лишь один раз (при запуске), поэтому и функцию Bangle.drawWidgets() мы тоже вызовем только один раз.
Использование кнопки BTN2 для запуска лаунчера
В каждом циферблате должна быть возможность запустить лаунчер, и по умолчанию за это отвечает кнопка BTN2. Чтобы добавить эту возможность в свой циферблат, просто поместите код ниже в конец всего кода (не в функцию):
// Показываем лаунчер после нажатия на среднюю кнопку:
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
Энергосбережение
Прямо сейчас мы перерисовываем экран каждую секунду – независимо от того, включен он или нет. Очевидно, что для заряда батареи это плохие новости.
Чтобы оптимизировать этот момент, мы можем отслеживать то, когда экран выключается, и следом выключать интервал secondInterval, а затем снова включать его, когда экран снова включат (и сразу же перерисовывать циферблат):
// Останавливаем обновление экрана после его выключения,
// а затем возобновляем, когда он снова будет включен:
Bangle.on('lcdPower',on=>{
if (secondInterval) clearInterval(secondInterval);
secondInterval = undefined;
if (on) {
secondInterval = setInterval(draw, 1000);
draw(); // сразу же рисуем
}
});
Итог
В результате наш код должен выглядеть вот так:
// Загружаем шрифты:
require("Font7x11Numeric7Seg").add(Graphics);
// Позиция на экране:
const X = 160, Y = 140;
function draw() {
// Задаём, как будем показывать текущее время:
var d = new Date();
var h = d.getHours(), m = d.getMinutes();
var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2);
// Сбрасываем состояние графической библиотеки:
g.reset();
// Рисуем текущее время (7-сегментный шрифт, увеличенный в 4 раза):
g.setFont("7x11Numeric7Seg",4);
g.setFontAlign(1,1); // выравниваем справа внизу
g.drawString(time, X, Y, true /*очищаем фон*/);
// Рисуем секунды (7-сегментный шрифт, увеличенный в 2 раза):
g.setFont("7x11Numeric7Seg",2);
g.drawString(("0"+d.getSeconds()).substr(-2), X+30, Y, true /*очищаем фон*/);
// Рисуем дату обычным шрифтом:
g.setFont("6x8");
g.setFontAlign(0,1); // выравниваем по центру снизу:
// Добавляем отступы к дате.
// Это очистит фон, если у даты изменится размер.
var dateStr = " "+require("locale").date(d)+" ";
g.drawString(dateStr, g.getWidth()/2, Y+15, true /*очищаем фон*/);
}
// Очищаем экран один раз (при запуске):
g.clear();
// Сперва сразу рисуем:
draw();
var secondInterval = setInterval(draw, 1000);
// Останавливаем обновление экрана после его выключения,
// а затем возобновляем, когда он снова будет включен:
Bangle.on('lcdPower',on=>{
if (secondInterval) clearInterval(secondInterval);
secondInterval = undefined;
if (on) {
secondInterval = setInterval(draw, 1000);
draw(); // сразу же рисуем
}
});
// Загружаем виджеты:
Bangle.loadWidgets();
Bangle.drawWidgets();
// Показываем лаунчер после нажатия на среднюю кнопку:
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
Создание приложения
Теперь, когда код готов, нам нужно превратить его в приложение для смарт-часов. Для этого нам нужно создать два основных файла:
- Код приложения в JS-файле.
- JSON-файл, описывающий приложение (название и т.д.) для лаунчера.
Во-первых, придумайте уникальный ID для своего приложения. Не используйте пробелы, используйте строчные символы и старайтесь сделать его покороче (в разумных пределах – лучше всего в пределах 10 символов).
В этот список его лучше не помещать, чтобы оно не пересекалось с другими приложениями, которые у вас, возможно, уже установлены.
Код приложения: «myclock.app.js»
Мы используем название myclock. Теперь кликните на стрелочку под кнопкой загрузки кода, выберите Storage, затем New File, впишите «myclock.app.js» и кликните на OK.
Теперь кликните на кнопку загрузки кода. Приложение будет загружено на часы, а затем выполнено из заданного вами файла. Теперь вы можете спокойно продолжать разрабатывать своё приложение, как если бы оно было на часах.
Информация о приложении: «myclock.app.info»
Итак, приложение у нас есть, но в лаунчере оно отображаться не будет, потому что у нас нет файла с информацией о приложении. Чтобы исправить этот недостаток, просто скопируйте и вставьте код ниже в левую часть IDE Espruino.
Это запишет в файл «myclock.info» информацию о нашем приложении:
require("Storage").write("myclock.info",{
"name":"My Clock",
"type":"clock",
"src":"myclock.app.js"
});
Теперь, если зажать на часах кнопку BTN3, чтобы перейти к циферблату, затем нажать BTN2, чтобы зайти в меню, и прокрутить вниз, можно увидеть пункт My Clock. Если выбрать его, это выполнит ваше приложение!
Вы также можете перейти в настройки (Settings) и в Select Clock задать, чтобы этот циферблат стал циферблатом по умолчанию.
Примечание: Загрузчик приложений Bangle.js генерирует этот файл автоматически – мы сделали всё это здесь, чтобы вы научились создавать приложение без использования загрузчика.
Что дальше
Итак, циферблат готов!
Как насчёт добавить его в загрузчик приложений Bangle.js? О том, как это сделать, можно почитать в этой статье.
См.также
Внешние ссылки