Telegram Web Link
#инструмент дня

Я, конечно, прошу прощения за неожиданную иллюстрацию к посту, но у меня примерно сейчас такие вот ощущения от либы, про которую хочу рассказать :)

И называется она, какая неожиданность, cigs.

Ну, буквально: 🚬 cigs

Сразу ссылка: https://github.com/cigs-tech/cigs

Итак, что же она делает.

А она позволяет задавать вопросы по заданной Zod-схеме обычным человеческим языком используя OpenAI-токены!

Короче, ещё более просто. Описываешь некую схему объекта, а потом спрашиваешь у системы: "А какой там любимый цвет у Джона?". И получишь ответ!

Пример:
function getUserCompliment(username: string) {
const colorMap = {
"Alice": "blue",
"Bob": "green",
"Charlie": "red",
};
return {
color: colorMap[input.username as keyof typeof colorMap] || "unknown",
};
}

const userInfoSchema = z.object({
username: z.string(),
});

// Define a cig to get a user's favorite color
const getFavoriteColor = cig("getFavoriteColor", userInfoSchema)
.handler(async (input) => {
// Simulated database lookup
return getUserCompliment(input.username);
});

// Usage example
(async () => {
try {
const result = await getFavoriteColor.run(
"What is the favorite color of Alice",
); // { color: 'blue' }
console.log(result);

const result2 = await getFavoriteColor.run(
"What is the favorite color of Susan",
); // { color: 'unknown' }
console.log(result2);

// You can also call that function with the specified input
const result3 = await getFavoriteColor.run({ username: "Alice" }); // { color: 'blue' }
console.log(result3);
// Expected output: { username: 'alice', favoriteColor: 'blue', compliment: 'You have great taste!' }
} catch (error) {
console.error("Error:", error);
}
})();


Вы вообще понимаете, что это значит для тех, кто пишет парсеры или генераторы фейковых данных? :)

Вытащить все спец предложения с "красной ценой" со страницы интернет-магазина? Да запросто! Даже если этот самый магазин обфуцирует код.

Или использует Styled Components.

Пройдите на страницу библиотеки и почитайте примеры. Это нечто потрясающее.

#ai #parser
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 #бородач
#инструмент дня

Вы, наверное, уже наслышаны от обладателей айфонов про AirDrop и дикпики.

Кроме шуток, передать файлы по локальной сети между двумя своими устройствами должно быть максимально просто же! Без ковыряний в Network Discovery, настроек Samba и так далее.

И такое решение есть, даже с открытым кодом: LocalSend.

Сайт: https://localsend.org/

Написано на Dart и Flutter, работает на всех разумно доступных платформах: Windows, Linux, MacOS, Android, iOS.

Не опирается на один протокол, а перебирает все доступные и даже может запустить свой собственный сервер по необходимости. В крайнем случае, можно донастроить.

Никаких облаков, всё по локальной сети.

Поддержка нескольких получателей, поддержка буфера обмена.

В общем, если у вас дома зоопарк устройств и пока не хватило времени настроить что-то иное, или лучше Samba вы ничего в жизни не видели — вот это самое то.

Мне особенно импонирует Flutter. Я недавно вернулся к разработке своего пульта и это всё ещё очень приятный экспириенс.

#flutter #localsend #airdrop #network
#проверка дня

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

Чтобы проверить, не боты ли это набегают, давайте проведём эксперимент :)

Впрочем, это частично подтверждается тем, что вам всем нравится формат #фишка дня.

Вот есть такой прекрасный Твиттер-аккаунт CSS Weekly и сегодня на нём вышла подборка про логические свойства CSS, которые вы видите на иллюстрациях.

Поделитесь, пожалуйста, своими мыслями на тему. Нравится ли вам такой формат больше, чем текстовый, и почему?

Очень интересно ваше мнение и, естественно, мне надо понимать, пробовать ли в такой формат самому.
#новость дня

Итак, мы писали Джаваскрипт в браузере, в консоли, на серверах, на микроконтроллерах, в играх, в кофеварках, в аудиоплеерах, телевизорах, в макросах офисных пакетов, в NoSQL базах данных...

Но до сих пор не писали его в хранимых процедурах MySQL!

Встречайте: JavaScript Stored Programs in MySQL. И соответствующий пост в блоге Oracle: https://blogs.oracle.com/mysql/post/introducing-javascript-support-in-mysql

Зачем? Ну для разных целей:
1. Извлечение данных, очевидно
2. Форматирование
3. Примерный поиск
4. Валидация данных
5. Собственные алгоритмы сжатия, сериализации и десериализации данных

Пример:


CREATE FUNCTION gcd_js (a INT, b INT) RETURNS INT
LANGUAGE JAVASCRIPT AS $$

let [x, y] = [Math.abs(a), Math.abs(b)];
while(y) [x, y] = [y, x % y];
return x;

$$;

Работает всё, ожидаемо, на GraalVM. Почему ожидаемо? Ну потому что Oracle и Java/JVM :)

Что, котаны, пишем стартап на MySQL? 😬

#mysql #sql #js #бородач
#такое дня

Тут такое дело, наткнулся на пост в, простите, 𝕏, цитирую: "Айти сообщество может сколько угодно переобуваться в прыжке, переименовывая мастеры в мейны и блэклисты в блоклисты, но в CSS всё ещё есть именованный цвет indianred, и это цвет кожи индейцев".

Давайте чуть разберёмся, вот пример использования: https://codepen.io/alinaki/pen/abPWmNy

Я специально не стал выносить его в иллюстрацию, чтобы каждый себе сам его представил.

Кажется, уже сходу можно догадаться, что это что угодно, но не цвет кожи. На самом деле, он и к индейцам отношения никакого не имеет 🫠

Это цвет почвы, богатой латеритом. В Индии!

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

Впрочем, фирма Crayola, когда-то придумавшая восковые мелки, переименовала Indian Red в ореховый ровно по вышеозначенной причине...

А, ну пост был бы неполон без ссылки на обсуждение рабочей группы CSSWG, как раз об этом: https://github.com/w3c/csswg-drafts/issues/5284

Комментарии там очень интересно почитать, на самом деле. Про статистику использования там тоже есть. И про Навахо

#css #color #indianred #бородач
#заметка дня

Часто приходится делать таблицы в GitHub Markdown? Тогда лови это знание, пригодится.

Списки и контейнеры не могут и не должны отображаться внутри таблиц, набранных "палочками" (||). Палочки — только для текстового контента, для данных. Точка.

Нужен табличный, кхрм, макет (ну список изменений там запихать) – используй HTML таблицы.

Но есть нюанс.

Чтобы правильно использовать Markdown внутри HTML-таблиц, нужно этот самый контент с двух сторон обложить переводами строки, вот так:

<td>

_markdown_ **тут**

</td>

...и будет норм.

#markdown #бородач
#ссылка дня

Воскресная тема для тех, кому за!

Не так давно разработчики WinAmp решили выложить его код в открытый доступ. По пути несколько раз облажавшись и заодно открыв код, который им не принадлежал :)

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

Но раз винамп снова оказался в сфере наших новостей, представляю вашему вниманию каталог скинов для него! Гордого и всё же непобеждённого.

Каждый скин — шедевр своего времени, выверенный до пикселя.

https://skins.webamp.org/

Скины можно попробовать тут же в проигрывателе WebAmp, который является визуальным и функциональным клоном того самого.

Открытый код, кстати! Кому нужна работа с аудио в том числе — рекомендую к ознакомлению.

#history #winamp #music #audio
Media is too big
VIEW IN TELEGRAM
#видео дня

Вы думали, я забыл?

Я тут каким-то чудом выкроил время, подолбился в геометрию, документацию и ChatGPT и таки довёл свой ТВ-пульт на #Flutter до вида, в котором за него уже не стыдно.

Теперь навернуть ещё фичей, отшлифовать настройки и в продакшен, котаны!

Подумываю ввести воскресную рубрику о разработке на Flutter и для не-веба вообще, чтобы получилось некое обещание.

Надо? :)
#молния дня

Срочно нужно ваше мнение! Куда пихать эмодзи: в коммиты, переменные или комментарии? 👴
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня

Дизайнеры в последнее время очень полюбили градиенты. Особенно ненаправленные.

Градиенты как элемент оформления. Градиенты как плейсхолдеры. Градиенты как идея.

И вот вроде есть у нас продукты, исповедующие идеологию LQIP (Low Quality Image Preview), о которых я писал не так давно, но многим этого мало и охота точной настройки. Особенно если дело касается mesh-градиентов (по сетке, или, проще говоря, ненаправленных).

И тут нашёлся такой инструмент для генерации и настройки градиента по фото! Буквально, так и называется: https://photogradient.com/

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

Но для нагруженного проекта я предпочту LQIP или SQIP, ссылку на которые дал выше.

#gradient #tool #mesh
#заметка дня

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

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

Да и выглядит такой код чуток попроще, чем на CustomPainter во Flutter (хотя по факту-то тоже просто холст).

Итак, для пульта я решил сделать D-pad (он же джойстик или directional pad). На моём пульте он состоит из четырех кнопок по кольцу и одной центральной.

Чаще всего, d-pad-ом называют всем известную крестовину, которая не всегда обладает отдельным центром.

Проще всего достичь такого эффекта, разделив весь круг на четыре сектора. Каждый сектор — это дуга, занимающая угол
90°. Чтобы они визуально отделялись, добавляем контуры между дугами, а поверх всего накладываем центральный круг — он становится кнопкой.

Для корректного размещения делим полный угол 360° на количество дуг — четыре — и задаём начальный угол сдвига -45°. Он нужен, чтобы первый сектор смотрел строго вверх. А то а чо он.

В результате получаем симметричный D-pad, где каждый сегмент и центр выделены визуально: https://codepen.io/alinaki/pen/oNKmxNe?editors=0010

Ладно, ладно. Это на бумаге кажется, что всё действительно просто. На деле же я жёстко тупил.

1. Я не очень понимал, как обрабатывать клики, поэтому думал в сторону пяти отдельных элементов. А значит, об уравнении арки.
2. Потом я никак не мог врубиться, как же мне сделать отступы одинаковой ширины. Мысль, что это просто контур, граница, вообще не сразу мне в голову пришла.
3. Вроде, в школе учат, как определять, попала ли точка в контур, заданный неким уравнением, но вспоминаешь это тоже далеко не сразу.

В следующих постах расскажу, как решил уравнение в пункте 3, добавив подсветку нужного сегмента при нажатии.

Не переключайтесь, котаны!

#canvas #paint #remote
This media is not supported in your browser
VIEW IN TELEGRAM
#статья дня

Я уже не раз выражал свою любовь к шейдерам и 3D в целом. Это какой-то свой особый мир, который требует отдельного погружения. Когда удаётся прикоснуться самостоятельно — хоть немного — уже ору от восторга.

Хочется выделить хотя бы недели две только на изучение нужной математики.

Ладно, хватит нытья. Сегодня у нас прошлогодняя работа Shopify: глобус чёрной пятницы.

Да, глобусы разных вариаций с какими-нибудь рюшками постоянно появляются в ежегодных отчётах разных компаний, то у GitHub, то у Google. Но Shopify добавили nice touch в виде шейдеров фейрверков.

И выкатили об этом статью! Вот: https://shopify.engineering/how-we-built-shopifys-bfcm-2023-globe

Пройдите сразу, насладитесь этой красотой. А уже потом провалитесь в статью и удивитесь, что все эти фейрверки — это просто вершины икосаэдров.

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

Это настоящий подарок.

#webgl #glsl #shaders
This media is not supported in your browser
VIEW IN TELEGRAM
#ссылка дня

Паскаля Витьелло и его очередная пачка Tailwind+React UI компонентов возвращается!

Давайте вспоминат: поля ввода, кнопки, чекбоксы, переключатели и радиокнопки.

Что на очереди? Правильно, выпадающие списки!

И опять 50, куда ж без этого.

Часть нативные, часть — shadcdn. К сожалению, без комбобоксов :( Потому, берём в руки react-downshift...

Ссылка: https://originui.com/selects

Как обычно, shadcn и Tailwind, без сюрпризов. Вдохновляемся, котаны?

#tailwind #shadcn #react #ui
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня

Как заполнить фон целым количеством, например, кружочков или цветков?

Ну, вдруг, вы работаете в Маримекко

Очень просто! Используем background-repeat: space.

Работает аналогично флексовому space-between

И пример от Аны Тюдор: https://codepen.io/thebabydino/pen/RwXvryZ

#css #background #fill
2025/07/07 15:31:02
Back to Top
HTML Embed Code: