Задать вопрос
Ответы пользователя по тегу JavaScript
  • Как перезапустить полностью pixijs?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    GL_INVALID_VALUE: Offset overflows texture dimensions.

    Ошибки такого рода в мире WebGL обычно связаны с тем фактом, что мы пытаемся использовать текстуру, но у нас левые ее размеры, и мы, например, пытаемся получать из нее пиксели за ее границами. Искать проблему нужно вокруг этого факта. На сайте PixiJS можно найти описание основ работы с текстурами, и там сказано, что они кешируются. Если мы делаем Texture.from с тем же источником, то получаем не новую текстуру, а ту, которая уже была. Но в вашем коде где-то по дороге меняются размеры. А сама текстура, сам буфер с пикселями, получается старый, закешированный. Это, вполне вероятно, и вызывает несоответствие. Решением должно быть использование метода destroy() у текстуры, чтобы ее уничтожить с концами при переинициализации. Альтернативно у конструктора Texture.from есть второй параметр skipCache, который по идее даст схожий результат.
    Ответ написан
    1 комментарий
  • Как заменить под-зависимость на локальную копию?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    В package.json есть раздел overrides как раз для таких модификаций зависимостей зависимостей. В примерах в документации там почему-то акцент сделан только на версии пакетов, но можно и полностью заменить пакет на свой, если указать не версию, а локальный путь к нему.
    Ответ написан
  • Реально ли сделать лепестковую диаграмму с градиентом?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    В CSS и SVG есть какие-то градиенты и фильтры, из которых можно что-то такое плюс-минус собрать. Ну и вариации clip-path или масок, чтобы обрезать. Но. Логика формирования градиентов там своя, и она не всегда хорошо подходит под идею, как оно должно выглядеть. Иногда все мешается очень грязно, или какие-то полосы появляются. Не идеально там все. Много костылей нужно подставлять. Если будет нужна какая-то совсем особая интерполяция - то от количества костылей и подпорок тошно станет. Один раз подогнать можно, но с автоматизацией могут возникнуть сложности. А задача построения диаграмм почти всегда требует автоматизации. Это может быть не совсем очевидно с самого начала, но усугубляется там все очень быстро. Так что может иметь смысл сразу брать canvas и делать свою логику под свои хотелки. Там мы нарисовать можем что угодно, мы уже не зависим от браузера и его представлений о градиентах. Это более сложное решение в своей основе, чем подбор градиентов в SVG, но более перспективное в плане его дальнейшего развития.

    Ответ написан
    1 комментарий
  • Почему функция-конструктор срабатывает без `new`, хотя, согласно документации, не должна?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    У вас примеры с new и без new не эквивалентны. Вы просто посмотрите, что там на самом деле находится в получаемых переменных:

    function Foo(arg) {
        this.bar = function() {
            return arg;
        };
    
        return this.bar();
    }
    
    const notfoo = Foo('not foo');
    console.log(notfoo); // "not foo", т.е. notfoo - это не новый Foo, это строка текста.
    console.log(notfoo.bar); // undefined, что логично, у стандартной строки никакого bar нет.
    
    const foo = new Foo('foo');
    console.log(foo); // [object Object], т.е. вот это - настоящий новый Foo.
    console.log(foo.bar); // function() { ... }, и метод bar в нем есть.
    console.log(foo.bar()); // "foo"
    Ответ написан
    5 комментариев
  • Почему не добавляется класс следующему элементу после 2 клика?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    Метод querySelector возвращает первый элемент, который соответствует селектору. В вашем конкретном случае querySelector('.btn') - это всегда первая кнопка. Тут вопрос не в количестве кликов, а в том, что логика действий завязана на первую кнопку.
    Ответ написан
    Комментировать
  • Как реализована анимация SVG элементов (персонажей) в web app?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    Могу предположить что что-то на подобии gsap

    Если рассматривать эту задачу в целом, без привязки к конкретному сайту, то это задача по созданию мультиков, в больших количествах, на потоке, в рамках сформированной дизайнерской системы. Делать это за счет фронтендеров - такая себе идея. Сложно всех синхронизировать, очень много накладных расходов. Это будет реально дорогая разработка. И разработчики нужны очень прошаренные по части анимаций, чтобы они были со всей командой дизайнеров на одной волне. Таких днем с огнем не найдешь. Более простой и дешевый подход состоит в том, чтобы этим всем занимались моушен-дизайнеры в рамках экосистемы Lottie. А со стороны разработки мы только интегрировали готовые сценки в сайт или приложение. В последние годы обычно все так и делают. Наш стек здесь не имеет значения, равно как и умения разработчиков.
    Ответ написан
    5 комментариев
  • Как повторить такую же анимацию?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    Для начала можно посмотреть в их исходники. Беглый просмотр кода показывает основной план действий:

    • Создать плоскость с кастомным материалом. Вершинный шейдер стандартный нейтральный, который ничего необычного не делает, только сохраняет координаты UV, чтобы их во фрагментном использовать. Фрагментный будет содержать в себе всю логику. Это частенько так делается в 2D-эффектах.
    • Во фрагментный шейдер передать две текстуры. Одна обычная, для фона. Вторая - карта смещений для пикселей. Displacement map по-нашему. Берем пиксели из фона, смещаем по данным из карты смещений - получаем результат.
    • Нарисовать текстуру для фона. В их случае она делается из кадров видео, т.е. вот этот бултыхающийся градиент на фоне в их случае заранее заготовлен. И, к слову, видно, что он шакалится. Но с точки зрения производительности видео тут - это хорошая идея. Генерирование клякс-градиентов - требовательная в вычислительном плане задача.
    • Нарисовать displacement map по какой-то логике, завязанной на положение мыши. Тут большой простор для экспериментов. В их случае они используют отдельную сцену с кучей объектов, у которых меняются расположение и прозрачность в зависимости от положения мыши и просто со временем. Там много магических чисел. Вероятно все подбиралось наугад. Как это обычно и происходит. И потом они рендерят эту сцену в текстуру, которая передается в уже упомянутый шейдер. Можно было бы на 2D канвасе ее рисовать. Но с трехмерной сценой в таких задачах проще работать, хотя это поначалу кажется контринтуитивным.

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

    От этого вполне можно оттолкнуться и сделать что-то подобное в рамках своих инструментов/требований/дизайнов.
    Ответ написан
    Комментировать
  • Как сделать плавную анимацию при смене значений через js?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Вероятно вам нужен обычный transition, он будет срабатывать каждый раз, когда значения будут меняться:

    .items {
        .single-chart {
            .circular-chart {
                .circle {
                    /* animation: progress 1s ease-out forwards; */
                    transition: stroke-dasharray 1s ease-out;
                }
            }
        }
    }
    Ответ написан
    1 комментарий
  • Как сделать так, чтобы prettier не переносил каждый метод на новую строчку в JS?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    Prettier использует определенную логику для определения ситуаций, когда такие вещи должны быть разделены. Ее нельзя выключить. Этот инструмент в целом имеет очень мало настроек, он изначально очень строгий и нацелен на то, чтобы навязать свой стиль форматирования везде. В этом его философия. Не нужно спорить, как лучше форматировать. Робот все решит за нас.

    Можно игнорировать какие-то конкретные штуки с помощью комментария // prettier-ignore. Но нужно ли?
    Ответ написан
    1 комментарий
  • Как сделать два canvas для одной сцены в three.js?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    Точно такая же сцена требуется в другом месте, и не хотелось бы дублировать код и создавать ту же сцену для другого канвас

    Сцену дублировать не обязательно. WebGLRenderer не умеет рендерить в несколько мест одновременно, но можно иметь одну сцену и много рендереров, каждый из которых будет рендерить ее в свой канвас. Это работает.

    Если посмотреть с другой стороны, то возможно, что вам не нужны два канваса. Это может звучать странно, но тем не менее. Пользователь же все равно видит только один экран информации. Можно иметь один канвас на весь экран, и в нем рендерить сцены в какие-то его участки. Там есть такой функционал у рендерера, называется "ножницы" (scissor). Его можно использовать как раз для таких задач. Есть хороший пример в документации.

    Но если делать именно 100% дублирование, то оба этих варианта будут не самыми толковыми с точки зрения производительности. В лоб скопировать уже готовое содержимое канваса в другой через drawImage должно быть проще, чем рендерить всю сцену еще раз. Поэтому решение, которое пришло вам в голову - очень даже ничего в текущем контексте. Хотя и выглядит топорно.
    Ответ написан
    1 комментарий
  • Как увеличить производительность 2д- игр?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    если я перейду на визуализатор pixi то будет ли существенное повышение производительности?

    Matter использует 2D канвас (если мы говорим про их стандартный рендерер). Pixi - WebGL. Ваш вопрос получается не про Pixi, как библиотеку, а про разницу технологий.

    Когда-то было такое время, что 2D-канвас рендерился полностью на CPU, и тогда разница между ним и WebGL была в первую очередь обусловлена этим фактом. WebGL - это более низкоуровневый интерфейс с доступом к видеокарте. Много ядер, процессы хорошо распараллеливаются, при наличии прямых рук и понимания основ компьютерной графики все рендерится быстрее. Но в наше время и 2D-канвасы ускоряются видеокартой. Если очень грубо говорить, то сейчас 2D канвас - это тот же GL-канвас, но с более высокоуровневой обвязкой сверху. Чисто для удобства. Можно сказать, что разница в алгоритмах самого рендеринга с годами сводится к нулю, остается лишь разница в обвязке. Изначальная высокоуровневая структура вокруг 2D-канваса с кучей условно ненужного в конкретных случаях функционала не оптимизируются так эффективно, как бы нам хотелось. Она не умеет предсказывать наши намерения. Из-за этого переход от 2D к WebGL может дать прирост производительности. Но не столько за счет самого рендеринга, сколько за счет более умного переиспользования ресурсов и избавления от всех ненужных в конкретных случаях операций. Так что в целом идея взять двумерный рендерер на WebGL и делать в нем только то, что требуется, и ничего лишнего - все еще хорошая. Плюс у него будет сразу задел на использование своих кастомных шейдеров, что открывает целый мир визуальных эффектов, неподвластных 2D-канвасу.

    Но не стоит ждать чуда - уменьшение времени обработки одного среднестатистического игрового кадра в 2-3 раза можно будет считать хорошим результатом. Тесты, в которых люди меряют разницу в десятки раз, обычно завязаны на какие-то узкие случаи с переиспользованием ресурсов. Далеко не факт, что это будет ваш случай. Так что если у вас там что-то конкретно тормозит - может быть будет больше пользы от оптимизации узких мест в текущей логике, чем от машинального переписывания всего на других инструментах.
    Ответ написан
    Комментировать
  • Зачем нужен блок инструкций без управляющей инструкции?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    В изначальных исходниках там TypeScript. Вы смотрите уже скомпилированный код. В исходниках местами все обернуто в разные условия, завязанные на__DEV__:
    export function setExtraStackFrame(stack: null | string): void {
      if (__DEV__) {
        currentExtraStackFrame = stack;
      }
    }

    Когда происходила сборка кода, который вы смотрите, вероятно __DEV__ был true, условие было опущено, т.к. оно всегда выполняется, а скобки остались как артефакт. Скорее всего транспилятор TS не проверяет весь контекст, и чтобы ничего не сломать случайно, оставляет скобки на своих местах.
    Ответ написан
    2 комментария
  • Насколько опасно использование конструктора Function?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    И конструктор Function, и eval, в теории позволяют без каких-либо проверок выполнить код, который мы не контролируем. Мы не можем проверить его на этапе разработки и не можем быть уверенными, что у пользователя будет выполняться именно он. Он прилетает откуда-то. И весь вопрос в доверии к источнику. Если кто-то (пользователи, контент-редакторы, или кто там еще может быть) может влиять на то, что прилетит - возникает простор для потенциальных атак на пользователей системы. Кто-то что-то куда-то написал, скопипастил, а потом это что-то у пользователя выполнилось. И кто знает, что оно с данными пользователя сделает. Тут каждый оценивает риски сам, но в общем случае выполнять непроверенный код действительно не рекомендуется.

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

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    Никакой Three.js тут не нужен. Ну то есть, конечно, никто не мешает сделать все это на WebGL и прикрутить здоровенный фреймворк сверху, но все же это будет слегка избыточным решением в большинстве случаев. Такое можно аргументировать только если весь сайт изначально так и делается на WebGL и это просто "один из" эффектов, которые туда нужно интегрировать.

    В 99% остальных случаев подобные штуки делаются одной svg-картинкой, одним path, который рисуется в зависимости от положения мышки и размеров контейнера. Немного школьной геометрии, ограничение диапазона возможных смещений всего этого - и дальше можно до посинения играть с алгоритмом расчета смещения, до тех пор, пока реакция на мышку не начнет нравится. Там уже нет универсального рецепта, все от дизайна зависит. Можно линейно привязать к положению мыши. Это обычно выглядит скучно. Можно использовать какую-то функцию от расстояния до центра, чтобы сделать движения менее равномерными. В каких-то случаях делают полноценный эффект инерции, как верно подмечено в соседнем ответе. Там получаются более естественные движения (обычно все это является развитием гравитационных моделей). Есть совсем замороченный подход, когда используется моделирование системы пружин (для общего развития можно загуглить силовые алгоритмы визуализации графов). Там можно получить целый ряд занятных эффектов, которые часто оказываются в тему как раз в таких фонах, где какие-то штуки связаны между собой прямыми линиями. Ну и можно просто вдохновиться какими-то физическими явлениями и сделать что-то "по мотивам".

    Ответ написан
    22 комментария
  • Почему canvas на телефоне работает по другому?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    В codepen я нашел интересный проект...

    Это WebGL Fluid Simulation. И оригинальная ее версия на телефонах работает хорошо. Вы нашли какую-то из вариаций на тему этой штуки. Думаю для вас будет проще взять оригинал, а не отлаживать тот пример, который вы нашли.
    Ответ написан
    1 комментарий
  • Как добавить класс если в блоке что то есть?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    через css хочу скрыть его, когда пуст

    В такой формулировке можно обойтись без дополнительных классов:
    .wishlist_products_counter_number:empty {
        display: none;
    }
    Ответ написан
    1 комментарий
  • Почему на windows возникает ошибка, а на linux работает?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    В документации moment.js говорится, что для парсинга строки (когда мы делаем moment(String)) эта самая строка должна соответствовать одному из форматов ISO 8601. В случае если строка стандарту не соответствует - работа во всех браузерах не гарантируется. Там есть специальное предупреждение по этому поводу и примеры строк, которые будут соответствовать. Вероятнее всего вы столкнулись именно с этим - ваши даты не парсятся в определенных браузерах.
    Ответ написан
    Комментировать
  • Как сделать эффект движения за курсором?

    sfi0zy
    @sfi0zy Куратор тега JavaScript
    Creative frontend developer
    На этом сайте используется какая-то из версий WebGL Fluid Simulation.
    Ответ написан
    1 комментарий
  • Как вивести на экран камеру?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    var video = document.querySelector('video');

    У вас в body нет ни одного тега video, соответственно с помощью querySelector не находится ничего, переменная video равна null, и дальше все ломается. Добавьте тег video и все заработает.
    Ответ написан
    1 комментарий
  • Как сделать анимацию кардиограммы?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Вообще рисование линий обычно делается через изменение свойств stroke-dasharray и stroke-dashoffset у кривых в SVG. Это самый простой способ в рамках фронтенда, хотя и изначально эти вещи были для другого придуманы. Но в случае с ЭКГ нужна постоянная скорость рисования по горизонтали. Поэтому можно взять прямоугольную маску в рамках той же SVG, и двигать ее в сторону:

    Ответ написан
    6 комментариев