Будни разработчика
14.6K subscribers
1.36K photos
397 videos
8 files
2.28K links
Download Telegram
Как правильно работать с резервным копированием в облаке?

25 июня приглашаем на бесплатный вебинар от MWS Cloud Platform всех, кто работает с облаками.

Развеем мифы, разберём лучшие современные подходы и инструменты.

Обсудим интеграцию в процессы, консистентность, точечное восстановление и безопасность. Поговорим о плюсах нативных облачных инструментов.

Проведём демо в MWS Cloud Platform и ответим на ваши вопросы.

Зарегистрируйтесь, чтобы не пропустить!

25 июня в 14:00 (мск)

Зарегистрироваться
Please open Telegram to view this post
VIEW IN TELEGRAM
#новость дня

В HTTP появился (точнее, вот-вот появится, только RFC приняли) новый метод QUERY.

Примерно такой:


QUERY /search
Content-Type: application/json

{
"q": "foo",
"limit": 10,
"sort": "-published"
}


И самое интересное тут даже не то, что теперь можно отправлять сложный поисковый запрос в теле HTTP-запроса. Самый интересный вопрос: а разве мы не могли делать это через GET?

Могли. Иногда даже делали.


GET /search
Content-Type: application/json

{
"q": "foo",
"limit": 10,
"sort": "-published"
}


На уровне HTTP-сообщения тело у GET возможно. Протокол не развалится только потому, что после заголовков пришёл body.

Проблема в другом: у тела GET нет нормальной общей семантики.

Стандарт не говорит: «тело GET — это параметры запроса». Сервер и клиент могут между собой так договориться, но для остальной инфраструктуры это будет частная магия. Прокси, CDN, кэши, балансировщики, библиотеки и браузерные API не обязаны понимать такой договор.

Поэтому GET с body — это поведение из серии “может работать в нашей связке”. Где-то пройдёт, где-то тело проигнорируют, где-то запрос завернут, а где-то его вообще нельзя будет отправить. Например, браузерный fetch не разрешает body у GET и HEAD.

QUERY как раз стандартизирует этот сценарий.


QUERY /search
Content-Type: application/json

{
"q": "foo",
"limit": 10,
"sort": "-published"
}


Смысл метода: это запрос на чтение, но параметры запроса лежат в теле. То есть больше не нужно притворяться, что сложный фильтр — это короткая строка query-параметров, и не нужно использовать POST там, где состояние на сервере не меняется.

От POST отличие тоже важное. POST для HTTP-инфраструктуры выглядит как метод с возможными побочными эффектами. QUERY, наоборот, описан как safe и idempotent: его можно повторить, не ожидая, что повтор сам по себе что-то создаст или изменит.

Получается, QUERY — это не «GET с body», а нормальный стандартный способ сказать: тело запроса важно, оно описывает выборку, и сам запрос при этом остаётся запросом на чтение.

#http
👍195
#такое дня

Как выбесить коллег одной строкой?

А сейчас я покажу вам...

Автор

#бородач #js
🤩17🤬4👍3🤡1
#ссылка дня

Когда-то давным давно поддержки кастомных шрифтов в браузерах толком не было, а желание сделать красиво — было.

Как же обходились? Ну, например, генерировали картинки, используя библиотеки FreeType и (для PHP) GD2/Imagemagick.

К слову, это до сих пор валидный кейс, соответствующие плагины для популярных CMS вполне себе поддерживаются: https://www.drupal.org/project/textimage

Просто зачастую нет никакого смысла тащить целый шрифт на фронт ради пары заголовков. Да и даже его часть — тоже.

Естественно, всегда можно резать набор глифов (символов) на лету... например, утилитами вроде https://opentype.js.org/ или FontForge в командном режиме, но каждый ли проект в этом нуждается?

А, ну и как же, нельзя забывать о вкладе Adobe Flash в поддержку кастомных шрифтов! Была технология sIFR, которая генерировала маленькие Flash-апплеты на месте, где должен был располагаться ваш заголовок.

Или аналогичная — Cufon, но уже на связке JS/SVG или VRML (векторный язык в IE).

Забавное было время, конечно, но иногда лучше и правда сгенерировать картинку, чем тащить весь шрифт целиком.

#font #old #бородач
5
Media is too big
VIEW IN TELEGRAM
Вышел anime.js 4.5.0.

Anime.js — это JavaScript-библиотека для анимаций. Её часто используют для DOM, CSS-свойств, SVG, таймлайнов и обычных JS-объектов: когда нужна не одна transition, а нормальное управление движением, задержками, easing’ами и последовательностями.

В 4.5.0 появился API адаптеров. Если коротко, теперь anime.js можно научить работать с объектами, которые устроены не как DOM-элементы.

Главный пример в этом релизе — встроенный адаптер для Three.js.

В Three.js анимация часто требует писать во вложенные свойства объекта:


mesh.position.x = 100
mesh.rotation.y = Math.PI / 4
mesh.material.opacity = 0.5
mesh.material.color.set('#ff8844')


С адаптером это можно описывать прямо в animate():


animate(mesh, {
x: 100,
rotateY: 45,
opacity: 0.5,
color: '#ff8844',
})


Адаптер сам сопоставляет параметры с position, rotation, material, цветом и другими свойствами Three.js.

Появился и более привычный для фронтендера синтаксис 3D-трансформаций: rotateX, rotateY, rotateZ, scale, transformOrigin, плюс skewX, skewY, skewZ.

Материалы тоже стало анимировать проще. Цвет можно передавать строкой — hex, rgb, hsl или CSS-переменной — без ручного перекладывания в THREE.Color.

Ещё одна хорошая часть — instanced mesh. Объекты, которые в Three.js обычно используются для большого количества одинаковой геометрии, теперь можно анимировать почти как обычные меши. Для сцен с сетками, частицами, волнами и кучей повторяющихся элементов это сильно сокращает ручной код.

В stagger() добавили поддержку 3D: теперь задержки можно раскладывать не только по x и y, но и по z. Плюс появились jitter и seed, чтобы делать разброс в движении, но при этом получать повторяемый результат.

Остальные изменения — в changelog: фиксы timeline, keyframes, seek, reversed loops, render engine, работа с цветами и разные мелкие правки.

Важная деталь: сайт anime.js теперь тоже портирован на новый API с Three.js-адаптером. То есть это не просто пример в документации, а уже основа для собственного сайта проекта.

Получился релиз, после которого anime.js заметно лучше ложится на 3D-сцены. Да здравствуют описания анимаций без постоянного ручного прохода по position, rotation, material и прочим внутренним полям.

#animejs #animation #threejs
13
Media is too big
VIEW IN TELEGRAM
#статья дня

Не так давно в чате канала проскочил вопрос, как правильно делать контейнеры, которые могут вылезать за визуальные границы.

Например, основной контент находится посредине и занимает в ширину 80-120 приятных для чтения глазу символов, а вот картинки хотелось бы разнести до краёв.

Техника называется full bleed. Я не знаю, как точно перевести.

Если посмотрите видео, то виден ещё один вариант использования, когда галерея выходит за пределы экрана лишь с одной стороны, но дальше тем не менее границы игнорирует.

Вот так: https://codepen.io/hexagoncircle/pen/gOWjwme

Альтернативный вариант: https://codepen.io/maartenbruggink/full/eYWjxae

Раньше такое делалось жонглированием полями, теперь же у нас есть гриды.

И у небезызвестного Джоша Комо есть статья как раз об этом: https://www.joshwcomeau.com/css/full-bleed/

Тем не менее, я рекомендую посмотреть приложенные кодпены, поскольку в них зоны грида именуются и становится понятнее, что к чему.

Всем full bleed, котаны!

#css #fullbleed #gallery #бородач
110🫡1
This media is not supported in your browser
VIEW IN TELEGRAM
#библиотека дня

Есть небольшая библиотека для undo/redo в JavaScript: async-history-stack.

Она интересна не тем, что «умеет откатывать состояние». Это как раз самый простой случай. Интереснее другое: в историю можно складывать действия, у которых есть асинхронные операции и побочные эффекты.

Например, пользователь удаляет картинку из галереи. В реальном приложении это может быть не один setState, а целая цепочка: уйти со страницы картинки, отправить запрос на удаление, убрать ссылку из локального состояния, обновить интерфейс.

А при undo надо сделать обратное: восстановить картинку, вернуть ссылку в состояние и снова открыть страницу этой картинки.

async-history-stack предлагает описывать такие действия через push: функция сразу выполняет изменение и возвращает функцию, которая умеет это изменение откатить.


await historyStack.push(async () => {
await applyChanges()

return async () => {
await revertChanges()
}
})


То есть в историю кладётся не снимок объекта, а переход туда-обратно. Благодаря этому undo/redo может быть не привязан к конкретному стору и нормально покрывает навигацию, RPC, работу с файлами и другие асинхронные штуки.

В библиотеке есть undo, redo, clear, size, timestamp, лимит истории, отмена через signal и merge, чтобы склеивать несколько изменений в одну запись. Например, когда много мелких действий должны откатываться одним undo.

Я набросал демо: галерея, удаление карточки, имитация асинхронного RPC, лог операций, undo/redo и восстановление маршрута. Ну и да, вместо обычных заглушек там процедурно генерируются SVG-паркеты, потому что почему бы и нет.

Ссылка на библиотеку:
https://github.com/kettanaito/async-history-stack

Демо:
https://codepen.io/editor/alinaki/pen/019f1263-8e38-73da-a864-9854b6093cee

Всем undo, котаны!

#history #undo #library #svg #tile
13🔥4🫡1
#ссылка дня

Когда технологии стареют, это почти незаметно — пока не становится поздно. Вроде всё работает, но обновлений безопасности больше нет, старые зависимости перестают собираться, а новые версии библиотек ломают совместимость. Так проект постепенно превращается в мину замедленного действия.

Чтобы не попадать в такие ситуации, существует проект endoflife.date. Он показывает, когда заканчивается поддержка языков, библиотек, фреймворков и систем. Вводишь, например, Node.js или Ubuntu — и сразу видно, какие версии ещё живы, а какие пора обновлять. У них даже есть открытое API, так что можно встроить проверку прямо в CI и получать напоминания автоматически.

Но обновляться стоит с умом. Иногда новая версия приносит несовместимые изменения и кучу головной боли. Поэтому существуют LTS-версии — стабильные ветки, которые поддерживаются дольше обычных и меняются не так резко. На них удобно сидеть, если важна предсказуемость и стабильность.

Простая идея, но в долгосрочной перспективе экономит много времени и нервов.

#lts #support #бородач
6🫡2
#инструмент дня

Я уже один раз потерял ссылку на этот сервис, потому на правах закладки.

Встречайте, Cobalt: https://cobalt.tools/

Это сервис с открытым исходным кодом (GitHub), предназначенный для скачивания видео с большой кучи разнообразных сервисов: вк, ютуб, рутуб, тикток, твиттер, инстаграм и так далее и тому подобное. Полный список тут.

Никакой рекламы и занудства. Разве только UI на мобиле подглючивает — у меня не всегда правильно определяется безопасная зона "чёлки".

В общем, рекомендация.

#video #download #бородач
14🔥4🤡2
Соскучились по рождественским календарям для программистов?

У CodeRun тут получился Advent of Code посреди лета, только с более олимпиадной составляющей: 15 задач, которые выкатываются пачками по 5 штук каждые 5 дней до 17 июля, общий зачёт и отдельные лидерборды по 11 языкам.

Главная механика — не просто «решил / не решил». Быстрый и экономный код даёт больше баллов, так что после первого accepted всё только начинается: можно переписывать решение, смотреть на время, память, крайние случаи и пытаться выжать из него ещё немного.

Я знаю людей, которые реально встают на час раньше, чтобы перед работой прорешать очередной LeetCode. Я не уверен, что сам готов к такой дисциплине, но понимаю, зачем они это делают: алгоритмы быстро ржавеют, если их не трогать. А здесь примерно тот же формат тренировки, только не в одиночном режиме и с таблицей, где сразу видно, насколько твоё «и так нормально» на самом деле нормально.

Призы тоже есть: топ-1 по каждому из 11 языков получает мерч-пак CodeRun, топ-3 общего зачёта — коллекционный лего-набор, а топ-200 общего зачёта — скип контеста и пробное интервью в Яндекс.

Последний пункт, кстати, довольно практичный. Даже если не относиться к этому как к спорту, такой челлендж можно использовать как понятный способ размяться перед алгоритмическими интервью: задачи, ограничения, дедлайн, сравнение решений и болезненное напоминание, что O(n²) иногда всё ещё O(n²).
🔥32👍2
Media is too big
VIEW IN TELEGRAM
#фишка дня

Когда я наткнулся на этот твит в обсуждении утилиты работы с цветами Андрея Ситника, я не сразу примерил его на себя. Но, как оказалось, стоило бы.

Итак, давайте поясню для тех, кто по ссылкам не ходит.

В азиатских иероглифических языках почти весь ввод с клавиатуры происходит в аккордном режиме или же в режиме т. н. композитинга, общее название — Input Method Editor.

TL;DR: На экране всплывает окошко с символами или их группами и пользователь может что-то выбрать.

На каких-то ОС оно вызывается долгим зажатием клавиши, где-то — по хоткею, а где-то — автоматически и сразу.

Так вот, одно дело азиатские языки (я очень рекомендую посмотреть сам твит), а другое — разные европейские. И речь о диакритических знаках: умляуты, акуты, ударения, птички и шапочки.

Так вот, я не имею финской раскладки, потому буквы ä, å и ö ввожу как раз в режиме композитинга, долгим зажатием «материнской» клавиши.

Собственно, так база для азиатских языков проникла и в мою жизнь.

Кстати, выбор Emoji из всплывающего окошка — туда же.

В JavaScript-событиях для этого режима имеется флаг isComposing. Поэтому если вы, как и я в примере на видео, решили реализовать ввод групп символов подобным образом — циклически перебирая поля ввода — стоит об этом подумать :)

Собственно, давайте и пример: https://codepen.io/alinaki/pen/MWMpdvO?editors=1010

И напишите в комментариях, как вы решаете проблему редкого ввода букв с диакритикой у себя в системе. Например, я не помню, как это происходит в Windows, а в Linux я использую клавишу Compose, она работает чуть иначе.

#javascript #composing #event #бородач
🔥5
#инструмент дня

Появился Nub — новый «всё-в-одном» тулкит для JavaScript. Название, конечно, опасное: любой пост про него автоматически звучит как обращение к аудитории.

GitHub: https://github.com/nubjs/nub
Site: https://nubjs.com/

Кто уже догадался, откуда у названия ноги растут?

Да, оттуда.

Но есть нюанс: Nub не пытается заменить Node.js.

Смысл такой: дать разработчику всё приятное, что люди обычно хвалят в Bun — быстрый запуск, TypeScript из коробки, меньше зоопарка CLI, — но оставить выполнение кода на старом добром Node.js.

Nub — это один Rust-бинарник поверх обычного Node.js. Он умеет:

— запускать TypeScript/TSX/JSX без отдельного build step
— автоматически подхватывать tsconfig paths
— грузить .env
— импортировать YAML/TOML/JSONC/JSON5
— работать как быстрый runner для package.json scripts
— заменять npx/pnpm exec
— ставить зависимости
— управлять версиями Node
— делать watch mode

То есть вместо набора из tsx, ts-node, dotenv, tsconfig-paths, nvm, pnpm run, npx и пары заклинаний из README вашего монорепо — один nub.

Главный selling point не «мы быстрее всех, потому что переписали мир на Zig, потом по-ковбойски переписали его на Rust с помощью ИИ, а теперь давайте все сделаем вид, что это нормальный жизненный цикл инфраструктурного рантайма».

Код в итоге выполняет обычный Node.js. Nub просто добавляет слой удобства: транспиляцию через oxc, хуки резолвинга, полифиллы и быстрые команды вокруг проекта.

На сайте, конечно, бенчмарки красивые:

nub run — сильно быстрее npm run / pnpm run
nubx — сильно быстрее npx
nub install — быстрее pnpm и, по их тестам, даже чуть быстрее bun install
nub index.ts — примерно как обычный node по старту и быстрее tsx

Плюс отдельно упирают в supply-chain безопасность: build scripts по умолчанию не запускаются, свежие подозрительные релизы можно придерживать, вредоносные пакеты проверяются через OSV.

Выглядит как очень понятная реакция на последние годы JS tooling: всем понравилось, что Bun быстрый и удобный, но не всем хочется тащить в прод ещё один почти-Node, который иногда внезапно оказывается «почти», а потом ещё и внезапно оказывается почти переписанным.

Nub говорит: а давайте оставим Node, но перестанем страдать от того, что вокруг него исторически вырос целый огород одноразовых CLI.

Пока штука свежая, я бы не тащил её сразу в критичный CI без проверки, но для внутренних тулов, dev-скриптов и монореп — очень интересно.

#node #bun #typescript #oxc #rust
👍13🔥3🫡21
#уязвимость дня

У браузеров новый жанр: сайт может косвенно смотреть, что вы делаете на компьютере, по задержкам SSD.

Исследователи из Graz University of Technology показали атаку FROST. Схема примерно такая: сайт заводит себе большой файл в локальном хранилище браузера через Origin Private File System и постоянно читает его маленькими кусками. Пока SSD занят только этим — задержки одни. Открыли другой сайт или приложение — нагрузка на диск изменилась, задержки тоже. По этим микросдвигам можно попытаться понять, что ещё запущено на компьютере.

В эксперименте сайты угадывались примерно с точностью 89%, приложения — около 96%.

Отдельно хороша реакция браузеров. По пересказу Ars Technica и Tom’s Hardware, Google не считает fingerprinting уязвимостью безопасности. Apple, судя по статье, отправила в сторону будущих privacy-защит. Mozilla проблему признала, но фикса пока нет.

Получилось как обычно: API добавляли для нормальных вещей — локального хранения, офлайн-работы, быстрых приложений. А потом выяснилось, что из этого же API можно собрать ещё один датчик состояния машины.

Закрывать лишние вкладки теперь можно не из-за RAM, а для своей же приватности.

#ssd #vulnerability
9👎1👏1🤬1
#игра дня

Среда — это маленькая пятница! Время сыграть в... Carmageddon!

Его как Никита Аксёнов портировал в браузер :) Точнее, не оригинальную игру, а движок Deathrace, целью которого является реверс-инжиниринг оригинального движка.

Естественно, чтобы играть локально нужны ассеты игры, но по ссылке — всё работает прекрасно: https://retrogamescenter.ru/ports/carmaweb/index.html

В отличие от нативного Carmageddon, управление тут перенесено на стрелки, а не работает на Numpad. Я всё ещё помню, насколько это было ублюдочно.

Я стар. Я суперстар.

Жаль, мультиплеер не пашет пока :)

#game #old
10👍1🤡1
Media is too big
VIEW IN TELEGRAM
#инструмент дня

После Scratch в обучении программированию часто начинается пробел.

Сначала ребёнок собирает игру из блоков: персонаж ходит, говорит, что-то собирает. Всё живое и понятное. А потом ему внезапно дают VS Code, JavaScript, Canvas, npm и объясняют, что теперь надо быть взрослым.

Roblox Studio и Minecraft MakeCode этот пробел частично закрывают, но по-своему. Они хорошо отвечают на вопрос «зачем мне вообще кодить»: чтобы сделать свой мир, карту, режим, предмет или механику. Но как следующий шаг после Scratch они не всегда мягкие. Roblox Studio быстро превращается в отдельную IDE с Luau, сценой, объектами и клиент-серверной моделью. Minecraft — в редстоун, команды, datapacks, моды и свою специфическую экосистему.

Odyc.js интересен тем, что он меньше.

Это маленький JavaScript-движок для пиксельных narrative games: карта, персонаж, диалоги, звуки, взаимодействия. Игру можно собрать буквально в одном файле, без большого геймдев-цирка и обряда посвящения через инфраструктуру. У него есть песочница, где можно сразу ковырять игру в браузере.

Для обучения это хороший масштаб: уже не блоки, но ещё не Unity. Ребёнок пишет настоящий код, видит объекты, строки, координаты, условия и события — и всё это сразу превращается не в абстрактный прямоугольник, а в комнату, дверь, ключ, NPC и диалог.

Scratch учит: программирование — это поведение.

Minecraft и Roblox показывают: кодом можно менять миры.

Odyc аккуратно вставляется между ними: теперь то же самое, но буквами — и пока в масштабе, который можно удержать в голове.

#game #js
👍7🫡3
Проект от подписчика!

Напоминаю, что я выкачу любую статью или проект от вас, не стесняйтесь писать.

Презентация? Выступили на митапе? Хотите поделиться интересной статьёй — добро пожаловать!



Всем привет! Меня зовут Влад. Хочу поделиться историей создания своего iOS-приложения «Мои зубы: дневник».

В конце 2025 года, работая HTML-верстальщиком, я остался без работы и решил перейти в разработку, начав изучать React. Вместо учебных задач придумал собственный pet-проект - стоматологический дневник.

Идея появилась из собственного опыта. Из-за частых переездов информация о лечении зубов постоянно терялась и со временем забывалась. Тогда решил совместить обучение с решением собственной проблемы. Так появилась первая веб-версия с минимальным интерфейсом и базовым функционалом заметок. По сути, это был полигон для экспериментов, на котором я закреплял полученные знания о новой технологии.

Но постепенно проект начал увлекать меня все больше. Я придумывал новые функции, улучшал интерфейс и в какой-то момент поймал себя на мысли, что хочу довести его до состояния настоящего продукта, причем в формате мобильного приложения.

Разработка мобильной версии потребовала разобраться не только с React Native, но и глубже погрузиться в UI/UX, адаптацию интерфейса и пользовательский опыт. Для ускорения миграции и разработки активно использовал Codex.

Больше всего переживал за публикацию в App Store, но модерация прошла с первой попытки менее чем за сутки.

Немного о технической стороне проекта. Приложение построено по принципу Local First: все основные данные хранятся на устройстве пользователя, поэтому регистрация не требуется. Для резервного копирования используется iCloud.

С точки зрения функциональности это уже не просто заметки. Дневник поддерживает ведение нескольких профилей, детскую и взрослую схемы зубов, позволяет вести записи не только по зубам, но и по полости рта, деснам, брекетам, капам, протезам и пластинкам. Также есть напоминания, экспорт стоматологической карты в PDF, учет расходов с экспортом в CSV, поддержка нескольких языков и множество настроек для персонализации.

Сейчас продолжаю развивать проект в свободное время. Теперь, когда публикация первой версии позади, начинается не менее интересный этап - продвижение и поиск первых пользователей.

Буду очень благодарен за установку, отзыв в App Store или обратную связь. Спасибо всем, кто решит поддержать проект !🫶🏻
App Store:
https://apps.apple.com/app/id6777985791
👍22🔥123👏2
#релиз дня

TypeScript 7.0 доехал до stable: тот самый компилятор на Go теперь ставится обычным npm install -D typescript.

Пресс-релиз: https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/

Языковых изменений по сравнению с TypeScript 6 почти нет: главный смысл релиза — новый нативный компилятор.

Microsoft обещает примерно 8–12x ускорение именно для TypeScript-компилятора на больших проектах. В их бенчмарках VS Code проверяется за 10.6 секунды вместо 125.7, Sentry — за 15.7 вместо 139.8, Playwright — за 1.47 вместо 12.8. Памяти тоже обычно уходит меньше.

Но это не значит, что весь ваш build внезапно стал в десять раз быстрее. Ускорили tsc, type-checking и language server. А рядом всё ещё живут бандлер, тесты, линтеры, генераторы, typedoc, typescript-eslint и всякая обвязка, которая как раз может сломаться первой.

Но есть скучная часть, из-за которой лучше не обновлять это пятничным вечером.

Зелёный tsc --noEmit ещё не значит, что миграция зелёная. Сам код может типизироваться нормально, а вот вокруг него внезапно начнёт трещать обвязка: старые опции в tsconfig, тулзы, которые лезут в Compiler API, генераторы схем, typedoc, ts-morph, typescript-eslint с type-aware правилами, кастомные трансформеры и прочая инженерная живность.

Microsoft прямо пишет: в TypeScript 7.0 нового API ещё нет, он ожидается в 7.1, причём будет другим. Для переходного периода предлагается держать рядом TypeScript 6 через @typescript/typescript6, чтобы tsc уже был быстрым, а инструменты, которым нужен старый API, пока жили на старой версии.

Так что новость хорошая, но миграция не уровня «npm update и пошли пить кофе». Сначала grep по tsconfig на старые флаги, потом проверка всего, что импортирует typescript, потом уже tsc --noEmit, build и тесты. Особенно если у вас монорепа, decorators/metadata, Nest/TypeORM/MikroORM или самописный codegen.

TypeScript стал сильно быстрее, а твоя миграция — нет.

#typescript
1🔥6🤩1
This media is not supported in your browser
VIEW IN TELEGRAM
#заметка дня

Одно из моих любимых применений ИИ-агентов и ИИ вообще, это разработка под закрытые, ограниченные и легаси-платформы. Например, NES/Dendy, PalmOS, Rockbox для iPod или... телевизор.

Да-да, стоит себе в комнате телевизор на Tizen, вроде и можно на него приложения ставить — а нечего. Стриминги да и только. Ну да, может и есть в магазине пара игр, но там какое-то невозможное количество рекламы.

А иногда хочется просто позалипать в условный тетрис, 2048, сокобан, арканоид — на большом экране и без возни с эмуляторами. Да даже приставку запускать в лом.

Штош, приступаем к работе!

Одна из самых сложных задач — это тулинг. В случае Tizen OS он давно не обновлялся, эмулятор вообще не работает под современными маками, половина бинарников — под Intel-машины. Установка и настройка всего этого, выбор подходящих версий SDK и закрепление документации жрут какое-то невероятное количество контекста.

После же начинается классическая проблема. Да, игры известные и ничего нового я пока не привношу, кода в сети полно. Но именно по этой причине ИИ пишет какую-то совершеннейшую неоптимизированную дичь.

Да и я тоже не особо в курсе, как пишутся игровые движки, потому пришлось повозиться. Но мы дошли от стабильных 3 кадров в секунду при перерисовке всего экрана разом до стабильных ограниченных сверху 50! C эффектами шейдеров и звуком :)

Врубаешь звук, и всё падает с 50 кадров до 25. Кто ж знал, что надо держать аудиоконтекст прогретым и запускать звуки только по событию, а не всегда держать в процессе :)

В общем, подробности последуют. Пишется это всё на C++ c таргетом в NaCl (говорю же, старый ТВ), WebAssembly и Cocoa (macOS, на илюстрации). Очень хотелось выжать максимум из платформы.

Оставайтесь на связи, дальше будет больше :) Исходники и релиз тоже попозже.

#tizen #nacl #webassembly
5🔥5
#фишка и #статья дня

Надоело проигрывать битву z-index? Используй BFG от CSS: infinity.

Ладно, кроме шуток (хотя я и не шутил). С помощью infinity можно гарантировать верно скруглённые углы на прямоугольниках, мы с вами уже рассматривали алгоритм для веба и Flutter: https://xn--r1a.website/htmlshit/1565

Вместо

border-radius: 9999px;

...пишем:

border-radius: calc(infinity * 1px);


А ещё в CSS общепринятое «если что-то поделить на ноль, получится бесконечность» вполне себе закреплено на практике:


calc(infinity) = calc(1 / 0)
calc(1px / 0) = calc(infinity * 1px)


Учителя вторых классов будут нами явно недовольны.

В общем, читаем статью и погружаемся в бесконечность и далее:
https://codersblock.com/blog/playing-with-infinity-in-css/

#css #infinity #math #бородач
6👍3👎1
This media is not supported in your browser
VIEW IN TELEGRAM
#статья дня

У Джоша Комо вышел разбор squash and stretch — старого анимационного приёма, который нормально работает и в интерфейсах.

Суть простая: объект во время движения немного растягивается, а при остановке или ударе — сжимается. Из-за этого движение выглядит не таким механическим.

В интерфейсах это можно использовать совсем незаметно. Например, при наведении стрелка не только удлиняется, но ещё чуть меняет форму:

.arrow {
transition: transform 200ms;
}

.button:hover .arrow {
transform: scaleX(1.15) scaleY(0.9);
}

Особенно хорошо это работает с пружинной анимацией вместо обычного easing. Но выкручивать эффект сильно не стоит: тогда кнопка уже начинает вести себя как желе.

Ну а сама статья тут: Squash and Stretch

#animation #tutorial
🔥91