Ask the assistant
0/400
Your question is processed by an AI service and kept to improve answers. Do not enter personal data.

    * Render-примитивы (оптимизированный слой)

    This page has not been translated into English yet. The Russian original is below.

    Семейство элементов с именем на * — это высокооптимизированные render-компоненты : в отличие от обычных элементов (каждый = отдельный Flutter-виджет/RenderObject), все * -элементы одной цепочки схлопываются в ОДИН Flutter RenderObject ( ReeelSingleChildRenderBox ) и рисуются напрямую в его paint через Canvas . Это даёт минимум оверхеда — идеально для дашбордов и графиков , где важна скорость перерисовки.

    Когда использовать: карточки/тайлы дашбордов, фоны с градиентом, векторная графика и графики. Для обычной раскладки экранов используйте виджет-элементы ( Column / Row / Grid /…).

    Как рисовать графику. Общий способ нарисовать что угодно — низкоуровневые примитивы рисования ( *Line / *Rect / *Circle / *Arc / *Polygon / *Points / *Path ) в компоновщике *Stack , с эффектами ( *Clip / *Transform / *Opacity ) и итератором *Repeat . Готовые чарты ( $Bars / $Sparkline / $Donut / $Ring ) — это макросы над этими примитивами (см. «Примитивы рисования» и «Чарты как макросы» ).

    Модель: линейная цепочка * -элементов схлопывается в один ReeelSingleChildRenderBox ; как только дерево ветвится ( *Stack / *Repeat ) или оборачивает поддерево эффектом ( *Clip / *Transform / *Opacity ), оно рендерится в ReeelMultiChildRenderBox (рекурсивный обход, тот же один render-pass). Каждый слой либо задаёт отступ/размер ( layout ), либо рисует ( paint ) в общий бокс. Размер берётся из самого «внутреннего» элемента с размером ( *Text , примитивы) — остальные ( *Colored , *Gradient , *Padding ) оборачивают его. Примитивы адаптивны : рисуют в выданный размер; можно закрепить width / height .

    Базовые компоненты

    Элемент Тип Описание
    *Colored single-child Заливка сплошным цветом (+ скругление radius ).
    *Gradient single-child Двухстоповый линейный градиент ( from / to / angle / radius ).
    *Padding single-child Отступы вокруг вложенного содержимого.
    *Text leaf Текст напрямую через TextPainter .
    *Captions leaf Субтитры из записей по часам фильма: окна по нормам, появление и уход в полях, прокрутка, заливка по словам; стиль — #style (TextStyle), блок :# speaker:"A" на спикера. Только внутри *Scene .
    *Sprite leaf Картинка проекта в координатах сцены ( x / y / w / h , как у *Rect ): неподвижная, лист спрайтов ( grid:[столбцы, ряды] + fps ) или список кадров frames: ; кадр — по часам слоя, flipX / flipY , filterQuality:none для пиксель-арта.
    *Stack multi-child Компоновщик: накладывает детей в один бокс (снизу вверх).
    *State single-child Скоуп реактивных @ -переменных для вложенных * -элементов.

    *Gradient

    *Gradient from:0xFF6D5EF6 to:0xFF9B8AFB angle:120 radius:16
      *Padding all:20
        *Text "Balance" color:0xFFFFFFFF
    Параметр Тип Default Описание
    from color прозрачный Начальный цвет.
    to color прозрачный Конечный цвет.
    angle double 0 Угол в градусах: 0 = слева→направо, 90 = сверху→вниз.
    radius double 0 Скругление углов.

    Чарты ( $Bars / $Sparkline / $Donut / $Ring ) — это макросы над примитивами рисования и *Repeat , см. разделы ниже.

    Примитивы рисования

    Низкоуровневые * -примитивы рисуют геометрию прямо в Canvas . Из них (плюс *Repeat ) собирается любой график — чарты $Bars / $Donut /… — это макросы над той же механикой.

    Координатное пространство. По умолчанию координаты — доли 0..1 от бокса (независимо от размера): cx:0.5 cy:0.5 — центр, r:0.42 — 42% меньшей стороны. Переключается:

    • units:px — абсолютные пиксели;
    • viewBox:[w,h] — виртуальная SVG-сетка w×h , растягиваемая на бокс.

    Радиус ( r у *Circle / *Arc ) — доля меньшей стороны; w / h масштабируются по ширине/высоте.

    Общие атрибуты заливки

    Принимают все примитивы ( *Line / *Rect / *Circle / *Arc / *Polygon / *Points / *Path ):

    Атрибут Описание
    fill Цвет заливки.
    color Дружелюбный алиас: у заливаемых фигур ( *Rect / *Circle / *Polygon / *Arc -сектор) — заливка; у линейных ( *Line / *Points / *Path / *Arc -кольцо) — обводка.
    stroke Цвет обводки (всегда).
    strokeWidth Толщина обводки; >0 добавляет проход обводки.
    cap butt | round | square .
    join miter | round | bevel .
    gradientFrom / gradientTo / gradientAngle Линейный градиент заливки (угол в градусах).
    draw Доля обводки, которая нарисована ( 0..1 от начала контура; по умолчанию 1 — вся). Заливки не касается.
    blur Мягкий край / свечение ( MaskFilter.blur ).
    blendMode Любое имя Dart BlendMode .
    units / viewBox Координатное пространство (см. выше).
    width / height Закрепить размер бокса примитива (иначе — заполняет бокс).

    Фигура рисует заливку , если задан fill /градиент, и обводку , если strokeWidth>0 (или задан stroke ). Могут применяться оба прохода сразу.

    *Line / *Rect / *Circle / *Arc / *Polygon / *Points / *Path

    *Line x1:0.1 y1:0.85 x2:0.9 y2:0.2 color:0xFFF9C74F strokeWidth:4 cap:round
    *Rect x:0.15 y:0.15 w:0.7 h:0.7 radius:10 fill:0xFF6C5CE7
    *Circle cx:0.5 cy:0.5 r:0.38 fill:0x2200B894 color:0xFF00B894 strokeWidth:3
    *Arc cx:0.5 cy:0.5 r:0.4 startAngle:-90 value:0.68 strokeWidth:10 cap:round color:0xFF6C5CE7
    *Polygon points:[[0.5,0.12],[0.9,0.88],[0.1,0.88]] fill:0xFFE17055
    *Points values:[30,42,38,55,48,63,58,70,60] mode:line color:0xFF22C55E strokeWidth:2 cap:round join:round
    *Path d:"M0.05,0.9 L0.3,0.4 L0.5,0.65 L0.72,0.2 L0.95,0.5" color:0xFF9B8AFB strokeWidth:3
    Примитив Ключевые параметры
    *Line x1 / y1 (0,0) → x2 / y2 (1,1). Только обводка.
    *Rect x / y (0,0), w / h (1,1), radius (0). Заливка и/или обводка.
    *Circle cx / cy (0.5), r (0.5 — доля меньшей стороны).
    *Arc cx / cy , r , startAngle (-90 = 12 часов), value (0..1 — сектор value·360° ) или sweep (градусы), useCenter . strokeWidth>0 — кольцо, иначе залитый сектор.
    *Polygon points:[[x,y],…] , closed (true).
    *Points values:[…] (x равномерно, y нормируется по min..max) или points:[[x,y],…] ; mode = line | area | scatter ; dotRadius .
    *Path d — SVG-путь M/L/H/V/C/Q/A/Z (заглавные — абсолютные доли, строчные — относительные); fillRule = nonZero | evenOdd .

    Линия, которая рисует себя сама ( draw )

    draw: — доля обводки , а не коробки: она меряется по длине контура, поэтому на изломанной линии половина приходится на середину пути, а не на середину ширины. Заливка при этом остаётся целой — ровно как stroke-dashoffset в CSS не трогает fill .

    InView once:true seen:@seen
      Animated of:{seen ? 1 : 0} duration:900 curve:easeOut value:@t
        *Path d:"M0.02,0.7 C0.25,0.95 0.75,0.15 0.98,0.45" color:0xFF6C5CE7 strokeWidth:3 draw:{t}

    Две вещи, которые стоит знать:

    • На сайте долю отмеряет браузер после раскладки (длина обводки у растянутой системы координат известна только по коробке). Со снятым JS страница рисует обводку целиком — тот же безопасный откат, что и у установки, не знающей слова.
    • У замкнутой фигуры обводка начинается там же, где начинается её контур: у круга это три часа, по часовой стрелке. Сдвигается *Transform rotate: .

    *Stack / эффекты

    Компоновщики оборачивают одно * -поддерево операцией Canvas :

    *Stack                         // рисует детей снизу вверх в одном боксе (z-слои)
      *Colored color:0xFF12101F radius:12
      *Circle cx:0.5 cy:0.5 r:0.4 fill:0xFF6C5CE7
    
    *Clip shape:circle             // rect | rrect (radius:) | circle | path (d:)
      *Gradient from:0xFF6D5EF6 to:0xFFF9C74F angle:120
    
    *Transform rotate:20 origin:[0.5,0.5]   // rotate / scale / translate вокруг origin
      *Rect x:0.2 y:0.3 w:0.6 h:0.4 radius:6 fill:0xFF4B9BFF
    
    *Opacity value:0.4             // групповая прозрачность (0 — не рисует, 1 — без слоя)
      *Circle cx:0.5 cy:0.5 r:0.42 fill:0xFFE84393

    *Transform прозрачен для раскладки (ребёнок сохраняет бокс) — оборачивай в *Clip , чтобы обрезать выступающее.

    *Repeat

    Штампует одного ребёнка-шаблон N раз, подставляя в скоуп каждой копии {...} -биндинги текущей итерации. Управляется values:[…] (числа или составные map'ы) либо count:N .

    Биндинг Значение
    index Индекс итерации (с 0).
    item values[index] (или index , если задан только count ).
    count Число итераций.
    first / last Булевы флаги.
    prev / next Соседние значения.
    min / max / sum / mean Агрегаты по числовым значениям.
    norm item , нормированный в 0..1 по min..max .
    frac item / sum .
    accBefore / accAfter Префиксные суммы (для стекинга и дуг).
    accFrac accBefore / sum — префиксная доля 0..1 (стартовый угол доната: {accFrac*360 - 90} ).
    // бар-чарт: по одному *Rect на значение
    *Repeat values:[12, 28, 20, 44, 32, 38, 26]
      *Rect x:{index/count + 0.08/count} w:{0.84/count} y:{1 - item/max} h:{item/max} radius:3 fill:0xFF6D5EF6
    Грабли. Ведущий унарный минус в {...} роняет парсер — пиши {x - 90} , а не {-90 + x} .
    Приоритет. В {...} цепочка a/b*c считается как a/(b*c) — для (a/b)*c подставляется готовый accFrac , либо ставь скобки: {(a/b)*c} . Для высоты столбца используй {item/max} , а не {norm} ( norm отправляет минимальное значение в 0, и его столбец исчезает).

    Чарты как макросы

    Поскольку весь чарт — это один *Repeat + один примитив с {...} -математикой, он аккуратно сворачивается в макрос . Библиотека assets/editor/reeel/charts.reeel поставляет четыре готовых ( import charts ):

    import charts
    
    $Ring value:0.72 color:0xFF6C5CE7 strokeWidth:12
    $Bars values:[12, 28, 20, 44, 32, 38, 26] color:0xFF6D5EF6
    $Donut values:[35, 25, 22, 18] strokeWidth:22
    $Sparkline values:[30, 42, 38, 55, 48, 63, 58, 70, 60] color:0xFF22C55E fill:0x2222C55E

    Рецепты (тело макросов):

    Макрос Собран из
    $Ring $value *Stack из двух *Arc — полный трек ( value:1 ) + дуга прогресса ( value:$value , скруглённый конец).
    $Bars $values *Repeat по *Rect , высота {item/max} , ширина {0.84/count} .
    $Donut $values *Repeat по *Arc : startAngle:{accFrac*360 - 90} , sweep:{frac*360 - 4} , цвета {pick(index, …)} .
    $Sparkline $values *Stack из двух *Points — заливка ( mode:area ) + линия ( mode:line ).

    Передай реактивный список — и чарт станет живым: $Bars {revenue} color:0xFF9B8AFB , где @revenue объявлена в *State или приходит от генератора данных.

    Паттерн: карточка дашборда

    *Gradient (фон) может обёртывать Flutter-содержимое ( Padding / Column / Text ) как свой child; график кладём * -блоком (макрос $Bars из charts или примитивы напрямую).

    import charts
    
    *Gradient from:0xFF1E1B34 to:0xFF2A2550 angle:120 radius:20
      Padding all:20
        Column crossAxisAlignment:start spacing:12
          Text "Доход за неделю"
            #style color:0xFFEDEBFF fontSize:16 fontWeight:w600
          SizedBox height:96
            $Bars values:[12, 28, 20, 44, 32, 38, 26] color:0xFF9B8AFB

    Реактивные значения работают внутри * -детей: объявите переменную в *State (или получите её от генератора — JsonData / HttpData ) и привяжите выражением {...} к параметру примитива — списком ( values:{revenue} ) или скаляром ( value:{progress} , height:{t*120} ). При изменении переменной * -слой перерисовывается.

    *State @revenue:[12, 28, 20, 44, 32, 38, 26]
      *Repeat values:{revenue}
        *Rect x:{index/count} w:{0.8/count} y:{1 - item/max} h:{item/max} radius:4 fill:0xFF9B8AFB

    Анимация: *Animated / Animated

    Драйвер анимации, управляемый внешней переменной . Гонит выходную @ -переменную из from в to (по умолчанию 0→1), а дети читают её выражением {...} . Два имени — один движок; поведение зависит от ребёнка:

    • *Animated — когда ребёнок — это * -render-поддерево: значение идёт через render-конвейер, элементы перерисовываются (repaint), виджеты НЕ пересобираются.
    • Animated — когда анимируешь Flutter-виджеты (они пересобираются).
    @mode:"fromStartToEnd"
    *Animated value:@t controller:$mode duration:900 curve:easeOutCubic
      *Arc value:{t} r:0.45 color:0xFF6C5CE7 strokeWidth:12 cap:round width:120 height:120
    Параметр Тип Default Описание
    value @var — Выходная переменная; сюда пишется текущее eased-значение ( {value} у детей).
    controller $var (dynamic) — Управление: число = значение, к которому анимировать; строка = команда.
    from / to double 0 / 1 Диапазон выхода.
    duration int (мс) 600 Длительность.
    curve string easeOut linear/easeIn/Out/InOut/easeOutCubic/easeOutBack/elasticOut/bounceOut/decelerate.

    Команды controller (строкой): forward (к to ), reverse (к from ), stop , reset (в начало), fromStartToEnd , fromEndToStart . Число — animateTo к этому значению в диапазоне from..to . Меняй значение переменной-контроллера (кнопкой, логикой) — анимация реагирует.

    Дальнейшее развитие слоя (стек/z, удобная раскладка *Row / *Column / *Grid , обработка нажатий, *Arc / *Candles ) ведётся инкрементально — примеры каждого нового примитива проверяются reeel_validate и доступны агенту через reeel_schema .
    DOCS
    dark_mode_baseline
    RU/EN
    menu_baseline