Выводим текст с обводкой, контурный текст и текст с теньюИногда бывает полезно отобразить текстовую информацию с обводкой, тенью или в виде контурного текста, например, время на АОД.
Стандартные средства это не позволяют сделать.
Как вариант, можно сделать
копию текстового виджета, разместить его
ниже основного со смещением вниз и в сторону на пару пикселей. И задать ему другой цвет. Получим
"текст с тенью".
Если сделать несколько таких копий и сместить их в разные стороны, то получится
"текст с обводкой".
Ну а если фон однотонный, основной цвет текста совпадает с цветом фона, то получится
"контурный текст".
Для удобства создания такого текста и изменения его свойств, написала два класса.
Класс текст с обводкой
class TextWithOutline {
constructor(props) {
this._x = props.x || 0;
this._y = props.y || 0;
this._widget = [];
this._color = (props.color == null) ? 0xffffff : props.color;
this._color_outline = (props.color_outline == null) ? 0x000000 : props.color_outline;
this._offset = props.offset || 2;
this._group = props.group || hmUI;
for (let i = 0; i < 5; i++) {
this._widget[i] = this._group.createWidget(hmUI.widget.TEXT, {
x: this._x,
y: this._y,
w: props.w || 100,
h: props.h || 40,
text_size: props.text_size || 30,
char_space: props.char_space || 0,
line_space: props.line_space || 0,
text: props.text,
color: i > 3 ? this._color : this._color_outline,
align_h: props.align_h || hmUI.align.CENTER_H,
align_v: props.align_v || hmUI.align.CENTER_V,
text_style: props.text_style || hmUI.text_style.NONE,
});
if (props.font){
this._widget[i].setProperty(hmUI.prop.MORE, {
font: props.font
});
}
}
this._widget[0].setProperty(hmUI.prop.MORE, {
x: this._x - this._offset,
y: this._y + this._offset
});
this._widget[1].setProperty(hmUI.prop.MORE, {
x: this._x + this._offset,
y: this._y - this._offset
});
this._widget[2].setProperty(hmUI.prop.MORE, {
x: this._x - this._offset,
y: this._y - this._offset
});
this._widget[3].setProperty(hmUI.prop.MORE, {
x: this._x + this._offset,
y: this._y + this._offset
});
}
hide() {
this._widget.forEach(item => {
item.setProperty(hmUI.prop.VISIBLE, false);
});
}
show() {
this._widget.forEach(item => {
item.setProperty(hmUI.prop.VISIBLE, true);
});
}
set visible(v) {
if (v) this.show()
else this.hide();
}
set x(v) {
this._x = v;
this._widget[4].setProperty(hmUI.prop.MORE, {x: this._x});
this._widget[0].setProperty(hmUI.prop.MORE, {x: this._x - this._offset});
this._widget[1].setProperty(hmUI.prop.MORE, {x: this._x + this._offset});
this._widget[2].setProperty(hmUI.prop.MORE, {x: this._x - this._offset});
this._widget[3].setProperty(hmUI.prop.MORE, {x: this._x + this._offset});
}
set y(v) {
this._y = v;
this._widget[4].setProperty(hmUI.prop.MORE, {y: this._y});
this._widget[0].setProperty(hmUI.prop.MORE, {y: this._y + this._offset});
this._widget[1].setProperty(hmUI.prop.MORE, {y: this._y - this._offset});
this._widget[2].setProperty(hmUI.prop.MORE, {y: this._y - this._offset});
this._widget[3].setProperty(hmUI.prop.MORE, {y: this._y + this._offset});
}
set text(txt) {
this._widget.forEach(item => {
item.setProperty(hmUI.prop.TEXT, txt);
});
}
set color(v) {
this._color = v;
this._widget[4].setProperty(hmUI.prop.MORE, {color: this._color});
}
set color_outline(v) {
this._color_outline = v;
for (let i = 0; i < 4; i++) {
this._widget[i].setProperty(hmUI.prop.MORE, {color: this._color_outline});
}
}
}
Класс текст с тенью
class TextWithShadow {
constructor(props) {
this._x = props.x || 0;
this._y = props.y || 0;
this._offset = props.offset || 2;
this._group = props.group || hmUI;
this._shadow = this._group.createWidget(hmUI.widget.TEXT, {
x: this._x + this._offset,
y: this._y + this._offset,
w: props.w || 100,
h: props.h || 40,
text_size: props.text_size || 30,
char_space: props.char_space || 0,
line_space: props.line_space || 0,
text: props.text,
color: (props.color_shadow == null) ? 0x000000 : props.color_shadow,
align_h: props.align_h || hmUI.align.CENTER_H,
align_v: props.align_v || hmUI.align.CENTER_V,
text_style: props.text_style || hmUI.text_style.NONE,
});
this._widget = this._group.createWidget(hmUI.widget.TEXT, {
x: this._x,
y: this._y,
w: props.w || 100,
h: props.h || 40,
text_size: props.text_size || 30,
char_space: props.char_space || 0,
line_space: props.line_space || 0,
text: props.text,
color: (props.color == null) ? 0xffffff : props.color,
align_h: props.align_h || hmUI.align.CENTER_H,
align_v: props.align_v || hmUI.align.CENTER_V,
text_style: props.text_style || hmUI.text_style.NONE,
});
if (props.font){
this._widget.setProperty(hmUI.prop.MORE, {
font: props.font
});
this._shadow.setProperty(hmUI.prop.MORE, {
font: props.font
});
}
}
hide() {
this._widget.setProperty(hmUI.prop.VISIBLE, false);
this._shadow.setProperty(hmUI.prop.VISIBLE, false);
}
show() {
this._widget.setProperty(hmUI.prop.VISIBLE, true);
this._shadow.setProperty(hmUI.prop.VISIBLE, true);
}
set visible(v) {
if (v) this.show()
else this.hide();
}
set x(v) {
this._x = v;
this._widget.setProperty(hmUI.prop.MORE, {x: this._x});
this._shadow.setProperty(hmUI.prop.MORE, {x: this._x + this._offset});
}
set y(v) {
this._y = v;
this._widget.setProperty(hmUI.prop.MORE, {y: this._y});
this._shadow.setProperty(hmUI.prop.MORE, {y: this._y + this._offset});
}
set text(txt) {
this._widget.setProperty(hmUI.prop.TEXT, txt);
this._shadow.setProperty(hmUI.prop.TEXT, txt);
}
set color(v) {
this._widget.setProperty(hmUI.prop.MORE, {color: v});
}
set color_shadow(v) {
this._shadow.setProperty(hmUI.prop.MORE, {color: v});
}
}
Свойства повторяют свойства обычного виджета
widget.TEXT, плюс добавлены свойства:
offset - смещение обводки/тени
color_shadow - цвет тени
color_outline - цвет обводки
group - если нужно добавить объект в группу
Если при создании объекта свойства не указаны, берутся
значения по умолчанию:
- основной цвет - белый,
- цвет тени и обводки - черный,
- смещение - 2 пикс.,
- группы нет.
Примечание. При малых значениях размера текста
text_size текст с обводкой может выглядеть не очень читаемым.
Использование
Создаем текст с обводкой
let outlinedText = new TextWithOutline({
x: 60,
y: 60,
w: 380,
h: 105,
text_size: 60,
char_space: 0,
line_space: 0,
color: 0xffffff,
offset: 1,
text: 'С обводкой',
align_h: hmUI.align.LEFT,
align_v: hmUI.align.CENTER_V,
text_style: hmUI.text_style.NONE,
});
Меняем текст, цвет в созданном объекте:
outlinedText.text = 'Новый текст';
outlinedText.color = 0xff0000;
Таким образом, если у вас в циферблате уже есть текст, и его нужно изменить на текст с обводкой (или тенью), то нужно сделать всего 3 шага:
1. Добавить в начале кода циферблата код нужного класса.
2. Заменить заголовок текстового виджета (все остальные свойства остаются теми же)
someText = hmUI.createWidget(hmUI.widget.TEXT, {
на
someText = new TextWithOutline({
Если необходимы значения параметров, отличные от значений по умолчанию, надо добавить и их.
3. Если текст в циферблате динамически меняется, то заменить функции изменения текста
someText.setProperty(hmUI.prop.TEXT, 'Новый текст');
на
someText.text = 'Новый текст';
Также
для изменения доступны свойства:
someText.
x - координата X
someText.
y - координата Y
someText.
color - основной цвет
someText.
color_outline - цвет обводки
someText.
color_shadow - цвет тени
someText.
visible - установить видимость (true или false)
При необходимости можно этот список расширить и добавить другие свойства.
В архиве тестовый пример. При нажатии на текст для наглядности случайно меняются цвета и содержимое.
Скачать: text_utils.zip ( 37.33 КБ )