Русский
Русский
English
Статистика
Реклама

Flow

Типобезопасность в JavaScript Flow и TypeScript

16.04.2021 16:20:16 | Автор: admin
Все, кто имеют дело с разработкой UI в кровавом enterprise наверняка слышали о типизированном JavaScript, подразумевая под этим TypeScript от Microsoft. Но кроме этого решения существует как минимум ещё одна распространённая система типизации JS, и тоже от крупного игрока IT-мира. Это flow от Facebook. Из-за личной нелюбви к Microsoft раньше всегда использовал именно flow. Объективно это объяснял хорошей интеграцией с существующими утилитами и простотой перехода.

К сожалению, надо признать, что в 2021 году flow уже значительно проигрывает TypeScript как в популярности, так и в поддержке со стороны самых разных утилит (и библиотек), и пора бы его закопать поставить на полку, и перестать жевать кактус перейти на де-факто стандарт TypeScript. Но под этим хочется на последок сравнить эти технлогии, сказать пару (или не пару) прощальных слов flow от Facebook.

Зачем нужна безопасность типов в JavaScript?


JavaScript это замечательный язык. Нет, не так. Экосистема, построенная вокруг языка JavaScript замечательная. На 2021 год она реально восхищает тем, что вы можете использовать самые современные возможности языка, а потом изменением одной настройки системы сборки транспилировать исполняемый файл для того, чтобы поддержать его выполнение в старых версиях браузеров, в том числе в IE8, не к ночи он будет помянут. Вы можете писать на HTML (имеется ввиду JSX), а потом с помощью утилиты babel (или tsc) заменить все теги на корректные JavaScript-конструкции вроде вызова библиотеки React (или любой другой, но об этом в другом посте).

Чем хорош JavaScript как скриптовый язык, исполняемый в вашем браузере?

  • JavaScript не нужно компилировать. Вы просто добавляете конструкции JavaScript и браузер обязан их понимать. Это сразу даёт кучу удобных и почти бесплатных вещей. Например, отладку прямо в браузере, за работоспособность которой отвечает не программист (который должен не забыть, например, включить кучу отладочных опций компилятора и соответствующие библиотеки), а разработчик браузера. Вам не нужно ждать по 10-30 минут (реальный срок для C/C++), пока ваш проект на 10к строк скомпилируется, чтобы опробовать написать что-то по другому. Вы просто меняете строку, перегружаете страницу браузера и наблюдаете за новым поведением кода. А в случает использования, например, webpack, страницу еще и за вас перезагрузят. Многие браузеры позволяют менять код прямо внутри страницы с помощью своих devtools.
  • Это кросс-платформенный код. В 2021 году уже почти можно забыть о разном поведении разных браузеров. Вы пишете код под Chrome/Firefox, заранее запланировав, например, от 5% (enterprise-код) до 30% (UI/мультимедиа) своего времени, чтобы потом подрихтовать результат под разные браузеры.
  • В языке JavaScript почти не нужно думать о многопоточности, синхронизации и прочих страшных словах. Вам не нужно думать о блокировках потоков потому что у вас один поток (не считая worker'ов). До тех пор, пока ваш код не будет требовать 100% CPU (если вы пишете UI для корпоритавного приложения), то вполне достаточно знать, что код исполняется в одном единственном потоке, а асинхронные вызовы успешно оркестрируются с помощью Promise/async/await/etc.
  • При этом даже не рассматриваю вопрос, почему JavaScript важен. Ведь с помощью JS можно: валидировать формы, обновлять содержимое страницы без перезагрузки её целиком, добавлять нестандартные эффекты поведения, работать с аудио и видео, да можно вообще целиком клиент своего enterprise-приложения написать на JavaScript.

Как и почти в любом скриптовом (интерпретируемом) языке в JavaScript можно писать неработающий код. Если до этого кода не доберётся браузер, то не будет ни сообщения об ошибке, ни предупреждения, вообще ничего. С одной стороны это хорошо. Если у вас есть большой-большой веб-сайт, то даже синтаксическая ошибка в коде обработчика нажатия кнопки не должна приводить к тому, что сайт не загружается у пользователя целком.

Но и, разумеется, это плохо. Потому что сам факт наличия чего-нибудь где-нибудь это плохо. И было бы здорово до того, как код попадёт на сайт, видимый пользователям, проверить все-все скрипты на сайте и убедиться, что они хотя бы компилируются. А в идеале и работают. Для этого используются самые разные наборы утилит (мой любимый набор npm + webpack + babel/tsc + karma + jsdom + mocha + chai).

Если мы живём в идеальном мире, то все-все скрипты на вашем сайте, даже однострочные, покрыты тестами. Но, к сожалению, мир не идеален, и для всей той части кода, что не покрыта тестами, мы можем только понадеяться на какие-нибудь автоматизированные средства проверки. Которые могут проверить:

  • Что вы корректно используете синтаксис языка JavaScript. Проверяется, что набранный вами текст может быть понят интерпретатором языка JavaScript, что вы не забыли закрыть открытую фигурную скобку, что строковые лексемы корректно ограничены кавычками и прочее, и прочее. Эту проверку выполняют почти все утилиты сборки/траспилирования/сжатия/обфускации кода.
  • Что семантика языка используется корректно. Можно попытаться проверить, что те инструкции, которые записаны в написанном вами скрипте могут быть корректно поняты интерпретатором. Например, пусть есть следующий код:
    var x = null;x.foo();
    

    Данный код является корректным с точки зрения синтаксиса языка. Но с точки зрения семантики он некорректен попытка вызова метода у null вызовет сообщение об ошибке во время выполнения программы.

Кроме ошибок семантики могут быть ещё более страшные ошибки: логические. Когда программа отрабатывает без ошибок, но результат совсем не тот, что ожидался. Классический со сложением строк и чисел:

console.log( input.value ) // 1console.log( input.value + 1 ) // 11

Существующие средства статического анализа кода (eslint, например), может попытаться отследить значительное количество потенциальных ошибок, которые программист допускает в своём коде. Например:


Обратите внимание, что все эти правила по сути представляют собой ограничения, которые линтер накладывает на программиста. То есть линтер фактически уменьшает возможности языка JavaScript, чтобы программист допускал меньше потенциальных ошибок. Если включить все-все правила, то будет нельзя делать присваивания в условиях (хотя JavaScript это изначально разрешает), использовать дубликаты ключей в литералах объектов и даже нельзя будет вызывать console.log().

Добавление типов переменных и проверка вызовов с учётом типов это дополнительные ограничения языка JavaScript, чтобы уменьшить количество потенциальных ошибок.

image
Попытка умножить число на строку

Попытка обратиться к несуществующему (неописанному в типе) свойству объекта
Попытка обратиться к несуществующему (неописанному в типе) свойству объекта

Попытка обратиться к несуществующему (неописанному в типе) свойству объекта
Попытка вызвать функцию с несовпадающим типом аргумента

Если мы напишем этот код без средств проверки типов, то код упешно траспилируется. Никакие средства статического анализа кода, если они не используют (явно или неявно) информацию о типах объктов, не смогут эти ошибки найти.

То есть добавление типизации в JavaScript добавляет дополнительные ограничения на код, который пишет программист, но зато позволяет найти такие ошибки, которые в противном случае случились бы во время выполнения скрипта (то есть скорее всего у пользователя в браузере).

Возможности типизации JavaScript


Flow TypeScript
Возможность задать тип переменной, аргумента или тип возвращаемого значения функции
a : number = 5;function foo( bar : string) : void {    /*...*/} 
Возможность описать свой тип объекта (интерфейс)
type MyType {    foo: string,    bar: number}
Ограничение допустимых значений для типа
type Suit = "Diamonds" | "Clubs" | "Hearts" | "Spades";
Отдельный type-level extension для перечислений
enum Direction { Up, Down, Left, Right }
Сложение типов
type MyType = TypeA & TypeB;
Дополнительные типы для сложных случаев
$Keys<T>, $Values<T>, $ReadOnly<T>, $Exact<T>, $Diff<A, B>, $Rest<A, B>, $PropertyType<T, k>, $ElementType<T, K>, $NonMaybeType<T>, $ObjMap<T, F>, $ObjMapi<T, F>, $TupleMap<T, F>, $Call<F, T...>, Class<T>, $Shape<T>, $Exports<T>, $Supertype<T>, $Subtype<T>, Existential Type (*)
Partial<T>, Required<T>, Readonly<T>, Record<K,T>, Pick<T, K>, Omit<T, K>, Exclude<T, U>, Extract<T, U>, NonNullable<T>, Parameters<T>, ConstructorParameters<T>, ReturnType<T>, InstanceType<T>, ThisParameterType<T>, OmitThisParameter<T>, ThisType<T>

Оба движка для поддержки типов в JavaScript обладают примерно одинаковыми возможностями. Однако если вы пришли из языков со сторогой типизацией, даже в типизированном JavaScript есть очень важное отличие от той же Java: все типы по сути описывают интерфейсы, то есть список свойств (и их типы и/или аргументы). И если два интерфейса описывают одинаковые (или совместимые) свойства, то их можно использовать вместо друг-друга. То есть следующий код корректен в типизированным JavaScript, но явно некорректен в Java, или, скажем, C++:

type MyTypeA = { foo: string; bar: number; }type MyTypeB = { foo: string; }function myFunction( arg : MyTypeB ) : string {    return `Hello, ${arg.foo}!`;}const myVar : MyTypeA = { foo: "World", bar: 42 } as MyTypeA;console.log( myFunction( myVar ) ); // "Hello, World!"

Данный код является корректным с точки зрения типизированного JavaScript, так как интерфейс MyTypeB требует наличие свойства foo с типом string, а у переменной с интерфейсом MyTypeA такое свойство есть.

Данный код можно переписать чуть короче, используя литеральный интерфейс для переменной myVar.

type MyTypeB = { foo: string; }function myFunction( arg : MyTypeB ) : string {    return `Hello, ${arg.foo}!`;}const myVar = { foo: "World", bar: 42 };console.log( myFunction( myVar ) ); // "Hello, World!"

Тип переменной myVar в данном примере это литеральный интерфейс { foo: string, bar: number }. Он по прежнему совместим с ожидаемым интерфейсом аргумента arg функции myFunction, поэтому данный код не содержит ошибок с точки зрения, например, TypeScript.

Подобное поведение значительно уменьшает количество проблем при работе с разными библиотеками, пользовательским кодом и даже просто с вызовом функций. Типичный пример, когда некоторая библиотека определяет допустимые опции, а мы передаём их в виде объекта options:

// Где-то внутри библиотекиinterface OptionsType {    optionA?: string;    optionB?: number;}export function libFunction( arg: number, options = {} as OptionsType) { /*...*/ }

// В пользовательском кодеimport {libFunction} from "lib";libFunction( 42, { optionA: "someValue" } );

Обратите внимание, что тип OptionsType не экспортирован из библиотеки (и не импортирован в пользовательский код). Но это не мешает вызывать функцию с использованием литерального интерфейса для второго аргумента options функции, а для системы типизации проверить этот аргумент на совместимость типов. Попытка сделать что-то подобное в Java вызовет у компилятора явное непонимание.

Как это работает с точки зрения браузера?


Ни TypeScript от Microsoft, ни flow от Facebook не поддерживаются браузерами. Как впрочем и самые новые расширения языка JavaScript пока не нашли поддержки в некоторых браузерах. Так как же этот код, во-первых, проверяется на корректность, а во-вторых, как он исполняется браузером?

Ответ траспилирование. Весь нестандартный JavaScript код проходит через набор утилит, которые превращают нестандартный (неизвестный браузерам) код в набор инструкций, который браузеры понимают. Причём для типизации всё превращение заключается в том, что все уточнения типов, все описания интерфейсов, все ограничения из кода просто удаляются. Например, код из примера выше превращается в

/* удалено: type MyTypeA = { foo: string; bar: number; } *//* удалено: type MyTypeB = { foo: string; } */function myFunction( arg /* удалено: : MyTypeB */ ) /* удалено: : string */ {    return `Hello, ${arg.foo}!`;}const myVar /* удалено: : MyTypeA */ = { foo: "World", bar: 42 } /* удалено: as MyTypeA */;console.log( myFunction( myVar ) ); // "Hello, World!"

т.е.
function myFunction( arg ) {    return `Hello, ${arg.foo}!`;}const myVar = { foo: "World", bar: 42 };console.log( myFunction( myVar ) ); // "Hello, World!"


Такое преобразование обычно делается одним из следующих способов.
  • Для удаления информации о типах от flow используется плагин для babel: @babel/plugin-transform-flow-strip-types
  • Для работы с TypeScript можно использовать одно из двух решений. Во-первых можно использовать babel и плагин @babel/plugin-transform-typescript
  • Во-вторых вместо babel можно использовать собственный транспилер от Microsoft под названием tsc. Эта утилита встраивается в процесс сборки приложения вместо babel.


Примеры настроек проекта под flow и под TypeScript (с использованием tsc).
Flow TypeScript
webpack.config.js
{  test: /\.js$/,  include: /src/,  exclude: /node_modules/,  loader: 'babel-loader',},
{  test: /\.(js|ts|tsx)$/,  exclude: /node_modules/,  include: /src/,  loader: 'ts-loader',},
Настройки транспилера
babel.config.js tsconfig.json
module.exports = function( api ) {  return {    presets: [      '@babel/preset-flow',      '@babel/preset-env',      '@babel/preset-react',    ],  };};
{  "compilerOptions": {    "allowSyntheticDefaultImports": true,    "esModuleInterop": false,    "jsx": "react",    "lib": ["dom", "es5", "es6"],    "module": "es2020",    "moduleResolution": "node",    "noImplicitAny": false,    "outDir": "./dist/static",    "target": "es6"  },  "include": ["src/**/*.ts*"],  "exclude": ["node_modules", "**/*.spec.ts"]}
.flowconfig
[ignore]<PROJECT_ROOT>/dist/.*<PROJECT_ROOT>/test/.*[lints]untyped-import=offunclear-type=off[options]

Разница между подходами babel+strip и tsc с точки зрения сборки небольшая. В первом случае используется babel, во-втором будет tsc.


Но есть разница, если используется такая утилита как eslint. У TypeScript для линтинга с помощью eslint есть свой набор плагинов, которые позволяют найти ещё больше ошибок. Но они требуют, чтобы в момент анализа линтером у него была информация о типах переменных. Для этого в качестве парсера кода необходимо использовать только tsc, а не babel. Но если для линтера используется tsc, то использовать для сборки babel будет уже неправильно (зоопарк используемых утилит должен быть минимальным!).


Flow TypeScript
.eslint.js
module.exports = {  parser: 'babel-eslint',  parserOptions: {    /* ... */
module.exports = {  parser: '@typescript-eslint/parser',  parserOptions: {    /* ... */

Сравнение flow и TypeScript


Попытка сравнить flow и TypeScript. Отдельные факты собраны из статьи Nathan Sebhastian TypeScript VS Flow, часть собрана самостоятельна.

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

Различные линейки
Flow TypeScript
Основной contributor Facebook Microsoft
Сайт flow.org www.typescriptlang.org
GitHub github.com/facebook/flow github.com/microsoft/TypeScript
GitHub Starts 21.3k 70.1k
GitHub Forks 1.8k 9.2k
StackOverflow frequent 2289 49 353
StackOverflow unanswered 123 11 451

Смотря на эти цифры у меня просто не остаётся морального права рекомендовать flow к использованию. Но почему же я использовал его сам? Потому что раньше была такая штука, как flow-runtime.

flow-runtime


flow-runtime это набор плагинов для babel, который позволяет встроить типы от flow в runtime, использовать их для определения типов переменных в runtime, и, самое главное для меня, позволяло проврять типы переменных в runtime. Что позволяло в runtime во время, например, автотестов или ручного тестирования отловить дополнительные баги в приложении.

То есть прямо во время выполнения (в debug-сборке, разумеется), приложение явно проверяло все-все типы переменных, аргументов, результаты вызова сторонних функций, и всё-всё-всё, на соответствие тех типов.

К сожалению, под новый 2021 год автор репозитория добавил информацию о том, что он перестаёт заниматься развитием данного проекта и в целом переходит на TypeScript. Фактически последняя причина оставаться на flow для меня стала deprecated. Ну что же, добро пожаловать в TypeScript.
Подробнее..

14 свежих и полезных дизайн-ресурсов в Январе

17.01.2021 12:19:01 | Автор: admin

Что в сегодняшнем выпуске: различные генераторы, крутые источники для вдохновения, стильные иконки, топовые продукты из Product Hunt за 2020 год, инструменты для экспорта анимаций и гифок, и многое другое.

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

Погнали!

14. Vektors

Vektors это агрегатор коллекций с иллюстрациями. Все иллюстрации этого ресурса бесплатные (но на некоторые коллекции есть пользовательские лицензии).

В Vektors вы найдете иллюстрации от художников по всему миру и для самых разных проектов. Иллюстрации доступны в форматах PNG, SVG, Figma, Sketch.

На данный момент паки насчитывают 70+ единиц.

13. Pattern Generator

Браузерный генератор текстур позволяет создавать уникальные royalty-free текстуры.

УPattern Generatorгибкие настройки: выбрав базовый стиль, вы можете затем настроить свою текстуру с помощью цветов, фильтров и преобразований. Каждый стиль узора имеет свои уникальные преобразования. Кнопка Shuffle это та же кнопка Random, которая перемешивает стили и выдает рандомизированные элементы.

Экспортнуть файл можно не только в JPEG или PNG, но и в качестве кода для inline SVG и фоновой картинки CSS.

12. Gumaffiliates

Gumaffiliates новый ресурс, который позволяет развивать партнерский маркетинг через Gumroad.

Идеален как для креативщиков без аудитории, так и для affiliate-маркетологов с аудиторией, но без своей продукции.

Приобретя товар (Gumaffiliates стоит $1):

1) Креативщики получают таблицу людей с аудиторией;

2) Affiliate-маркетологи получают таблицы с продуктами, которые нужно продвигать.

В таблицы входят следующие данные: название продукта (в случае affiliate партнера это название аудитории), ниша, сайт, контактные данные.

11. Parametric Color Mixer

Parametric Color Mixerпозволяет генерировать цвета и затем настраивать палитру при помощи интерактивных эквалайзеров.

После того, как вы определились с выбором цвета, его можно регулировать посредством следующих параметров: Положение, Воздействие, Диапазон, Смешивание.

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

Экспорт в SVG и CSS.

10. Game UI Database

Этот сайтсоздан специально для дизайнеров, специализирующихся на создании игр.На этом ресурсе вы найдете обширную базу самых разных элементов: от различных попап-меню до HUD элементов. Просто кладезь информации для игровых дизайнеров.Почти 13 000 скриншотов из 355 игр. Более 80 типов экранов.

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

Также можно фильтровать по жанру, теме, эстетическим элементам игр, устройству / элементам управления и т.д.

9. GIFRun

GIFRunпозволяет создавать GIF-изображения без водяных знаков с разных соцсетей, типа YouTube, Facebook, TikTok, Vimeo, Twitter и многих других, где есть функция встроенного видео.

Просто вставьте ссылку источника, определите продолжительность и время начала, добавьте текст (по желанию) и ваш GIF-файл готов.

8. Doodle Strudel

Если вы работаете художником или иллюстратором то попробуйтеDoodle Strudel. Этот генератор задач от Пабло Стэнли отличная вещь для тех, у кого кризис идей.

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

7. Scale

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

Нужную иллюстрацию можно найти в поисковой строке, или профильтровать по полу, а при настройке можно подбирать цветовую схему в поле HEX-кода.

Иллюстрации доступны в SVG и PNG форматах.

Ресурс совсем новый, но коллекция эффектных иллюстраций насчитывает уже более 120 единиц.

Авторы гарантируют каждый день выкладывать что-то новое.

6. UX Database

Каталог UX-ресурсов, который мы заслуживаем.

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

Сортировать можно по следующим категориям: исследования, анализ, визуальный дизайн, дизайн интерфейсов, продукты нового поколения (AR / VR, чат-боты и т. д.), продуктивности, обучению, мультимедиа.

База данных также удобна тем, что каждый ресурс помечен доступностью: платный, бесплатный или с лицензией Freemium.

5. Pattern Collect

Pattern Collect это своеобразный Dribbble для художников, создающих узоры и текстуры.

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

Ресурс содержит шаблоны в 45 категориях, включая: абстракцию, лица, геометрические фигуры, краски, ретро и многое другое.

4. Flow

Flow это новый игрок на рынке моушн-дизайна. В арсенал инструмента входит:

Импорт файлов Figma, Sketch, XD, Illustrator, Affinity и т.д. (в будущем обещают добавить поддержку Instagram и Dribbble);

Большой ассортимент самых разных функций для крутого анимирования;

Прямой экспорт ваших анимаций из Sketch / Figma в чистый код для Swift, React, SVG и др.

Анимации onboarding экранов, кнопок, рекламного контента и промо-роликов Flow станет отличным помощником в добавлении изюминки вашему продукту.

К тому же, интерфейс Flow интуитивно понятен, т.к. вобрал в себя лучшие практики интерфейса дизайн-инструментов последних лет. Поэтому, если вы умеете работать в Figma или Sketch значит вы быстро разберетесь и с Flow.

3. Byte Dance Icons

Byte Dance Icons крутая коллекция иконок из Figma community, содержащая

почти 3000 элементов для самых разных проектов. Иконки доступны в стилях outlined, filled и two-tone.

Для использования иконок в коде доступна документация дляVueиReact.

Коллекция постоянно обновляется.

2. Best of Product Hunt

Один энтузиаст собрал в Notionтаблицу с лучшими продуктами на Product Hunt за 2020год. Здесь вы найдете коллекцию из более чем 360 продуктов.

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

На 1-ом месте у нас статьяThe State of Design Systems: 2020. Это очень информативный материал, где Google провел исследование касательно использования дизайн-систем в 2020 году. В этом исследовании Google опросил более 1000 дизайнеров.

1. The State of Design Systems 2020

Делимся с вами основными результатами.

UI киты, по мнению 83% опрошенных одна из главных составляющих дизайн-системы. Что в очередной раз подтверждает эффективность его использования.

Figma лидер в таких компонентах, как:

1) Инструменты для дизайна цифровых продуктов;

2) Инструменты дизайн-документации и передачи файлов разработчикам;

3) Инструменты, используемые для управления дизайн-системами.

Material Design с отрывом на первом месте в сегменте используемых дизайн-систем. Далее идут Apples Human-Interface Guidelines и Bootstrap (неожиданно!).

Все больше компаний предпочитают создавать собственные дизайн-системы. 80% респондентов сообщили, что они разрабатывали собственные дизайн-системы внутри компаний. Основная причина своя дизайн-система лучше соответствует бренду компании.

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

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

Подробнее..

Перевод Миграция с LiveData на Kotlins Flow

08.06.2021 16:18:29 | Автор: admin

LiveData была нужна нам еще в 2017 году. Паттерн наблюдателя облегчил нам жизнь, но такие опции, как RxJava, в то время были слишком сложными для новичков. Команда Architecture Components создала LiveData: очень авторитетный класс наблюдаемых хранилищ данных, разработанный для Android. Он был простым, чтобы облегчить начало работы, а для более сложных случаев реактивных потоков рекомендовалось использовать RxJava, используя преимущества интеграции между ними.

DeadData?

LiveData по-прежнему остается нашим решением для Java-разработчиков, новичков и простых ситуаций. В остальном, хорошим вариантом является переход на Kotlin Flows. Flows (потоки) все еще имеют крутую кривую обучения, но они являются частью языка Kotlin, поддерживаемого Jetbrains; кроме того, на подходе Compose, который хорошо сочетается с реактивной моделью.

Мы уже говорили об использовании Flows для соединения различных частей вашего приложения, за исключением представления и ViewModel. Теперь, когда у нас есть более безопасный способ сбора потоков из пользовательских интерфейсов Android, мы можем создать полное руководство по миграции.

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

Flow: простые вещи труднее, а сложные легче

LiveData выполняла одну вещь и делала это хорошо: она показывала данные, одновременно кэшируя последние значения и учитывая жизненные циклы Android. Позже мы узнали, что она также может запускать корутины и создавать сложные преобразования, но это требовало немного больше усилий.

Давайте рассмотрим некоторые паттерны LiveData и их эквиваленты Flow:

#1: Показ результата однократной операции с модифицированным держателем данных

Это классический паттерн, в котором вы мутируете держатель состояния с результатом выполнения корутины:

Показ результата однократной операции с модифицированным (Mutable) держателем данных (LiveData)Показ результата однократной операции с модифицированным (Mutable) держателем данных (LiveData)
<!-- Copyright 2020 Google LLC.   SPDX-License-Identifier: Apache-2.0 -->class MyViewModel {    private val _myUiState = MutableLiveData<Result<UiState>>(Result.Loading)    val myUiState: LiveData<Result<UiState>> = _myUiState    // Load data from a suspend fun and mutate state    init {        viewModelScope.launch {             val result = ...            _myUiState.value = result        }    }}

Чтобы сделать то же самое с потоками, мы используем модифицированный StateFlow:

Показ результата однократной операции с модифицированным держателем данных (StateFlow)Показ результата однократной операции с модифицированным держателем данных (StateFlow)
class MyViewModel {    private val _myUiState = MutableStateFlow<Result<UiState>>(Result.Loading)    val myUiState: StateFlow<Result<UiState>> = _myUiState    // Load data from a suspend fun and mutate state    init {        viewModelScope.launch {             val result = ...            _myUiState.value = result        }    }}

StateFlow это особый вид SharedFlow (который является особым типом Flow), наиболее близкий к LiveData:

  • У него всегда есть значение.

  • У него только одно значение.

  • Он поддерживает несколько наблюдателей (поэтому поток является общим).

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

При отображении состояния пользовательского интерфейса для представления используйте StateFlow. Это безопасный и эффективный наблюдатель, предназначенный для хранения состояния пользовательского интерфейса.

#2: Показ результата однократной операции

Это эквивалент предыдущего сниппета, демонстрирующий результат вызова корутины без модифицированного теневого свойства.

В LiveData мы использовали для этого конструктор корутин liveData:

Показ результата однократной операции (LiveData)Показ результата однократной операции (LiveData)
class MyViewModel(...) : ViewModel() {    val result: LiveData<Result<UiState>> = liveData {        emit(Result.Loading)        emit(repository.fetchItem())    }}

Поскольку держатели состояния всегда имеют значение, хорошей идеей будет обернуть наше UI-состояние в какой-нибудь класс Result, который поддерживает такие состояния, как Loading, Success и Error.

Эквивалент Flow немного сложнее, потому что вам придется выполнить некоторую настройку:

Показ результата однократной операции (StateFlow)Показ результата однократной операции (StateFlow)
class MyViewModel(...) : ViewModel() {    val result: StateFlow<Result<UiState>> = flow {        emit(repository.fetchItem())    }.stateIn(        scope = viewModelScope,         started = WhileSubscribed(5000), // Or Lazily because it's a one-shot        initialValue = Result.Loading    )}

stateIn это оператор Flow, который преобразует его в StateFlow. Давайте пока доверимся этим параметрам, так как позже нам понадобится более сложная информация для правильного объяснения.

#3: Однократная загрузка данных с параметрами

Допустим, вы хотите загрузить некоторые данные, которые зависят от ID пользователя, и вы получаете эту информацию от AuthManager, который показывает Flow:

Однократная загрузка данных с параметрами (LiveData)Однократная загрузка данных с параметрами (LiveData)

С помощью LiveData можно сделать примерно следующее:

class MyViewModel(authManager..., repository...) : ViewModel() {    private val userId: LiveData<String?> =         authManager.observeUser().map { user -> user.id }.asLiveData()    val result: LiveData<Result<Item>> = userId.switchMap { newUserId ->        liveData { emit(repository.fetchItem(newUserId)) }    }}

switchMap это преобразование, тело которого выполняется, а результат подписывается при изменении userId.

Если нет причин для того, чтобы userId был LiveData, лучшей альтернативой этому является объединение потоков с Flow и окончательное преобразование полученного результата в LiveData.

class MyViewModel(authManager..., repository...) : ViewModel() {    private val userId: Flow<UserId> = authManager.observeUser().map { user -> user.id }    val result: LiveData<Result<Item>> = userId.mapLatest { newUserId ->       repository.fetchItem(newUserId)    }.asLiveData()}

Выполнение этого действия с помощью Flows выглядит очень похоже:

Однократная загрузка данных с параметрами (StateFlow)Однократная загрузка данных с параметрами (StateFlow)
class MyViewModel(authManager..., repository...) : ViewModel() {    private val userId: Flow<UserId> = authManager.observeUser().map { user -> user.id }    val result: StateFlow<Result<Item>> = userId.mapLatest { newUserId ->        repository.fetchItem(newUserId)    }.stateIn(        scope = viewModelScope,         started = WhileSubscribed(5000),         initialValue = Result.Loading    )}

Обратите внимание, что если вам нужна большая гибкость, вы также можете использовать transformLatest и emit элементы в явном виде:

val result = userId.transformLatest { newUserId ->        emit(Result.LoadingData)        emit(repository.fetchItem(newUserId))    }.stateIn(        scope = viewModelScope,         started = WhileSubscribed(5000),         initialValue = Result.LoadingUser // Note the different Loading states    )

#4: Наблюдение за потоком данных с параметрами

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

Продолжая наш пример: вместо вызова fetchItem на источнике данных мы используем гипотетический оператор observeItem, который возвращает Flow.

С помощью LiveData вы можете преобразовать поток в LiveData и все обновления emitSource:

Наблюдение за потоком с параметрами (LiveData)Наблюдение за потоком с параметрами (LiveData)
class MyViewModel(authManager..., repository...) : ViewModel() {    private val userId: LiveData<String?> =         authManager.observeUser().map { user -> user.id }.asLiveData()    val result = userId.switchMap { newUserId ->        repository.observeItem(newUserId).asLiveData()    }}

Или, лучше всего, объединить оба потока с помощью flatMapLatest и преобразовать только выход в LiveData:

class MyViewModel(authManager..., repository...) : ViewModel() {    private val userId: Flow<String?> =         authManager.observeUser().map { user -> user?.id }    val result: LiveData<Result<Item>> = userId.flatMapLatest { newUserId ->        repository.observeItem(newUserId)    }.asLiveData()}

Имплементация Flow похожа, но в ней нет преобразований LiveData:

Наблюдение за потоком с параметрами (StateFlow)Наблюдение за потоком с параметрами (StateFlow)
class MyViewModel(authManager..., repository...) : ViewModel() {    private val userId: Flow<String?> =         authManager.observeUser().map { user -> user?.id }    val result: StateFlow<Result<Item>> = userId.flatMapLatest { newUserId ->        repository.observeItem(newUserId)    }.stateIn(        scope = viewModelScope,         started = WhileSubscribed(5000),         initialValue = Result.LoadingUser    )}

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

#5 Объединение нескольких источников: MediatorLiveData -> Flow.combine

MediatorLiveData позволяет вам наблюдать за одним или несколькими источниками обновлений (наблюдаемыми LiveData) и что-то делать, когда они получают новые данные. Обычно вы обновляете значение MediatorLiveData:

val liveData1: LiveData<Int> = ...val liveData2: LiveData<Int> = ...val result = MediatorLiveData<Int>()result.addSource(liveData1) { value ->    result.setValue(liveData1.value ?: 0 + (liveData2.value ?: 0))}result.addSource(liveData2) { value ->    result.setValue(liveData1.value ?: 0 + (liveData2.value ?: 0))}

Эквивалент Flow намного проще:

val flow1: Flow<Int> = ...val flow2: Flow<Int> = ...val result = combine(flow1, flow2) { a, b -> a + b }

Можно также использовать функцию combineTransform или zip.

Настройка открытого StateFlow (оператор stateIn)

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

val result: StateFlow<Result<UiState>> = someFlow    .stateIn(        scope = viewModelScope,         started = WhileSubscribed(5000),         initialValue = Result.Loading    )

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

StateIn имеет 3 параметра (из документации):

@param scope the coroutine scope in which sharing is started.@param started the strategy that controls when sharing is started and stopped.@param initialValue the initial value of the state flow.This value is also used when the state flow is reset using the [SharingStarted.WhileSubscribed] strategy with the `replayExpirationMillis` parameter.

started может принимать 3 значения:

  • Lazily: начать, когда появится первый подписчик, и остановить, когда scope будет отменен.

  • Eagerly: начать немедленно и остановить, когда scope будет отменен.

  • WhileSubscribed: Это сложно.

Для одноразовых операций вы можете использовать Lazily или Eagerly. Однако, если вы наблюдаете за другими потоками, вам следует использовать WhileSubscribed для выполнения небольших, но важных оптимизаций, как описано ниже.

Стратегия WhileSubscribed

WhileSubscribed отменяет восходящий поток, когда нет коллекторов. StateFlow, созданный с помощью stateIn, передает данные в View, но он также наблюдает за потоками, поступающими из других слоев или приложения (восходящий поток). Поддержание этих потоков активными может привести к напрасной трате ресурсов, например, если они продолжают считывать данные из других источников, таких как подключение к базе данных, аппаратные датчики и т.д. Когда ваше приложение переходит в фоновый режим, будет хорошо, если вы остановите эти корутины.

WhileSubscribed принимает два параметра:

public fun WhileSubscribed(    stopTimeoutMillis: Long = 0,    replayExpirationMillis: Long = Long.MAX_VALUE)

Таймаут остановки

Из документации:

stopTimeoutMillis настраивает задержку (в миллисекундах) между исчезновением последнего абонента и остановкой восходящего потока. По умолчанию она равна нулю (остановка происходит немедленно).

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

Решение в конструкторе корутины liveData заключалось в добавлении задержки в 5 секунд, после которой корутина будет остановлена, если нет подписчиков. WhileSubscribed(5000) делает именно это:

class MyViewModel(...) : ViewModel() {    val result = userId.mapLatest { newUserId ->        repository.observeItem(newUserId)    }.stateIn(        scope = viewModelScope,         started = WhileSubscribed(5000),         initialValue = Result.Loading    )}

Этот подход отвечает всем требованиям:

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

  • Последнее значение все еще будет кэшироваться, чтобы, когда пользователь вернется к нему, представление сразу же получило данные.

  • Подписки перезапускаются, и новые значения будут поступать, обновляя экран, когда они доступны.

Истечение срока воспроизведения

replayExpirationMillis настраивает задержку (в миллисекундах) между завершением работы программы совместного доступа и сбросом кэша воспроизведения (что делает кэш пустым для оператора shareIn и возвращает кэшированное значение к исходному initialValue для stateIn). По умолчанию он равен Long.MAX_VALUE (кэш воспроизведения сохраняется постоянно, буфер никогда не сбрасывается). Используйте нулевое значение для немедленного истечения срока действия кэша.

Наблюдение StateFlow из представления

Как мы уже видели, для представления очень важно сообщить StateFlows во ViewModel, что они больше не прослушиваются. Однако, как и во всем, что связано с жизненными циклами, все не так просто.

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

  • Activity.lifecycleScope.launch: запускает корутину немедленно и отменяет ее при завершении активности.

  • Fragment.lifecycleScope.launch: немедленно запускает корутину и отменяет ее при завершении фрагмента.

LaunchWhenStarted, launchWhenResumed...

Специализированные версии launch, называемые launchWhenX, будут ждать, пока lifecycleOwner находится в состоянии X, и приостановят выполнение корутины, когда lifecycleOwner упадет ниже состояния X. Важно отметить, что они не отменяют выполнение программы до тех пор, пока жизненный цикл не будет закончен.

Сбор потоков с помощью launch/launchWhenX небезопасенСбор потоков с помощью launch/launchWhenX небезопасен

Получение обновлений, когда приложение находится в фоновом режиме, может привести к сбоям, что решается приостановкой сбора в View. Однако восходящие потоки остаются активными, пока приложение находится в фоновом режиме, что может привести к трате ресурсов.

Это означает, что все, что мы делали до сих пор для настройки StateFlow, было бы совершенно бесполезно; однако в нашем распоряжении есть новый API.

lifecycle.repeatOnLifecycle на помощь

Этот новый конструктор корутин (доступный в lifecycle-runtime-ktx 2.4.0-alpha01) делает именно то, что нам нужно: он запускает корутины в определенном состоянии и останавливает их, когда уровень жизненного цикла опускается ниже этого состояния.

Различные методы сбора потокаРазличные методы сбора потока

Например, во Фрагменте:

onCreateView(...) {    viewLifecycleOwner.lifecycleScope.launch {        viewLifecycleOwner.lifecycle.repeatOnLifecycle(STARTED) {            myViewModel.myUiState.collect { ... }        }    }}

Сбор начнется, когда представление фрагмента будет STARTED, продолжится до RESUMED и остановится, когда оно вернется к STOPPED. Читайте об этом в статье Более безопасный способ сбора потоков из пользовательских интерфейсов Android.

Сочетание API repeatOnLifecycle с приведенным выше руководством по StateFlow обеспечит вам наилучшую производительность при рациональном использовании ресурсов устройства.

StateFlow выставляется с помощью WhileSubscribed(5000) и собирается с помощью repeatOnLifecycle(STARTED)StateFlow выставляется с помощью WhileSubscribed(5000) и собирается с помощью repeatOnLifecycle(STARTED)

Предупреждение: Поддержка StateFlow, недавно добавленная в Data Binding, использует launchWhenCreated для сбора обновлений, и она начнет использовать repeatOnLifecycle` вместо этого, когда достигнет стабильности.

Для Data Binding вы должны использовать Flows везде и просто добавить asLiveData(), чтобы отобразить их в представлении. Привязка данных будет обновлена, когда lifecycle-runtime-ktx 2.4.0 станет стабильным.

Резюме

Лучшим способом предоставления данных из ViewModel и сбора их из представления является:

  • Выставить StateFlow, используя стратегию WhileSubscribed, с таймаутом. [пример]

  • Собирать с помощью repeatOnLifecycle. [пример].

Любая другая комбинация будет поддерживать восходящие потоки активными, расходуя ресурсы:


Перевод материала подготовлен в рамках курса "Android Developer. Basic". Если вам интересно узнать о курсе больше, приходите на день открытых дверей онлайн. На нем вы сможете узнать подробнее о программе и формате обучения, познакомиться с преподавателем.

Подробнее..

Перевод Поле течения алгоритмы применения

18.11.2020 14:04:51 | Автор: admin

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

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

СЕТКА УГЛОВ

Поля течения основаны на сетке (grid). Грубо говоря, сетка покрывает всю картину. В каждой точке сетки хранится угол. Сетка должна храниться в виде 2D массива чисел с плавающей запятой. Каждая единица в сетке хранит значение угла и одновременно представляет собой точку на сетке.

При созданию сетки надо выбрать ее разрешение. Другими словами, расстояние между точками в сетке. Чем выше разрешение, тем мельче детали, которые вы можете проработать, и плавнее линии. Недостатком является то, что может пострадать функциональность, если увеличите его слишком сильно. Обычно я использую около 0.5% ширины изображения в качестве расстояния между точками. Ещё я использую ту же длину для длины пространства между точками, чтобы упростить расчёты и избежать ошибок точности плавающей запятой.

Последняя настройка, над которой надо подумать - это границы сетки. Вам, наверно, захочется сделать их такими же, как границы самой картина или кадра. Я понял, что лучше делать их ещё больше. Иногда намного больше. Зачем? Если линии выходят за пределы изображения, то это лучше, чем если они просто пропадают. Мне нравится иметь возможность их поворачивать в пределах изображения. Ещё иногда лучше работает, если начинать линии за границами картины и давать им влиться в неё.

Предположим, что перед нами картина 1000 x 1000 пикселей, и мы хотим залить ещё 50% площади вне ее границ. Мы можем установить нашу сетку вот так (псевдокод):

left_x = int(width * -0.5)right_x = int(width * 1.5)top_y = int(height * -0.5)bottom_y = int(height * 1.5) resolution = int(width * 0.01) num_columns = (right_x - left_x) / resolutionnum_rows = (bottom_y - top_y) / resolutiongrid = float[num_columns][num_rows]default_angle = PI * 0.25for (column in num_columns) {    for (row in num_rows) {        grid[column][row] = default_angle    }}

Если бы мы запустили программу для визуализации кода этой сетки в таком виде, то это выглядело бы приблизительно так (качество отрегулировано для лучшей видимости).

Стандартная сетка со всеми углами, установленными на pi* 0.25Стандартная сетка со всеми углами, установленными на pi* 0.25

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

for (column in num_columns) {     for (row in num_rows) {         angle = (row / float(num_rows)) * PI         grid[column][row] = angle     }}

Это выглядит как-то так:

Изогнутая сеткаИзогнутая сетка

РИСОВАНИЕ КРИВХ ЛИНИЙ ЧЕРЕЗ ПОЛЕ

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

// starting pointx = 500y = 100begin_curve()for (n in [0..num_steps]) {    draw_vertex(x, y)    x_offset = x - left_x    y_offset = y - top_y    column_index = int(x_offset / resolution)    row_index = int(y_offset / resolution)    // ПРИМЕЧАНИЕ: обычно на этом этапе стоит проверить границы    grid_angle = grid[column_index][row_index]    x_step = step_length * cos(grid_angle)    y_step = step_length * sin(grid_angle)    x = x + x_step    y = y + y_step}end_curve()

Если мы это проделаем только для одной кривой, это будет выглядеть как-то так:

Рисование единственной простой кривой на полеРисование единственной простой кривой на поле

Нам нужно выбрать значения для нескольких ключевых параметров для рисования линий: step_length, num_steps, и starting position (x, y). Step_length - самый простой параметр. Как правило, он должен быть настолько мал, чтобы нельзя было увидеть никаких резких углов на кривой линии. Как по мне, он должен быть около 0.1%-0.5% ширины картины. Я делаю больше, если мне нужен более быстрый рендеринг, и меньше, если есть углы, которые надо подкорректировать. Другие переменные требуют больше разъяснений.

num_steps

Значение num_steps повлияет на текстуру результата. Небольшие линии могут выглядеть более пушистыми. Длинные - более жидкими. Вот пример одного и того же кода, выполняемого с разными значениями num_steps. Для начала, с короткими линиями:

С короткими линиямиС короткими линиями

И теперь с длинными:

С длинными линиямиС длинными линиями

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

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

Unfenced ExistenceUnfenced ExistenceFragments of ThoughtFragments of Thought

С другой стороны, если я использую близкие цвета, то работа с длинными линиями в самый раз. Посмотрите на задний план: здесь используются лишь едва отличающиеся кремовые цвета.

Loxodography 0.26Loxodography 0.26

starting_point

Все кривые линии должны где-то начинаться. Обычно я использую один из трёх вариантов выбора начальной позиции:

  • Использовать стандартную сетку для начальных позиций

  • Использовать единообразный случайный выбор точек

  • Использовать круговую укладку

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

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

Сетка - Случайный выбор - Круговая укладкаСетка - Случайный выбор - Круговая укладка

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

Сетка - Случайный выбор - Круговая укладкаСетка - Случайный выбор - Круговая укладка

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

ДЕФОРМАЦИЯ ВЕКТОРОВ

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

Шум Перлина

В 90% случаев шум Перлина используется для отстройки векторов. Это удобно и просто, ибо даёт гладкие и продолжительные значения параметров по всей 2D плоскости. Есть ещё разные параметры шума - их множество от значимых до почти не влияющих на итоговую картину. Все это очень легко использовать в Processing. Функция noise() задает значения шума Перлина (между 0,0 и 1,0) с учётом координат.

Вернувшись к коду, мы вместо вставки default_angle можем сделать что-то такое:

for (column in num_columns) {  for (row in num_rows) {      //noise() в // Processing работает лучше всего в середине      // точки примерно 0.005, поэтому уменьшаем до      scaled_x = column * 0.005      scaled_y = row * 0.005      // получаем наше значение шума между 0,0 и 0,1      noise_val = noise(scaled_x, scaled_y)      // перенести значение шума к углу (между 0 0 2 * PI)      angle = map(noise_val, 0.0, 1.0, 0.0, PI * 2.0)      grid[column][row] = angle  }}

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

Использование шума Перлина в углахИспользование шума Перлина в углах

Как бы то ни было, я рекомендую придумать собственный способ деформации векторов, а не полагаться на шум Перлина, ибо он слишком явный и массовый. Но есть ещё один инструмент, о котором лучше знать или начинать с него.

Непродолжающиеся деформации

Важный аттрибут для деформации, который вы можете задать - это будет ли деформация продолжающейся или нет. Под продолжающейся я имею в виду плавный переход между соседними векторами, без прыжков Как я уже упоминал, шум Перлина как раз так и работает. У меня есть своя техника деформации, у которой есть это качество, и которую я люблю использовать. Когда вы используете продолжающуюся деформацию, кривые не пересекают друг друга, они плавные и систематизированные. Однако стоит поэкспериментировать ещё и с непродолжающейся деформацией векторов. Простой пример, как это можно сделать, - начать с шума Перлина, но округлить угол каждого вектора до pi/10:

Так мы получим более скульптурные, каменистые формы. Если увеличим до pi/4, то результат станет странным:

Как вариант, можно выбрать случайный угол (между 0 и pi) для каждого ряда векторов:

Или выбрать случайный угол для каждого вектора.

Суть в том, что и непродолжающиеся деформации тоже могут генерировать хорошие штуки.

СОЧЕТАНИЕ С ДРУГИМИ ТЕХНИКАМИ

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

Можно установить минимально возможное расстояние между кривыми. На каждой стадии кривой проверяйте, не слишком ли близко другая линия. Если близко, то останавливайтесь. Я использовал эту технику на зеркальном рисунке в 2019 году:

Mirror Removal #5Mirror Removal #5

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

Side Effects Inclue\dSide Effects Inclue\d

Можно слегка деформировать сетку между циклами рисования. Это немного изменит линии, которые вы получаете, предоставляя вам разнообразие и накладывающиеся друг на друга линии без полного изменения всей картины:

Festival Notes 0.161Festival Notes 0.161

Можно делать переход между соседними линиями для создания контура многоугольника. Если интерполировать между двумя соседями (возможно, с нелинейным ослаблением), то можно получить плавные, прекрасные формы:

Stripes 0.30Stripes 0.30

Можно вставлять объекты, которые деформируют сетку вокруг самих себя. В Ectogenesis я просчитал, как вода будет двигаться и преломляться вокруг объекта.

(Отмечу, что это было сложно)

Суммируя

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

Популярные посты по генеративному искусству:

Подробнее..

По следам CES 2021 обзор новинок

28.01.2021 16:20:38 | Автор: admin

В начале каждого года в Лас-Вегасе проходит знаковое событие для всех производителей электроники выставка Consumer Electronics Show, она же CES. В 2021 году из-за пандемии коронавируса мероприятие прошло в онлайн-формате, а мы основательно подготовились к выставке, чтобы продемонстрировать новейшие продукты от ASUS и Republic of Gamers.

В этом материале мы собрали основную информацию о всех новых устройствах и инновациях, показанных в рамках выставки.

Оглавление

Презентация Republic of Gamers

Мероприятие Republic of Gamers Для тех, кто не боится мечтать прошло в начале выставки - 12 января. В рамках презентации мы рассказали о новых ноутбуках, мониторах, игровой периферии и представили возможность каждому посетить стенд ROG с помощью приложения-игры ROG Citadel XV, с которой и начнем.

ROG Citadel XV

Смена формата выставки на виртуальный стала отличным поводом для поиска новых способов общения с аудиторией. Поэтому мы разработали собственную игру, в которой можно пройтись по виртуальной крепости и самостоятельно увидеть все новинки ROG Citadel XV.

Игра доступна бесплатно на платформе Steam, поэтому скачивайте ROG Citadel XV и самостоятельно изучайте все новые устройства. Там же можно пообщаться с роботом Omni и пострелять в тире.

Клавиатура ROG Claymore II

Новая клавиатура ROG Claymore II сохранила главную особенность линейки Claymore съёмный цифровой блок. Также мы добавили четыре новые клавиши для макросов или других действий. Находятся они между кнопками цифрового блока и регулятором громкости операционной системы.

В первой версии Claymore использовались механические переключатели Cherry MX, о которых знает любой геймер. Во второй версии вместо механики мы установили фирменные оптико-механические переключатели ROG RX Blue Optical Mechanical Switches. Благодаря новой конструкции механизма, нам удалось уменьшить дрожание клавиши на 50% и расположить точку срабатывания на дистанции в 1,5 миллиметра.

На этом апгрейд ROG Claymore II не закончился. Вторая версия клавиатуры стала беспроводной, а встроенного аккумулятора объёмом 4000 мАч хватит на 47 часов игры при включённой подсветке. Если же отключить подсветку, время автономной работы увеличится до 100 часов. Для подключения клавиатуры к компьютеру и для её зарядки используется кабель Type-C Type-C который поставляется в комплекте. После 30 минут зарядки Claymore II проработает до 18 часов без подсветки и 8 часов с подсветкой.

Мышка ROG Gladius III Wireless

Вторым аксессуаром, который мы представили на CES 2021, стала игровая мышь ROG Gladius III Wireless. Она продолжает линейку мышей Gladius, которые полюбились многим геймерам. Форма корпуса новинки не претерпела значительных изменений, а её вес стал на 30% меньше предшественницы - 89 грамм.

На левой стороне мыши вместо резиновой накладки появилась зона RGB-подсветки Republic of Gamers, выполненная при помощи лазерной гравировки. Возможность смены кликеров у мыши осталась, только теперь кроме 3-контактных переключателей Omron можно использовать 5-контактные оптические микросвитчеры. Также благодаря новому сокету Push-Fit Switch Socket II удалось уменьшить дрожание переключателей.

ROG Gladius III Wireless подключается к компьютеру или ноутбуку тремя разными способами. Через радиоканал 2,4 ГГц, по Bluetooth или при помощи комплектного кабеля. А разрешение оптического сенсора увеличилось до 19000 DPI.

Игровой монитор ROG Swift PG32UQ

Графика в компьютерах и ноутбуках с каждым годом становится мощнее и всё больше пользователей задумываются о приобретении мониторов с диагональю экрана 32 дюйма и выше. Согласно статистике, интерес к подобным моделям постоянно растет, а с 2019 года он вырос и вовсе на 33%. Поэтому игровое сообщество должно по достоинству оценить наш новый 32-дюймовый монитор ROG Swift PG32UQ, который имеет все шансы стать одним из ключевых игровых мониторов 2021 года.

Главная особенность ROG Swift PG32UQ 32-дюймовая IPS-матрица с разрешением 4К, частотой обновления в 144 Гц и временем отклика в 1 мс. Нам удалось собрать множество топовых характеристик в одном устройстве.

Для максимально плавного изображения в PG32UQ реализовали технологии NVIDIA G-Sync и ELMB. Благодаря первой технологии, частота обновления дисплея синхронизируется с частотой FPS видеокарты, а ELMB уберёт размытость у движущихся объектов. Также поддерживается DisplayHDR 600, а для подключения источников видео доступны два разъёма HDMI 2.1 и один DisplayPort 1.4.

Игровые ноутбуки Republic of Gamers, общие улучшения

Игровые ноутбуки ROG, которые выйдут в 2021 году получат несколько общих улучшений. За производительность новинок отвечают процессоры AMD Ryzen 5000-серии, а вместо обычного термоинтерфейса, теперь у всех ноутбуков ROG используется жидкий металл.

В 2021 году мы изменили конструкцию систем охлаждения игровых ноутбуков ROG для большей эффективности. На внешней части вентиляторов появились дополнительные небольшие лопасти, расположенные в виде волны. Благодаря им удалось увеличить эффективность работы вентилятора, и снизить турбулентность воздушных потоков. В результате шум от систем охлаждения снизился с 45 до 40 дБ.

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

Новые ноутбуки ROG оснащены системами виртуального объёмного аудио Dolby Atmos и интеллектуального шумоподавления Two-Way AI Noise Cancellation. Интеллектуальныйшумодав может работать в две стороны сразу: удалять шум из исходящего и входящего аудиопотоков.

Следующей вехой в развитии игровых ноутбуков стали экраны. Пользователям важно не только качество изображения, но и высокая частота обновления. Поэтому наши новые матрицы получили не только высокое качество цветопередачи, подтвержденное сертификатами, но и частоту обновления до 360 Гц и время отклика до 3 мс.

Последняя инновация, общая для всех игровых ноутбуков, касается возможностей зарядки. Вот уже несколько лет многие ноутбуки Republic of Gamers можно заряжать блоками питания с разъёмом Type-C. Подобная опция полюбилась многим нашим пользователям. При помощи компактного БП или пауэрбанка можно зарядить ноутбук в поездке, не доставая оригинальный адаптер. Поэтому мы подняли максимальную входную мощность при зарядке через Type-C с 65 Вт до 100 Вт, что позволило охватить большее количество моделей и увеличить скорость зарядки.

ROG Strix SCAR 17

Мы значительно переработали ноутбуки линейки Strix SCAR 17, чтобы сделать их еще мощнее и круче. Данная модель создана для киберспортсменов, поэтому в ней реализованы наши лучшие технологии и инновации.

Новое поколение Strix SCAR 17 на 7% компактнее предыдущего, при этом объём аккумулятора вырос почти на 50% и его емкость составляет 90 Втч. Для получения красивого орнамента на крышке используется процесс лазерного травления, поэтому нам удалось добавить ещё одну текстуру к крышке ROG Strix SCAR 17.

Новые Скары выпускаются в трёх цветах: чёрном, сером и в полюбившейся многим пользователям неоново-розовой расцветке Electro Punk. Также у новых SCAR 17 есть сменная панель Customizable Armor Cap, которая находится рядом с нижним краем крышки. В комплекте будут поставляться две сменные панели, поэтому пользователи смогут придать больше индивидуальности своим ноутбукам.

За производительность в топовой конфигурации ROG Strix SCAR 17 отвечает 8-ядерный процессор AMD Ryzen 9 5900HX с разблокированным множителем, который работает в паре с видеокартой NVIDIA GeForce RTX 3080 для ноутбуков.

Клавиатура выглядит как классическая островная, но только выглядит. На самом деле, в клавишах используются оптико-механические переключатели, со скоростью срабатывания 0,2 миллисекунды. Для изготовления рабочей области использованы новые технологии с применением стекловолокна, поэтому у пользователей Strix SCAR 17 есть возможность заглянуть внутрь ноутбука, не разбирая его.

ROG Zephyrus Duo 15 SE GX551

Следом за ROG Strix SCAR 17 расскажем про обновлённую версию 17-дюймового игрового ноутбука ROG Zephyrus Duo 15 SE GX551. Корпус новинки остался таким же, как и у предшественника все изменения внутри.

В самой производительной версии GX551 установлен 8-ядерный AMD Ryzen 9 5900HX с максимальной тактовой частотой в 4,6 ГГц. Для максимальной производительности в играх, ноутбук оснащен одной из видеокарт NVIDIA нового поколения: RTX 3070 или RTX 3080 для ноутбуков.

Спецификации основного дисплея зависят от модификации. Если ноутбук покупается для игр, то лучше выбрать версию с разрешением Full HD и частотой обновления 300 Гц. Это обеспечит максимальную плавность картинки. Создателям контента больше подойдёт дисплей c разрешением 4К и частотой 120 Гц. Обе матрицы прошли сертификацию Pantone, которая гарантирует правильную цветопередачу.

Разрешение второго дисплея - ROG ScreenPad Plus - не изменилось с первой версии (GX550), оно по-прежнему составляет 3840x1100 пикселей

ROG Zephyrus G14 GA401 и ROG Zephyrus G15 GA503

В 2020 году ноутбуки ROG стали одними из самых популярных в игровом сегменте рынка. Такого успеха мы добились во многом благодаря двум моделям: ROG Zephyrus G14 и Zephyrus G15. Компактные ноутбуки с диагоналями 14 и 15 дюймов предлагают высокую игровую производительность по разумной цене. В 2021 году мы кардинально обновили модель Zephyrus G15 и улучшили G14.

Ноутбук ROG Zephyrus G15 GA503 полностью переработан и получил новую внешность. На внешней стороне крышки появились 8279 перфорированных точек. Между блоками с точками нанесена призматическая плёнка, красиво переливающаяся на свету.

Рабочая область ноутбука покрыта 4 слоями экологически-чистой краски и дополнена покрытием Soft-Touch. Тачпад стал на 20% больше по сравнению с прошлым поколением.

Также ROG Zephyrus G15 оснащён массивом 3D-микрофонов, которые захватывают звук как с внутренней стороны крышки, так и с внешней. Новая система пригодится во время конференций, когда вокруг ноутбука или перед ним сидит несколько человек. Аудиосистема G15 насчитывает 6 динамиков с двойным сабвуфером. Система шумоподавления AI Noise Cancelation также поддерживается.

Начинка ноутбука зависит от модификации. Топовый конфиг Zephyrus G15 оснащается процессором AMD Ryzen 9 5900HS и графикой NVIDIA GeForce RTX 3080 для ноутбуков. Такого набора хватит для всех современных игр.

Матрица одинакова для всех вариантов ROG Zephyrus G15. Это панель класса IPS с разрешением 2560х1440 пикселей, сертификацией Pantone и полным покрытием цветового диапазона DCI-P3. Частота обновления экрана составляет 165 Гц, а время отклика 3 мс. Также заявлена поддержка технологии FreeSync, с помощью которой частота обновления дисплея синхронизируется с FPS видеокарты.

Вторая модель, ROG Zephyrus G14, изменилась только внутри. Теперь за производительность компактного 14-дюймового игрового ноутбука отвечает процессор AMD Ryzen 9 5900HS и мобильная графика NVIDIA GeForce RTX 3060 для ноутбуков. Также у ноутбука появился виртуальный питомец Omni, которого можно увидеть на рабочем столе.

ROG Flow X13

Последняя новинка, показанная на презентации Republic of Gamers, может перевернуть представление о компактных ноутбуках и рабочих станциях. Это первый в нашей линейке 13-дюймовый игровой ноутбук-трансформер ROG Flow X13.

За производительность Flow X13 отвечает 8-ядерный процессор AMD Ryzen 9 5980HS и видеокарта NVIDIA GeForce GTX 1650. Но это лишь половина! Специально для ноутбука доступна компактная док-станция XG Mobile с дискретной видеокартой RTX 3080!

Обычно, внешняя графика подключается через Thunderbolt, что вызывает задержки в работе десктопной видеокарты и ведёт к снижению производительности и, как следствие, падению FPS. Для того, чтобы избежать бутылочного горлышка, у док-станции Flow X13 используется собственный, проприетарный интерфейс, благодаря которому графика подключается напрямую к восьми процессорным линиям PCIe.

Док-станция оснащена четырьмя разъёмами USB, карт-ридером и сетевым портом Ethernet. Для подключения мониторов также доступны HDMI и DisplayPort. Наконец, внутри дока установлен блок питания на 280 Вт, который обеспечит питанием не только видеокарту, но и сам ноутбук. Поэтому для подключения внешней графики и зарядки ROG Flow X13 потребуется всего один кабель.

Соотношение сторон сенсорного дисплея составляет 16:10, разрешение экрана у модификации ROG Flow X13 с 4К-матрицей составляет 3840x2400 пикселей, а у варианта с матрицей Full HD 1920х1200 пикселей с частотой обновления 120 Гц. Экран ноутбука закрыт защитным стеклом Gorilla Glass.

Это настоящая революция в области гейминга. Отныне, вам не нужно выбирать между компактным ноутбуком и игровым компьютером. Все это доступно в одном устройстве, которое может быть и мощной игровой станцией, и компактным ноутбуком одновременно. И главное, все ваши файлы всегда под рукой, так как нет смены устройств.

Презентация Опережая время ASUS на CES 2021

На следующий день после презентации Republic of Gamers, прошло онлайн-мероприятие компании ASUS, под названием Опережая время. Во время трансляции были представлены новые устройства для бизнеса, учёбы и создания контента.

ASUS ExpertBook B9 B9400

В 2020 году поход к удаленной работе поменялся просто кардинально. Слово удаленка прочно вошло в нашу жизнь, и, кажется, уходить не планирует. Все это коренным образом меняет требование к организации рабочего места. Теперь в приоритете стала мобильность и вместе с ней возможность работы откуда угодно. Для таких задач у нас есть бизнес-ноутбук ASUS ExpertBook B9 B9400, который получил сертификацию Intel Evo.

Для людей, которым часто приходится работать в дороге, габариты и вес ноутбука крайне важны. ASUS ExpertBook B9400 стал самым лёгким 14-дюймовым бизнес-ноутбуком в мире. Его вес может достигать 880 грамм (с батареей на 33 Втч) или 1005 грамм с аккумулятором на 66 Втч. Хотя стоит отметить, что версия с АКБ на 33 Втч в Россию не поставляется автономность для наших пользователей оказалась важнее экономии 120 граммов веса.

Ноутбук ExpertBook B9400 прошёл дополнительные испытания на надёжность в соответствии с методикой тестирования MIL-STD-810H, используемой для оборудования армии США. Для того, чтобы владелец ноутбука смог работать откуда удобно, ExpertBook B9400 оснащён новой системой шумоподавления на базе искусственного интеллекта - Two Way AI Noise Canceling, которая будет отделять и удалять шумы. За производительность ASUS ExpertBook B9 отвечает один из процессоров Intel Core 11-го поколения с новой графикой Intel Iris Xe.

ASUS Chromebook CX9 CX9400 и ASUS ChromeBook Flip CX5 CX5500

Для тех, кто предпочитает облачные приложения для ведения бизнеса, например постоянно работает с сервисами Google, мы выпустили особую версию Хромбука. Представляем ASUS Chromebook CX9 CX9400. Это премиальное устройство с соответствующей начинкой. Во флагманской версии используется 4-ядерный процессор Intel Core i7-1165G7 c графикой Intel Iris Xe, известной своей высокой производительностью даже в играх.

ASUS ChromeBook Flip CX5 второй новый хромбук, выполненный в форм-факторе трансформера, с уникальным дизайном. Крышка окрашена в белый цвет, а её покрытие на ощупь напоминает керамику. Рабочая область окрашена в чёрный обсидиановый цвет, с бархатным на ощупь покрытием.

За производительность ChromeBook Flip CX5 отвечает один из процессоров Intel Core 11-го поколения, а сам ноутбук может стать игровым при помощи облачных сервисов Google Stadia и GeForce Now.

Ноутбук для учёбы ASUS BR1100

Трудно представить ученика, который сегодня не пользуется компьютером для обучения. Представляем ASUS BR1100, созданный специально для самых юных пользователей. Ноутбук будет выпускаться в двух форм-факторах: классическом и в варианте ноутбука-трансформера.

Прочный корпус ASUS BR1100 выдержит ежедневные удары. Благодаря резиновому бамперу, ноутбук не боится падения с высоты до 120 сантиметров. Клавиатура BR1100 также защищена от попадания влаги, чтобы пролитая вода не вывела ноутбук из строя.

Для особо требовательных пользователей, некоторые модификации ASUS BR1100 получат встроенные 4G-модемы. А для повышения конфиденциальности, веб-камеры всех ноутбуков оснащены защитными шторками. Также поддерживается автоматическое улучшение качества картинки с веб-камеры и система интеллектуального шумоподавления.

Строение у ноутбука модульное. Поэтому системные администраторы смогут быстро обновлять или менять модули BR1100.

ASUS VivoBook S14 S435

Ноутбуки серии VivoBook созданы для тех, кто ценит самовыражение. Крышки VivoBook всегда выполняются в ярких цветах, а в комплекте с ноутбуками поставляется набор наклеек. Новое поколение VivoBook S14 стало самым лёгким в истории линейки, к тому же, модель VivoBook S14 S435 оказалась на 11% меньше своего предшественника предыдущего поколения, а время автономной работы достигает 17 часов.

Уменьшение габаритов не сказалось на производительности. Все модели VivoBook с процессорами Intel Core 11-го поколения, поддерживают технологию ASUS Intelligent Performance Technology (AIPT).

Новая технология позволяет пользователю гибко регулировать производительность процессора в трёх режимах: производительность, баланс и тишина. При выборе любого режима меняется теплопакет процессора и скорость работы вентиляторов. Например, в производительном режиме теплопакет повышается с 15 Вт до 28 Вт, что даёт прирост производительности до 40%.

ASUS ZenBook Pro Duo 15 OLED UX582

С момента выпуска ASUS ZenBook Pro Duo UX581 прошло 18 месяцев. За это время мы получили много позитивных отзывов от наших пользователей и предложений по улучшению. Мы внимательно прислушивались к вашему мнению, чтобы сделать следующую модель, UX582 ещё лучше.

В новой модели второй экран наклоняется к пользователю при открытии крышки ноутбука. Также это помогло нам кардинально изменить систему охлаждения. В новом ASUS ZenBook Pro Duo 15 OLED используется Active Aerodynamic System Plus. Система охлаждения с похожим принципом работы применяется в игровом ноутбуке ROG Zephyrus Duo 15. Благодаря ей, а также оптимизациям вентиляторов, нашим инженерам удалось увеличить воздушный поток на 36%.

Инновационная система охлаждения позволила установить в UX582 мощные комплектующие: процессор Intel Core i9 и видеокарту NVIDIA GeForce RTX 3070 для ноутбуков, что выводит быстродействие ASUS ZenBook Pro на новый уровень. Максимальный объём оперативной памяти составляет 32 Гбайт, а SSD-накопителя 1 Тбайт.

Вместе с конструкцией второго экрана ScreenPad Plus, изменился его софт. Теперь работать с утилитой ScreenXpert 2, стало ещё проще. Окна можно перемещать с основного экрана на дополнительный (и обратно) одним быстрым жестом пальца или стилуса, а для основных приложений Adobe создана отдельная панель управления.

При запуске Adobe Photoshop, Premiere Pro, After Effects или Lightroom classic, на ScreenPad Plus появится новая панель управления. На ней расположены основные команды, которые используются в запущенном приложении. Больше не придётся выбирать мышкой команду в программе. Достаточно настроить панель управления так, как будет удобно вам.

Во всех модификациях ASUS UX582 используется сенсорный OLED-экран с разрешением 4К и максимальной яркостью в 440 нит. Благодаря технологии OLED, каждый пиксель является собственным источником света, поэтому изображение на дисплее будет ярким, сочным и без засветов. Это подтверждает сертификация Pantone и охват цветового пространства DCI-P3 в 100%. Также нам удалось снизить яркость синего цвета, без ущерба для значения ошибки цветопередачи DeltaE. Второй экран, как и ранее, также обладает разрешением 4К.

ASUS ZenBook Duo 14 UX482

ASUS ZenBook Duo 14 можно назвать младшим братом ASUS UX582. Новый 14-дюймовый ноутбук также оснащён поднимающимся вторым экраном, системой охлаждения Active Aerodynamic System Plus и новым железом.

За быстродействие ASUS UX482 отвечает один из процессоров Intel Core 11-го поколения, а благодаря использованию системы охлаждения AAS+ удалось увеличить воздушные потоки на 49%, что позволило вывести производительность процессора на новый уровень.

За работу с графикой у UX482 отвечает либо процессорное видеоядро Intel Iris Xe, либо дискретная видеокарта NVIDIA GeForce MX450 в зависимости от модификации. Объём оперативной памяти также зависит от версии ноутбука, и может достигать 32 Гбайт LPGDDR4X с тактовой частотой 4266 МГц. Максимальный объём SSD-накопителя составляет 1 Тбайт.

ASUS ProArt Display PA148CTV

Следующей новинкой, показанной на CES 2021, стал портативный дисплей ASUS ProArt Display PA148CTV, который мы разработали специально для контент-мейкеров. Матрица новинки относится к классу IPS, она на 100% покрывает цветовые пространства sRGB и Rec. 709, её показатель ошибки цветопередачи DeltaE составляет менее двух единиц.

Новый PA148CTV можно использовать во время съёмок. У монитора есть отдельное отверстие для штатива, а подключить камеру можно через MicroHDMI.

На этом особенности новинки не заканчиваются. На обратной стороне находится колёсико ASUS Dial. С его помощью можно работать в приложениях Adobe Photoshop, Premiere Pro, After Effects и Lightroom Classic. А в приложениях Windows, колёсико ASUS Dial ведёт себя также, как и инструмент Surface Dial от Microsoft.

Однако, это не все возможности новинки. Софт PA148CTV поддерживает панели управления. При запуске приложений Adobe, мини-дисплей можно использовать в роли полноценной панели управления как и дополнительный экран у новых ZenBook Duo. На его экран можно вывести все инструменты и регуляторы, которые используются в Adobe Photoshop, Premiere Pro, After Effects и Lightroom Classic. Выбор и расположение инструментов зависят от предпочтений пользователя.

ASUS ZenBeam Latte L1

Во время презентации обновилась линейка проекторов ZenBeam. К ней добавилась модель ASUS ZenBeam Latte L1, которая своими формами и габаритами напоминает стакан для кофе. Миниатюрный проектор обеспечивает проекцию диагональю до 120 дюймов при яркости в 300 люмен. Благодаря встроенному аккумулятору, время автономной работы Latte L3 составляет 3 часа при беспроводном воспроизведении видео со смартфона.

Также ASUS ZenBeam Latte L1 можно использовать в качестве компактной колонки, тогда одного заряда аккумулятора устройства хватит на срок до 12 часов. Корпус, обтянутый тканью, положительно влияет на пропускание звука. А если вам захочется посмотреть видео с YouTube или других популярных стриминговых сервисов, то смартфон не понадобится у проектора есть встроенная поддержка Aptoide TV.

ASUS TUF Dash F15

Серия игровых ноутбуков ASUS TUF Dash пополнилась новой моделью - ASUS TUF Dash F15. Новинка выпускается в двух цветах: сером и белом. Также совместно с выпуском Dash F15 мы обновили логотип TUF Gaming, чтобы лучше соответствовать аудитории продукта и общему духу TUF.

Кроме изменившегося дизайна TUF Dash F15 стал компактнее своих предшественников. Его корпус стал на 13% меньше и на 300 грамм легче, чем у схожих игровых ноутбуков TUF предыдущего поколения. За производительность топовой версии отвечает процессор Intel Core i7-11375H c теплопакетом 35 Вт и дискретная графика NVIDIA GeForce RTX 3070 для ноутбуков.

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

Впервые выставка CES 2021 проходила в онлайн-формате, но от этого не стала менее интересной. Мы познакомили вас с огромным количеством новых продуктов, каждый из которых нацелен на высокую производительность и комфорт в эксплуатации.

Какой продукт понравился больше всего именно вам? Давайте обсудим в комментариях.

Подробнее..

Вся правда о TGP в видеокартах NVIDIA GeForce RTX 30 для ноутбуков

08.02.2021 12:21:23 | Автор: admin

Привет, Хабр!

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

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

Прежде чем переходить к техническим характеристикам мобильных видеокарт GeForce RTX 30-й серии, стоит вспомнить, с чего всё началось. Откуда появилась технология Max-Q, для чего она создавалась и какие преимущества она предоставила пользователям. Давайте вспомним, с чего всё начиналось.

С момента своего появления мобильная графика отставала от аналогичных по названию десктопных версий. В начале нулевых техпроцесс всё ещё измерялся в десятках и сотнях нанометров, и несмотря на то, что топовая десктопная графика того времени не требовала двух- или трёх-слотовых систем охлаждения, уместить её в ноутбуках не представлялось возможным. Ведь остальные электронные компоненты также были большими и требовали больше места для размещения на материнской плате. К тому же системы охлаждения того времени были не так эффективны, как нынешние. В итоге NVIDIA снижала мощность мобильных видеокарт, чтобы сделать возможной их установку в ноутбуки. Даже драйвера для мобильных и десктопных видеокарт в то время различались и выпускались строго по отдельности.

ASUS V8200 DLX (NVIDIA GeForce3), 2002 годASUS V8200 DLX (NVIDIA GeForce3), 2002 год

Чтобы пользователи лучше понимали, какая видеокарта устанавливается в ноутбук, мобильная графика обозначалась иначе, чем десктопная. Когда названия серий состояли из одной цифры, в названии мобильной графики появилось дополнительное слово Go. Например, видеокарта NVIDIA GeForce 4 MX 460 предназначалась для компьютеров, а NVIDIA GeForce 4 Go 460 для ноутбуков.

ASUS ENGT220 (NVIDIA GeForce GT220), 2009 годASUS ENGT220 (NVIDIA GeForce GT220), 2009 год

Ранее снижение производительности и тепловыделения графики выражалось в понижении тактовых частот. Для сравнения возьмём всё ту же десктопную NVIDIA GeForce 4 MX460 и мобильную GeForce 4 Go 460. Строение видеоядра у двух видеокарт одинаковое: 2 пиксельных конвейера, 4 текстурных блока (TMU) и два блока растеризации (ROP). Изменились только частоты - десктопная GeForce 4 MX 460 работала с частотой 300 МГц, а мобильная GeForce4 Go 460 оказалась на 50 МГц медленнее.

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

В 2009 году NVIDIA изменила наименования линеек своих видеокарт, перейдя на сотые серии, ситуация повторилась - к мобильным видеокартам добавилась буква M. Просто взглянув на модель графики, можно сразу понять, что NVIDIA GeForce GTX 760 создана для стационарных компьютеров, а GeForce GTX 760M для ноутбуков. Частоты у мобильной графики также были ниже, а в GPU была отключена часть шейдерных процессоров, которые со временем преобразовались в CUDA-ядра благодаря унифицированной архитектуре.

Разница в производительности десктопных и мобильных видеокарт сохранялась до 2016 года, пока NVIDIA не представила архитектуру Pascal и видеокарты GeForce GTX 10-й серии. На этом этапе NVIDIA смогла свести к минимуму разницу между десктопными и мобильными GPU. Для обозначения мобильных видеокарт больше не требовались дополнительная буква, индекс или слово.

У NVIDIA GeForce GTX 1080 и GTX 1060, созданных для ноутбуков и компьютеров, стало одинаковое количество ядер CUDA. Даже у мобильной GeForce GTX 1070 оказалось чуть больше CUDA-ядер по сравнению с её десктопным аналогом. Разумеется, частоты у мобильных и десктопных видеокарт немного различались, но разрыв между мобильной и полноценной десктопной графикой в рамках одного поколения стал не настолько большим и заметным, как это было ранее. А в зависимости от эффективности системы охлаждения, разницы могло и вовсе не быть, как, например, в случае с ноутбуком ROG G703.

Появление архитектуры Pascal стало прорывом для тех, кто предпочитал играть на ноутбуках которые, в отличии от компьютера, всегда можно взять с собой. Ноутбуки с видеокартами GeForce GTX 10-й серии легко справлялись с играми того времени.

Появление технологии Max-Q

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

Для примера возьмём ROG G703, высокую производительность которого обеспечивал 4-ядерный процессор Intel Core i7-7820HK в паре с видеокартой NVIDIA GeForce GTX 1080. Топовая конфигурация для своего времени! Однако, при толщине в 51 мм и весе в 4,7 кг ROG G703 совершенно точно нельзя назвать ноутбуком, который можно носить с собой на работу каждый день. Скорее, это полноценная замена десктопа, которую при необходимости можно легко перенести в другое место. Главное, не забыть с собой огромный блок питания :).

Пользователям хотелось получить не только мощные, но и тонкие игровые ноутбуки, а производители стремились удовлетворить потребности. Все-таки, ноутбук ассоциируется с компактностью и мобильностью. К тому же, игровые ноутбуки многие используют для работы мощная начинка одинаково хорошо справляется как с играми, так и с большинством тяжёлых задач, вроде сложных расчётов, обработки фото, видеомонтажа и так далее. Но это требовало создания более энергоэффективных видеокарт, которыми в будущем и стали линейки под названием NVIDIA Max-Q.

В аэродинамике точкой Max-Q называют момент максимальной нагрузки на ракету в атмосфере, который особенно учитывается конструкторами. Компания NVIDIA применила похожий подход при разработке серии видеокарт Max-Q, которые работают на пределе своей энергоэффективности.

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

Зависимость между потребляемой мощностью и ростом производительности нелинейная. При увеличении потребляемой мощности прирост производительности сперва будет заметным, линейным, а потом, после прохождения точки максимальной эффективности, прирост производительности (который не стоит путать с самой производительностью) замедляется. Проще говоря, видеокарта NVIDIA GeForce GTX 1080 будет быстрее GTX 1080 Max-Q, но при этом потребует улучшенной системы охлаждения и станет потреблять больше энергии.

В результате в 2017 году на рынке появилось два типа ноутбуков: с классической графикой GTX 10-й серии и с графикой Max-Q. Появление линейки Max-Q позволило выпускать тонкие и лёгкие игровые модели, чего не удавалось добиться ранее. Для Max-Q не требуется крупногабаритная система охлаждения. При этом, видеокарты Max-Q остались производительными. Например, топовая версия GeForce GTX 1080 Max-Q оказалась почти в 2 раза быстрее обычной мобильной GeForce GTX 1060.

Благодаря появлению видеокарт Max-Q, мы смогли выпустить тонкие, лёгкие и при этом мощные игровые ноутбуки. Первой моделью стал 15-дюймовый ROG Zephyrus GX501. В ноутбуке толщиной 17,9 мм и весом 2,26 кг была установлена графика NVIDIA GeForce GTX 1080 в дизайне Max-Q в паре с 4-ядерным процессором Intel Core i7-7700HQ. Для рынка ноутбуков 2017 года это стало революцией.

Различия между TDP и TGP

Долгое время энергопотребление видеокарт обозначалось аббревиатурой TDP. Расшифровать эти три буквы можно как Thermal Design Point или Thermal Design Parameter. Значение TDP обозначало, сколько Ватт тепла нужно отводить от кристалла GPU, и не указывало общее энергопотребление видеокарты. Параметр TGP напротив указывает, сколько Ватт потребляет вся видеокарта целиком.

Видеопамять и другие электронные компоненты также потребляют свою часть электричества во время работы. Судя по таблице, реальное энергопотребление видеокарт оказалось заметно выше, чем тепловыделения GPU. Например, у GeForce RTX 2080 разнице между TDP и TGP составляет 67 Ватт, а у RTX 2070 - 55 Вт.

Графика NVIDIA GeForce RTX 30-й серии в ноутбуках ASUS и ROG

За время существования графики NVIDIA GeForce RTX 10-й и 20-й серий, мы успели привыкнуть к тому, что видеокарты для ноутбуков и десктопов стали практически одинаковыми. Однако, выход мобильных видеокарт нового поколения на архитектуре Ampere снова поменял правила игры.

Десктопные видеокарты NVIDIA GeForce RTX 30-й серии оказались не только производительными, но и требовательными к питанию. Согласно официальному сайту NVIDIA, энергопотребление GeForce RTX 3080 составляет 320 Вт, когда как GeForce RTX 2080 Super потребляла 250 Вт. При этом, мы имеем в виду энергопотребление, указанное без заводского разгона и самых пиковых значений.

Разница в энергопотреблении у старого и нового поколения видеокарт оказалась заметной. Впервые видеокарта NVIDIA с одним GPU потребляет более 300 Вт. Учитывая высокое энергопотребление и впечатляющую производительность графики, перед инженерами NVIDIA появилась сложная задача по оптимизации десктопной графики к мобильным реалиям. Если системы охлаждения ASUS и Republic of Gamers легко могут отвести от десктопной видеокарты всё лишнее тепло, то в случае с ноутбуками мы ограничены толщиной корпуса, которая не позволяет установить СО толщиной несколько сантиметров.

ROG Strix GeForce RTX 3080ROG Strix GeForce RTX 3080

В результате, инженерам NVIDIA пришлось вынужденно вернуться к старым методикам отключению CUDA-ядер. Также при разработке ноутбука стало возможным ограничивать TGP видеокарты как в большую, так и в меньшую стороны. Это означает, что на этапах проектирования и производства можно выставить максимальное энергопотребление согласно возможностям системы охлаждения. В результате на рынке появились ноутбуки с одинаковым названием видеокарт, но разной производительностью, что закономерно привело в замешательство многих пользователей.

Мы всегда открыто рассказываем о компонентах своих игровых ноутбуков. Чтобы у наших пользователей не осталось вопроса, какая именно графика используется в заинтересовавшем ноутбуке, мы публикуем таблицу с данными TGP и рабочими частотами для каждой отдельной модели. Скоро эти данные станут доступны на нашем официальном сайте в разделе технических характеристик на страницах новых ноутбуков.

В таблице указано как энергопотребление видеокарты (TGP), так и дополнительная мощность, потребляемая в режиме Dynamic Boost. Вместе с мощностью в таблице указана частота Boost Clock. Стоит отметить, что это скорее базовые частоты, на которых будет работать GPU. Реальная максимальная частота окажется выше, она зависит от системы охлаждения ноутбука и температуры в конкретный момент.

Пример увеличения тактовой частоты GPU у ноутбука Zephyrus Duo 15 SE GX551Пример увеличения тактовой частоты GPU у ноутбука Zephyrus Duo 15 SE GX551

Теперь разберёмся с новой мобильной графикой на примере. Рассмотрим пять 15-дюймовых ноутбуков с графикой NVIDIA GeForce RTX 3070: ROG Zephyrus Duo 15 SE, ROG Zephyrus G15, ROG Strix SCAR 15, TUF Dash F15 и TUF A15. Для того, чтобы сравнение стало наглядным, поместим ноутбуки в отдельную таблицу.

В сравнении наглядно видно, что производительная система охлаждения Active Aerodynamic System, которая используется в ROG Zephyrus Duo 15 SE, может отвести 130 Вт тепла от видеокарты. Основная мощность в 115 Вт приходится на стандартное энергопотребление (TGP), и ещё 15 Вт на Dynamic Boost. Если система решит, что возможностей системы охлаждения ноутбука хватит для увеличения нагрузки на графику, то, благодаря GPU Boost, видеокарта получит дополнительные 15 Вт мощности и сможет работать быстрее. В результате её энергопотребление вырастет до 130 Вт.

Системы охлаждения остальных ноутбуков ROG Zephyrus G15, TUF Dash F15 и TUF A15, сделаны по классическому принципу. В них у видеокарт был снижен параметр TGP, чтобы система охлаждения справилась со своей задачей. Вместе с TGP закономерно снизились частоты примерно на 16%, но при этом энергопотребление платы снизилось на 30%.

Заключение

Мы делаем всё возможное, чтобы предложить нашим пользователям полную и разнообразную линейку ноутбуков с разными форм-факторами, производительностью и ценой. Надеемся, что опубликованная информация по энергопотреблению мобильных видеокарт будет для вас полезной, и поможет лучше разобраться в современном рынке игровых ноутбуков, и понять различия в мобильной графике нового поколения в ноутбуках ASUS и Republic of Gamers.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru