• Как задать универсальный @keyframes для нескольких разных блоков, без скриптов?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    С точки зрения производительности в CSS анимациях почти всегда имеет смысл сразу смотреть на свойство transform, а не на width или height. А в терминах трансформаций у нас для изменения размеров используются вариации функции scale():

    50% {
        transform: scaleX(0.9) scaleY(1.1);
    }

    Если у вас действительно логика завязана на проценты от изначального размера, то это именно то, что доктор прописал, и не нужно ничего дополнительно придумывать.
    Ответ написан
    7 комментариев
  • Как повторить такую же анимацию?

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

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

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

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

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Без полноценого примера в песочнице это будет гадание на кофейной гуще, но что видно сейчас - для такой простой сцены у вас используется очень много вещей, которые потенциально могут что-то сделать c видимостью объектов. Обычно мы их используем для очень опасных оптимизаций, когда нужно все сделать нестандартным образом, где-то что-то сломать, но за счет этого что-то другое выиграть. Тут такие оптимизации явно преждевременны. Стоит пройтись по ним и убрать все. Если сцена будет работать, то потом можно будет вернуть назад по очереди, наблюдая за происходящим.

    Параметры depthWrite у материала и sortObjects у рендерера - первые кандидаты на то, чтобы их убрать. И определенно стоит вместо BoxGeometry нулевой толщины взять PlaneGeometry. Нулевая толщина тоже может давать разные сложности, с определением видимости в том числе.
    Ответ написан
    3 комментария
  • Почему заливка картинки больше самой заливки?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    как решить?

    .img img {
        display: block;
    }

    Всё это нужно для затемнения фотографии

    Можно рассмотреть еще вариант без отдельного элемента с фоном:
    img {
        filter: brightness(0.6);
    }
    Ответ написан
    Комментировать
  • Допустимо ли использование midjourney, шедеврум и тп в комерческих целях?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Шедеврум

    Условия использования сервиса «Шедеврум»:

    3.3. Пользователь вправе использовать Изображения, Видео и Тексты, созданные им или другими Пользователями с использованием Сервиса, в личных некоммерческих целях с соблюдением пунктов 2.5. и 3.6. настоящего Соглашения и действующего законодательства. Любое коммерческое использование Изображений, Видео и/или Текстов возможно только при условии предварительного согласования с Яндексом.

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

    ...

    В таких вопросах не нужно слушать никого в интернете, нужно идти и читать условия использования. При необходимости связываться с компанией или своим юристом. Конечно найдутся персонажи, которые скажут "да что такого", что вами лично никто не заинтересуется, если вы миллионы на этом не зарабатываете, но потом эти же персонажи пишут жалобные статьи, как их нагрели за коммерческое использование изображений, на которое у них не было прав. У Midjourney соглашение более гибкое, но тоже с оговорками. И тоже стоит самому почитать.
    Ответ написан
    1 комментарий
  • Как сделать плавную анимацию при смене значений через 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 комментарий
  • Как сделать чтобы у меня 3д анимация вращения не плавала в дополнительной плоскости?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    У нас три координаты - XYZ. Для CSS все элементы на странице - плоские, у них нет толщины, и их размеры по оси Z нулевые. Поэтому CSS за нас не угадает, куда должен смещаться transform-origin по оси Z для кирпичика, который существует исключительно в нашем воображении. Вы смещаете грани кирпичика в отрицательные значения по оси Z, но точка transform-origin, через которую проходит ось вращения, остается в плоскости Z = 0.

    Получается, что вам нужно как-то вручную совместить ось вращения и центр кирпичика. Тут два пути - либо сместить точку transform-origin на пол кирпичика вглубь по Z:

    .cube {
        transform-origin: 50% 50% -25px;
    }

    Так ось вращения будет проходить через его текущий центр. Либо сместить грани кирпичика, чтобы он изначально собирался не "весь вглубь экрана", а "половина вглубь, половина к нам". Его центр сразу будет в плоскости Z = 0, где по умолчанию находится transform origin, и не нужно будет ничего дополнительно двигать.
    Ответ написан
    1 комментарий
  • Как сделать так, чтобы prettier не переносил каждый метод на новую строчку в JS?

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

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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Вариант с градиентами - сложный для анимирования. Рисование линий со stroke-dasharray - это стандартный выбор. Но dash array может быть длинным, им можно описать самые разные последовательности линий и пробелов, так что если вам не нужны разные цвета, то можно сделать одну линию:

    Ответ написан
    5 комментариев
  • Как через css сделать такие блики на bk сайта?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Формально можно взять фильтр blur с большим радиусом и размыть абсолютно расположенные на фоне элементы. В SVG есть аналогичный фильтр. Но лучше так не делать. Для таких размытий используется вычислительно сложный алгоритм и можно существенно увеличить нагрузку на устройства пользователей на ровном месте. Это просто сложно рендерить в реальном времени.

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

    Есть, конечно, еще более развитый вариант - взять canvas, отрендерить эту штуку на нем один раз в фоновом режиме, а потом использовать результат как картинку. Так оно не будет требовать загрузки картинки по сети, и мы не будем грузить устройства пользователей постоянно. Но это уже другой вопрос, про другие инструменты.

    P.S.: Добавлю еще такой момент, что при использовании картинки может возникнуть такая мысль, что в CSS есть еще градиенты - и это ведь тоже как картинки, может быть их использовать? Но собрать такое из градиентов гораздо сложнее, чем кажется. Сложение полупрозрачных градиентов - это не тот же алгоритм, что размытие. При взаимном наложении клякс друг на друга результат будет отличаться. Чтобы иметь такое же красивое размытие - придется иметь много градиентов, что сведет на нет саму идею снижения нагрузки на железо через них.
    Ответ написан
    Комментировать
  • Как сгенерировать простую анимацию в виде списка WORD/DWORD?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Я максимально далек от программирования контроллеров, но поделюсь идеей, что у нас в javascript можно делать вот так (вероятно и в других языках, более близких к вашим задачам, есть похожая возможность):

    const frames = [
        [
            0b0000001100000000,
            0b0000001100100000,
            0b0001111111100000,
            0b0001001100000000,
            0b0000010010000000,
            0b0000100001000000,
        ],
        [
            0b0000001100000000,
            0b0001001100000000,
            0b0001111111100000,
            0b0000001100100000,
            0b0000010010000000,
            0b0000100001000000,
        ],
    ];
    
    console.log(frames);
    // -->
    // [
    //     [ 768, 800, 8160, 4864, 1152, 2112 ],
    //     [ 768, 4864, 8160, 800, 1152, 2112 ]
    // ]

    Мне кажется, что имея моноширинный шрифт натыкать единичек в виде каких-нибудь картинок вполне можно. Запустить этот скрипт можно в любом интерпретаторе js. Если нужно действительно что-то простое, на один раз, то как вариант. А можно и детям показать, как числа выглядят по-разному.
    Ответ написан
  • Как сделать два canvas для одной сцены в three.js?

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

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

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

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

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Ошибка вида TypeError: dest.on is not a function говорит о том, что что-то в вашем пайплайне не является потоком. Она отправляет нас сюда:

    src('src/scss/style.scss')
        .pipe(autoprefixer({overrideBrowserslist: ['last 10 version']}))
        .pipe(concat('style.min.css'))
        .pipe(scss({outputStyle: 'compressed'}))
        .pipe(dest('src/css'))
        .pipe(browserSync.stream())


    Нужно каждый pipe тут проверить. Первый сразу выглядит подозрительно. Согласно официальной документации autoprefixer в gulp интегрируется по-другому. Вероятно на нем все и ломается.
    Ответ написан
    Комментировать
  • Как увеличить производительность 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 раза можно будет считать хорошим результатом. Тесты, в которых люди меряют разницу в десятки раз, обычно завязаны на какие-то узкие случаи с переиспользованием ресурсов. Далеко не факт, что это будет ваш случай. Так что если у вас там что-то конкретно тормозит - может быть будет больше пользы от оптимизации узких мест в текущей логике, чем от машинального переписывания всего на других инструментах.
    Ответ написан
    Комментировать
  • Обработка тайлов на SVG. Видны прорези между ними, что делать?

    sfi0zy
    @sfi0zy Куратор тега HTML
    Creative frontend developer
    Это похоже на известную проблему с рендерингом разных штук в браузерах. Тут два связанных момента - с одной стороны есть вопрос подгонки размеров элементов под пиксельную сетку на экране, и потенциальные ошибки с округлениями значений и "дырками" или "нахлестами" в 1px между сущностями на экране, а с другой - собственно сглаживание, когда у нас появляются промежуточные цвета, смягчающие переходы от одних к другим. Иногда, как в таких ситуациях, мы можем воспринимать их как неуместные.

    С размерами мы еще можем попытаться что-то сделать. Например распространенный костыль состоит в том, чтобы по возможности иметь размеры элементов в целом количестве пикселей. Т.е. не давать браузеру округлять на свой вкус. А вот сглаживание мы не можем выключить просто так. Вы нашли атрибут shape-rendering, но если внимательно почитать в стандарте, что он предполагает, то там будут исключительно рекомендательные высказывания:

    the user agent might turn off anti-aliasing


    или

    might adjust line positions and line widths to align edges with device pixels


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

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

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

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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    В таких вопросах хорошо показывать код, а не скриншоты, но в общем случае если нам нужно вписать что-то очень большое на фон и сделать так, чтобы оно вылезало за края экрана, но не вызывало скролла нигде, то этой большой штуке делается контейнер с overflow: hidden. Внутри контейнера она может вылезать куда угодно, это уже не будет влиять на размер страницы в целом.
    Ответ написан
    3 комментария
  • Насколько опасно использование конструктора Function?

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

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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Хорошего нативного и кроссбраузерного решения у нас пока нет. Но у path в SVG есть методы getTotalLength и getPointAtLength, а из них можно сообразить себе утилиту для расположения кружков вдоль кривой в удобных единицах измерения. Это не так здорово, как на CSS, но тем не менее:

    function putCircleOnPath(path, circle, percent) {
        const length = path.getTotalLength();
        const point = path.getPointAtLength(length * percent / 100);
    
        circle.setAttribute('cx', point.x);
        circle.setAttribute('cy', point.y);
    }


    Получится что-то такое:

    Ответ написан
    2 комментария
  • Какие могут быть подводные камни при верстке в REM c шрифтом HTML в VW?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Классическая реализация этого подхода предполагает, что есть CSS шлюз, ограничивающий минимальный/максимальный размер шрифта для минимального/максимального размера экрана, и логика дизайна явно завязана на размер шрифта. Как в мире, где люди печатают разные штуки на бумаге. Плюс альтернативные единицы измерения - vw, vmax, проценты - если нужно. Это помогает сохранить в верстке логику дизайна в явном виде. Используя искусственную логику 1rem = 10px, и rem не в значении "базовый размер шрифта", а просто как костыль для адаптивности, вы упрощаете изначальные подсчеты, но в верстке получается гора рандомных дробных значений, которые не пойми что обозначают. Тут нужно либо подгонять все под 10px сетку, что не всегда уместно, либо по мере усложнения интерфейса это все превратится в такую кашу, что врагу не пожелаешь. Собственно это возвращает нас к изначальной проблеме верстки в пикселях. Куча магических значений и никакой логики в коде. Это главный недостаток вашего способа приготовления rem.

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