LeCodesdocs

Элементы контента UI

Листовые элементы, которые что-то отображают: UIText, UIImage, UIVideo. У каждого одно изменяемое свойство контента (.text, .src, .player), живущее на элементе — контент никогда не стиль. Для редактируемого текста см. UIInput в interactive.md.

Обзор

TypeScript
import photo from './photo.jpg'

const caption = UIText("Loading…").style({ color: "white", fontSize: 16 })

const screen = UIScreen([
  UIImage(photo).style({ width: "100%", height: 220, borderRadius: 16, objectFit: "cover" }),
  caption,
]).style({ bgColor: "black", p: 16, pt: "safe-top", gap: 12 })

screen.open()
caption.text = "Sunset over the harbor"     // перерисовывается сразу

UIText

TypeScript
UIText(text: string): UIText

text.text = "Updated"       // get/set отображаемой строки

Специфичные для текста стили (поверх общих стилей элемента):

TypeScript
textAlign:      "start" | "center" | "end" | "left" | "right"   // по умолчанию left
fontFamily:     string            // системные: "serif", "sans-serif", "monospaced"; кастомные через registerFont
fontSize:       UIValue           // по умолчанию 14
lineHeight:     UIValue | "normal"
fontWeight:     number | "normal" | "bold"     // 400, 700, …
fontStyle:      "normal" | "italic"
color:          Color
textDecoration: "underline" | "line-through" | "none"
letterSpacing:  UIValue
Note

lineHeight: 1.5 значит 1.5 px — голое число это px везде. Множитель это "1.5em" (разрешается относительно собственного fontSize этого элемента; наследования нет).

Note

фон экрана по умолчанию чёрный — всегда задавай color явно.

.style() у UIText не принимает свойств рамки/фонового-изображения — bgColor, отступы и поля работают, но декорированный текстовый чип — это UIRow/UIColumn вокруг UIText. Кастомные шрифты нужно зарегистрировать до открытия экрана — см. fonts.md.

UIImage

TypeScript
UIImage(src: ImageSource): UIImage

// ImageSource:
//   string          — удалённый URL, или asset() / импортированный файл проекта
//   FetchResponse   — скачанное тело, используемое напрямую как пиксели
//   File            — из openFilePicker()
//   SvgSource       — обёрнутый сырой SVG XML
//   Canvas          — 2D Canvas, запекается в текстуру при присвоении

img.src            // получить (разрешённый) источник / задать новый — обновляет отображаемое изображение

Специфичные для изображения стили:

TypeScript
objectFit:    "cover" | "contain" | "fill"   // как источник ложится в бокс
tintColor:    Color                          // только SVG-источники
borderRadius: number                         // px (только число на UIImage)
Note

tintColor применяется только к SVG-источникам и заменяет все цвета fill и stroke в SVG — это для монохромных иконок, не для многоцветной графики.

Note

голая строка относительного пути (UIImage("./photo.png")) не разрешается в собранный ассет — обычные строки работают только для https://… URL. Импортируй файл или используй asset('./photo.png').

Обрезка атласа: setSourceRect

TypeScript
img.setSourceRect(x: number, y: number, w: number, h: number): this   // пиксели текстуры

Рендерит только под-прямоугольник источника — примитив спрайт-листа. w/h прямоугольника становятся собственным размером элемента (один кадр, не весь атлас), и обрезанный кадр всегда заполняет бокс, переопределяя objectFit. Чейнится и безопасно вызывается до появления элемента на экране (начальная обрезка применяется при монтировании). Анимация в стиле спрайта — это смена прямоугольника на кадр:

TypeScript
const icon = UIImage(atlasUrl).style({ width: 64, height: 64 }).setSourceRect(0, 0, 128, 128)
let frame = 0
setInterval(() => { icon.setSourceRect((++frame % 8) * 128, 0, 128, 128) }, 100)

Ловушка: bgImage — не контент изображения

TypeScript
const img = UIImage("")            // ✗ пустой источник как заглушка
img.style.bgImage = url            // ✗ bgImage это декор контейнера, не контент
const img = UIImage(url)           // ✓ источник идёт в конструктор…
img.src = newUrl                   // ✓ …и меняется через .src

UIVideo

TypeScript
UIVideo(player: VideoPlayer): UIVideo

video.player       // только чтение — VideoPlayer, переданный при конструировании

Элемент — это лишь экранная поверхность; воспроизведение живёт целиком на VideoPlayer — создай его первым, управляй напрямую:

TypeScript
const player = new VideoPlayer(asset('./intro.mp4'))
const video = UIVideo(player).style({ width: "100%", height: 220, borderRadius: 12, objectFit: "cover" })
player.play()

Специфичный для видео стиль:

TypeScript
objectFit: "cover" | "contain" | "fill"

UIVideo также принимает рисуемые стили (border*, bgColor, …) для обрамления. Плеер — нативный ресурс — вызови dispose(), когда видео ушло навсегда, и останови воспроизведение в onClose экрана (см. Соглашения — Жизненный цикл).

Смотрите также