До списку уроків
8A · Урок 16 з 16

VR-прототип і фінальне портфоліо модуля

виконано0%
Крок 1

Що робимо сьогодні

Тема 8, урок 2 з 2 · останній урок модуля · 120 хвилин

Минулого уроку ти зібрав сцену з трьох фігур. Вона гарна, але мертва: ніщо в ній не рухається й не відповідає на твої дії.

Сьогодні фігур стане п'ять. Одна крутитиметься сама. Друга рахуватиме твої кліки написом просто в сцені.

Друга робота дня — портфоліо. Це одна сторінка, з якої відкриваються всі вісім робіт модуля.

Сцену ти покажеш на захисті сьогодні. А портфоліо лишиться після курсу: це адреса, яку можна дати будь-кому.

Чого навчишся за цей урок

Хід уроку

ЕтапХвЩо робимо
Перевірка ДЗ10GDD: як гравець виграє
П'ять об'єктів і анімація20Атрибут animation, три види руху
Інтерактив і лічильник30Курсор, клік, <a-text>
Перерва10
Портфоліо модуля15~/www/index.html і вісім посилань
check 0810Фінальний прогін до зеленого
Захист прототипів202 хвилини на людину + питання по коду
Підсумок модуля5Вісім тем однією картою
Разом120
Тека зветься за темою, а не за уроком Урок сьогодні шістнадцятий, а тека практики — lesson-08. Бо це восьма тема модуля. Теки lesson-16 немає й не буде.
Крок 2

Бібліотека лежить у тебе, а не в інтернеті

Перший рядок сцени вирішує, чи вона взагалі відкриється

Ти пишеш <a-box> — і в браузері з'являється куб. Робить це A-Frame, бібліотека для опису 3D-сцени звичайними HTML-тегами.

Далі вона все бере на себе. Будує сцену. Керує камерою. Малює кадри. Вмикає VR-режим на телефоні.

Підключається вона одним рядком у <head>. У цьому рядку стоїть адреса файлу.

Якщо адреса веде на чужий сервер, check 08 це побачить і критерій не зарахує.

так — бібліотека з твоєї теки
<script src="assets/aframe.min.js"></script>
так не можна — зовнішній домен
<script src="https://aframe.io/releases/1.7.0/aframe.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/aframe@1.7.0/dist/aframe.min.js"></script>

Чому чекер забороняє CDN

Бібліотеку можна не класти в себе, а тягнути з чужого сервера. Такі роздавальні сервери звуться CDN.

Вони швидкі й безкоштовні. Тому в інтернеті майже всі приклади A-Frame написані саме так. Але в нас так не можна, і причин три.

ПричинаЩо це означає на практиці
Сайт має працювати завжди CDN може бути недоступний: збій, блокування, шкільний фільтр, урок без інтернету. Твоя сцена тоді — біла сторінка. Локальний файл лежить на тому самому сервері, що й сторінка: якщо відкрилася сторінка — відкриється й бібліотека
Версія не змінюється сама Файл у твоїй теці — той самий і за пів року. Посилання на CDN у форматі @latest одного дня приведе іншу версію, і сцена зламається без жодної правки з твого боку
Чужий сервер бачить твоїх гостей Кожен, хто відкриє сторінку, непомітно постукає ще й на CDN. Той запише його IP-адресу й адресу твоєї сторінки. Тому в цьому курсі локально лежать навіть шрифти

Саме через ці три причини правило записали в критерій. check 08 шукає в HTML посилання на зовнішні домени. Знайшов — критерій не пройдено, хоча вдома все працювало.

Файл уже лежить у тебе Файл aframe.min.js учитель розклав у кабінети ще до уроку 15. По FTP ти його не завантажуєш. Він важить близько 1,8 МБ — майже впритул до ліміту приймальні у 2 МБ. Заливати 25 однакових копій немає сенсу. Твоя справа — правильний відносний шлях до нього.
Відносний шлях рахується від сторінки Сторінка лежить у ~/www/lesson-08/index.html. Бібліотека — у ~/www/lesson-08/assets/aframe.min.js. Тому в src пиши assets/aframe.min.js, без слеша на початку. Слеш на початку відлічує від кореня сайту, а там цього файлу немає.
Питання

Удома сцена крутиться, у школі — біла сторінка, у консолі порожньо, крім червоного рядка про aframe.min.js. У <head> стоїть src="https://aframe.io/releases/1.7.0/aframe.min.js". Що сталося?

Ще одна пастка з тим самим коренем: шрифт

Напис у сцені малює тег <a-text>. Системний шрифт він не бере — йому потрібен окремий файл із намальованими літерами.

За замовчуванням A-Frame тягне цей файл з cdn.aframe.io. Тобто із чужого домену — навіть коли сама бібліотека лежить локально. Тому шрифт теж має бути у твоїй теці:

лічильник із локальним шрифтом
<a-text value="Очки: 0" font="assets/Roboto-msdf.json"></a-text>

Поруч із aframe.min.js учитель кладе два файли шрифту: Roboto-msdf.json і Roboto-msdf.png.

В атрибуті ти вказуєш перший. Другий підтягнеться сам — його ім'я записане всередині JSON.

Якщо цих файлів у теці немає — скажи вчителеві. Ставити посилання на CDN не треба.

Питання

Сцена малюється, куби на місці, але напису з лічильником не видно взагалі, а в консолі — червоний рядок про Roboto-msdf.json. Де шукати причину?

Крок 3

Розмітка сцени, рядок за рядком

Мінімальна сцена — це вісім рядків, і кожен з них щось означає

мінімальна робоча сцена
<a-scene> <a-sky color="#0F1B2A"></a-sky> <a-plane position="0 0 -4" rotation="-90 0 0" scale="8 8 8" color="#3D5A6C"></a-plane> <a-box position="-1 0.5 -3" color="#E76F51"></a-box> <a-sphere position="1 1.2 -4" radius="0.6" color="#F4A261"></a-sphere> <a-camera> <a-cursor></a-cursor> </a-camera> </a-scene>
РядокЩо він робить
<a-scene> корінь сцени. Створює полотно на весь екран, запускає рендер, додає кнопку «VR» у кутку й два світла за замовчуванням
<a-sky> небо — величезна сфера навколо всього. Без неї фон чорний
<a-plane> плоский прямокутник 1×1 м. Стоїть вертикально, як стіна; підлогою стає після повороту на −90° по X
<a-box> куб 1×1×1 м
<a-sphere radius> куля. Радіус за замовчуванням — 1 м, тобто 2 метри завширшки: найчастіша причина «щось величезне закрило екран»
<a-camera> очі глядача. Якщо не написати — A-Frame додасть свою
<a-cursor> курсор усередині камери. Пускає невидимий промінь уперед; без нього клікати нема чим

Система координат: три числа в метрах

Атрибут position="x y z" — це три числа через пробіл. Без ком. Одиниця виміру — метр. Нуль — центр сцени на рівні підлоги.

X + · вправо Y + · вгору Z + · до тебе Z − · углиб екрана 0 0 0 камера 0 1.6 0 — рівень очей a-box position="0 1 -3" по центру, метр над підлогою, три метри попереду одна клітинка осі = 1 метр
Схема осей. Камера за замовчуванням стоїть у точці 0 1.6 0. Це середній зріст очей людини. Дивиться вона в бік мінус Z. Тому все, що ти хочеш бачити, став із від'ємним z.
Найчастіша помилка з позицією Учень ставить об'єкт у position="0 0 0" і не бачить нічого. Об'єкт там є. Просто він у тебе під ногами й позаду камери. Другий варіант тієї самої помилки — position="0 1.6 0". Тоді камера опиняється всередині об'єкта. Зсередини грані не малюються, тож екран чорний.
Питання

Ти хочеш поставити кулю так, щоб вона висіла на рівні твоїх очей за три метри попереду. Яке значення position?

Обертання, розмір, колір

АтрибутФорматЩо робить
rotation"x y z", градуси повертає об'єкт навколо трьох осей. "-90 0 0" кладе вертикальну площину горизонтально — так робиться підлога
scale"x y z", множник "2 2 2" — удвічі більший, "0.5 0.5 0.5" — удвічі менший. Одиниця — без змін
color"#E76F51" або "tomato" колір матеріала. Той самий шістнадцятковий запис, що й у CSS
id, classяк у звичайному HTML щоб знайти об'єкт із JS: querySelector('#score'), querySelectorAll('.clickable')
Площину видно лише з одного боку Тег <a-plane> малює одну сторону. Обійдеш площину — побачиш порожнечу. Для стіни, повз яку ходять, додай material="side: double".
Питання

Ти зробив підлогу <a-plane scale="8 8 8">, але вона стоїть перед тобою стіною. Який атрибут забули?

Крок 4

Анімація одним атрибутом

Рух у A-Frame пишеться в розмітці, а не в JavaScript

Рух у A-Frame вмикають атрибутом animation. Він уже вбудований у бібліотеку, докачувати нічого не треба.

Ти кажеш йому три речі. Що змінювати. До якого значення. За скільки часу. Усі проміжні стани він щокадру рахує сам.

три види руху
<a-box position="-1 0.5 -3" color="#E76F51" animation="property: rotation; to: 0 360 0; loop: true; dur: 6000; easing: linear"></a-box> <a-sphere position="0 1.5 -5" radius="0.5" color="#F4A261" animation="property: position; to: 0 2.1 -5; dir: alternate; loop: true; dur: 2000; easing: easeInOutSine"></a-sphere> <a-cylinder position="2 0.5 -4" radius="0.5" height="1" color="#2A9D8F" animation="property: scale; to: 1.4 1.4 1.4; dir: alternate; loop: true; dur: 1500"></a-cylinder>
ВластивістьЗначенняЩо означає
propertyrotation, position, scale, material.color що саме змінюємо
toкінцеве значення задається абсолютно, а не «на скільки». Для position це нова точка у метрах, а не зсув
durмілісекунди тривалість одного проходу. 6000 — шість секунд на оберт
looptrue або число true — нескінченно, 3 — три рази
diralternate рух туди-назад. Без нього об'єкт стрибне на початок ривком
easinglinear, easeInOutSine характер руху. Для нескінченного обертання беруть linear, інакше видно ривок на стику кіл
Крапка з комою, а не кома Усередині animation="…" властивості розділяються крапкою з комою. А координати всередині значення — пробілом. Кома не працює ніде. Помилки в консолі при цьому може й не бути — просто нічого не рухається.
Питання

Куля має плавно підніматися й опускатися, і так нескінченно. Ти написав property: position; to: 0 2.1 -5; loop: true; dur: 2000 — куля повзе вгору й кожні дві секунди ривком падає вниз. Чого бракує?

Крок 5

Клік і лічильник

Помилка номер один усієї теми — і вона в одному рядку

У 3D-сцені немає «кліку по картинці». Працює це як ліхтарик, прикріплений до голови.

З камери вперед виходить невидимий промінь. У що промінь упреться, те й отримає подію click, коли ти натиснеш.

Промінь створює курсор. Немає курсора — немає променя. Немає променя — жоден обробник не спрацює.

1 · камера a-camera 2 · курсор a-cursor усередині камери 3 · промінь летить у бік −Z 4 · влучив .clickable 5 · подія click на самому об'єкті 6 · обробник у JS n = n + 1 7 · напис оновлено score.setAttribute('text', 'value', …) немає a-cursor — ланцюжок рветься тут
Ось де рветься ланцюжок. Немає курсора в камері — немає променя. Об'єкт не отримає подію, обробник мовчить. А в консолі при цьому жодної помилки. Тому цю поломку так важко знайти.
курсор і клікабельний об'єкт
<a-box class="clickable" position="-1 0.5 -3" color="#E76F51"></a-box> <a-camera> <a-cursor raycaster="objects: .clickable"></a-cursor> </a-camera>

Запис raycaster="objects: .clickable" каже променю перевіряти лише позначені об'єкти.

Без цього рядка теж працює. Але тоді браузер щокадру перевіряє все підряд. На телефоні це помітно з'їдає кадри.

Лічильник у <a-text>

Напис у сцені — окремий об'єкт зі своєю позицією. Змінити його текст із JavaScript можна лише трьома аргументами: назва компонента, назва властивості, нове значення.

обробник кліку й оновлення напису
<a-text id="score" value="Очки: 0" position="0 2.4 -3" align="center" width="6" color="#EDF2F4" font="assets/Roboto-msdf.json"></a-text> <script> document.addEventListener('DOMContentLoaded', function () { var n = 0; var score = document.querySelector('#score'); document.querySelectorAll('.clickable').forEach(function (el) { var base = el.getAttribute('color'); el.addEventListener('click', function () { n = n + 1; if (score) score.setAttribute('text', 'value', 'Очки: ' + n); el.setAttribute('color', n % 2 === 1 ? '#F4D35E' : base); }); }); }); </script>
Два аргументи замість трьох — і напис не змінюється Запис score.setAttribute('value', n) нічого не зробить. Тут value — не компонент, а властивість усередині компонента text. Правильно так: score.setAttribute('text', 'value', n). Помилки в консолі не буде. Лічильник у пам'яті рахує, а напис у сцені мовчить.
Про event-set__click У прикладах в інтернеті клік часто вішають атрибутом event-set__click. Це стороннє доповнення. Усередині aframe.min.js його немає — потрібен ще один файл, а качати його з CDN нам не можна. Тому в нас клік обробляє звичайний addEventListener. Так навіть чесніше: видно, що саме відбувається.
Питання

Ти додав у обробник console.log(n) — числа в консолі ростуть після кожного кліку. Але напис у сцені так і показує «Очки: 0». Де помилка?

Крок 6

Редактор сцени

Крути параметри — код праворуч оновлюється сам. Копіюєш і вставляєш у свій index.html

Самої бібліотеки тут немає: сторінка уроку теж нічого не тягне з CDN. Тому замість тривимірного перегляду — дві схеми.

Вигляд згори показує, де об'єкти стоять на підлозі. Вигляд збоку — на якій вони висоті. А головний результат — готова розмітка внизу.

Вигляд згори · площина X-Z

Вигляд збоку · площина X-Y

А ось те, що з цього виходить. Кнопка «копіювати» бере весь файл цілком: від <!doctype> до останнього тега.

lesson-08/index.html
Скопіювати й здати — не спрацює Чекер порівнює твою сцену зі стартовим шаблоном. Власного коду має бути щонайменше 30%. Приклад із п'яти об'єктів — це відправна точка. Зміни типи, кольори, позиції, додай своє. На захисті все одно доведеться пояснити кожен атрибут.
Питання

У редакторі ти поставив п'ять об'єктів, але всі — a-box трьох різних кольорів, з анімацією й кліком. Чекер усе одно червоний. Яку вимогу порушено?

Крок 7

Коли нічого не працює

Консоль браузера — F12, вкладка Console. Спочатку читаємо, потім правимо

Що бачишЩо в консоліЩо робити
Біла порожня сторінка, жодного полотна GET .../lesson-08/assets/aframe.min.js 404 (Not Found) Неправильний шлях до бібліотеки. Перевір: файл справді в lesson-08/assets/, у src немає слеша на початку, ім'я теки саме assets, а не Assets — Linux розрізняє регістр
Чорний екран, але кнопка «VR» у кутку є порожньо Немає <a-sky> — фон за замовчуванням чорний. Другий варіант: ти додав власний <a-light>, і A-Frame прибрав два свої стандартні світла; одного слабкого замало
Чорний екран, і він не змінюється, коли крутиш камеру порожньо Камера всередині об'єкта. Зсередини грані не малюються. Прибери з точки 0 1.6 0 все, що там стоїть
Сцена є, але порожня порожньо Об'єкти позаду камери: z додатний або нуль. Став від'ємний: -3, -4, -5
Клік нічого не робить порожньо Немає <a-cursor> всередині <a-camera>. Або в raycaster="objects: .clickable" вказано клас, якого немає на об'єктах
Лічильник не змінюється порожньо setAttribute('value', n) замість setAttribute('text', 'value', n)
Напису немає взагалі GET .../assets/Roboto-msdf.json 404 Шрифт не лежить поруч із бібліотекою. Попроси вчителя розкласти Roboto-msdf.json і Roboto-msdf.png
Локально працює, на сервері біло 404 на будь-який файл Різниця в регістрі імен після заливання по FTP або файл потрапив не в ту теку. Відкрий адресу файлу напряму в браузері — 200 чи 404 видно одразу
Чекер каже «зовнішній домен» У HTML лишилося посилання на CDN — на бібліотеку, на шрифт або на event-set. Шукай у файлі рядок https://
Перевіряй на сервері одразу після заливання Половина поломок з'являється саме між «працює локально» і «лежить на сервері». Правило просте. Залив — відкрив https://логін.домен/lesson-08/ — глянув консоль. І так щоразу, а не раз наприкінці уроку.
швидка перевірка з термінала сервера
$ curl -o /dev/null -s -w "%{http_code}\n" http://91.219.61.4/s/$(whoami)/lesson-08/ 200 $ curl -o /dev/null -s -w "%{http_code}\n" http://91.219.61.4/s/$(whoami)/lesson-08/assets/aframe.min.js 200
Питання

Сторінка відкривається, кнопка «VR» у кутку є, камера крутиться — але екран чорний і не змінюється, хоч куди повернись. У консолі жодної помилки. Що це майже напевно?

Крок 8

Портфоліо модуля

Вісім тем зводяться в один файл: ~/www/index.html

Усі вісім тем ти складав по одній теці. Сьогодні вони з'єднуються.

Головна сторінка твого сабдомена — це зміст усього модуля. З неї має відкриватися кожна робота. І кожне посилання має віддавати 200.

lesson-01 Залізо машини sysinfo.sh · hardware.txt lesson-02 Порти й мережа net.log · speed.txt · peer.txt lesson-03 Звук у файлі report.csv · cmd.txt lesson-04 Растр і вектор logo.svg · sizes.csv lesson-05 Відео й монтаж cmd.txt · probe.txt lesson-06 Формати й скрипти detect.sh · manifest.json lesson-07 ШІ й атрибуція prompts.json · exif.txt lesson-08 VR-прототип index.html · game-design.json www/index.html портфоліо модуля 8 посилань · кожне віддає 200 https://логін.домен/ адреса, яку можна дати будь-кому
Кожна тема лишила по собі легкі файли на сервері. Головна сторінка їх не дублює, а лише веде до них. Тому вона маленька й майже ніколи не ламається.

Що писати про кожну роботу

Саме лише посилання нічого не каже. Тому пиши по три частини: що це, що саме зроблено, чого навчився. Два-три рядки, без води.

ПоганоДобре
Тема 3. Звук. Тема 3. Одне джерело — чотири формати. Порахував розмір WAV за формулою й звірив із реальним файлом; різниця 0,4%. Зрозумів, за що платимо бітрейтом.
Тема 6. Скрипт. Тема 6. Пакетна конвертація 10 файлів. Скрипт визначає справжній тип за першими байтами, а не за розширенням — три файли в наборі були підписані неправильно.
~/www/index.html — каркас портфоліо
<!doctype html> <html lang="uk"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Портфоліо · Олена Петренко · 8А</title> </head> <body> <h1>Олена Петренко · IT Skills, модуль I</h1> <p>Вісім тем, вісім робіт. Усе зроблено власноруч, файли лежать на цьому ж сервері.</p> <ol> <li><a href="lesson-01/">Тема 1. Технічний паспорт машини</a> — скрипт sysinfo.sh знімає модель процесора, пам'ять і диски. Навчився читати вивід lscpu і відрізняти залізо від софту.</li> <li><a href="lesson-02/">Тема 2. Мережевий паспорт і стенд інтерфейсів</a> — виміряв швидкість тричі, порахував середнє, перевірив чужий сабдомен.</li> <li><a href="lesson-03/">Тема 3. Аудіолабораторія: чотири формати</a> — той самий звук у WAV, FLAC, MP3 і OGG; таблиця розмірів і висновок на слух.</li> <li><a href="lesson-04/">Тема 4. П'ять доль одного зображення</a> — растр проти вектора, власний logo.svg без жодного пікселя всередині.</li> <li><a href="lesson-05/">Тема 5. Мій перший монтаж у командному рядку</a> — нарізка, склейка й підпис через ffmpeg; кодек і контейнер — різні речі.</li> <li><a href="lesson-06/">Тема 6. Пакетна конвертація скриптом</a> — визначення типу за першими байтами, manifest.json на 10 файлів.</li> <li><a href="lesson-07/">Тема 7. Галерея з чесною атрибуцією</a> — чотири згенеровані зображення, промпти й позначки походження.</li> <li><a href="lesson-08/">Тема 8. VR-прототип</a> — сцена A-Frame з анімацією, кліком і лічильником очок.</li> </ol> <p>Модуль I «IT Skills (Hardware &amp; Multimedia)», 8-А, 2025/2026.</p> </body> </html>
Слеш у кінці посилання — не дрібниця Запис href="lesson-04/" веде на теку. Сервер сам віддасть із неї index.html. Запис href="lesson-04" без слеша спрацює не завжди. А href="/lesson-04/" зі слешем спереду — це вже корінь сайту. Один зайвий символ — і чекер бачить 404.

Пройди всі вісім, перш ніж тиснути «перевірити»

Одрук у назві теки — найчастіша причина червоного фінального критерію. Команда нижче проходить усі вісім посилань за секунду й показує код кожного.

перевірка восьми посилань однією командою
$ for n in 01 02 03 04 05 06 07 08; do printf "lesson-%s " "$n"; curl -o /dev/null -s -w "%{http_code}\n" "http://91.219.61.4/s/$(whoami)/lesson-$n/"; done lesson-01 200 lesson-02 200 lesson-03 200 lesson-04 404 lesson-05 200 lesson-06 200 lesson-07 200 lesson-08 200

Вивід тут ілюстративний — показано, як виглядає знайдена помилка. У тебе всі вісім мають бути 200.

QR на власний сабдомен

Набирати довгу адресу на телефоні незручно. Тому згенеруй QR-код. Програма qrencode уміє віддавати його як SVG, а SVG приймальня пропускає.

QR у вигляді SVG
$ qrencode -t SVG -o ~/www/lesson-08/qr.svg "http://91.219.61.4/s/$(whoami)/lesson-08/"
Питання

Чекер пише: lesson-04 → 404. Ти заходиш по FTP — тека lesson-04 на місці, файли всередині є. Що перевіряєш першим?

Питання

Тему 5 ти закрив давно, а в теці www/lesson-05/ досі лежить забутий out.mp4 на 12 МБ. Сьогодні йде фінальний прогін по всьому кабінету. Що буде?

Крок 9

Практика

Спочатку доводимо сцену локально, тоді заливаємо. Галочки зберігаються — сторінку можна закрити.

Де що робиться Сцену ти збираєш і налагоджуєш у себе на комп'ютері. Файл index.html лежить поруч із локальною копією aframe.min.js. По FTP іде лише готовий легкий текст. Медіафайли сервер і не прийме.

Крок 10

Автоперевірка · check 08

Найважчий чекер модуля. Він відкриває сцену справжнім браузером без вікна, рахує об'єкти й натискає на них. Спроби не обмежені.

Демонстраційний режим: результат згенеровано для показу. На сервері ця кнопка викликає POST /api/check, який запускає /opt/school/check/lesson-08.sh від імені учня.

Як чекер доводить, що лічильник справді працює

Код він не читає. Код можна написати гарно й неробочий.

Замість цього він відкриває сторінку браузером без вікна. Зчитує напис у <a-text>. Робить два кліки по клікабельному об'єкту. Зчитує напис ще раз.

Не змінилося — критерій червоний. Навіть якщо на вигляд усе на місці.

З консоллю так само. Чекер збирає всі помилки рівня error. Їх має бути нуль. Один 404 на шрифт — і критерій не пройдено.

Що вчитель дивиться на екрані

Крок 11

Шкала виконання

Це те, що бачить учитель, коли виставляє оцінку.

СкладникВагаРезультат
Виконано
0%
Рекомендований бал за 12-бальною

Домашнє завдання

Надішли посилання на своє портфоліо у чат класу. Додай три речення: яка з восьми тем виявилася найкориснішою і чому.

Не «сподобалась», а саме найкорисніша. Тобто те, чим ти скористаєшся поза уроком.

Підсумок модуля: шістнадцять уроків одним поглядом

У вересні ти вмів користуватися комп'ютером. Зараз ти вмієш давати йому команди й розуміти, що він відповідає.

І в тебе є адреса в інтернеті, де це видно. Не переказ уроків, а вісім робіт, які ти зробив сам.

ТемаНе вмів на початкуУмієш тепер
Вступ сервер — щось абстрактне заходиш по SSH, орієнтуєшся в кабінеті, публікуєш файл по FTP
1 «у мене хороший комп'ютер» читаєш склад машини командами й пишеш скрипт, що робить це за тебе
2 «інтернет не працює» розрізняєш кабель, порт і протокол, міряєш швидкість і читаєш маршрут
3 звук — просто файл рахуєш розмір WAV за формулою і пояснюєш, за що платиш бітрейтом
4 «картинка розмита, збільш її» вибираєш формат під задачу і робиш вектор, який не розмивається ніколи
5 відео = mp4 відрізняєш кодек від контейнера й монтуєш із командного рядка
6 тип файлу — це розширення визначаєш справжній тип за першими байтами й автоматизуєш це скриптом
7 ШІ «просто малює» розумієш, звідки береться зображення, і чесно позначаєш походження
8 3D — це магія пишеш власну сцену з анімацією та інтерактивом і налагоджуєш її по консолі

Є ще одна навичка, і вона не належить жодній темі окремо. Ти навчився шукати причину, а не перезавантажувати.

404 у консолі. Великі літери в імені файлу. Зайва кома в атрибуті. Це вже не «нічого не працює», а конкретна поломка з конкретним виправленням.

Саме це й лишиться з тобою, коли назви бібліотек і версій забудуться.

Джерела

Звідки взяті факти й формулювання

Офіційна документація A-Frame, специфікації й довідники. Перевіряти дозволено й корисно.

Повний список із поясненнями, що саме звідки взято і які числа є ілюстративними, — у файлі urok-16-джерела.md поруч із цією сторінкою.