• Обновление света в three.js?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    const light1 = new THREE.PointLight(0xffffff, 0.4); // было
    const light1 = new THREE.PointLight(0xffffff, 1, 0, 0); // стало

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

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

    Последний параметр decay, затухание, непосредственно связан как раз с физикой распространения света. Обычно мы стараемся его никогда не трогать, потому что меняя физику мы себе усложняем дальнейшую разработку в 99% случаев. По умолчанию этот параметр равен 2. Не 0.

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

    В подавляющем большинстве случаев достаточно менять только второй параметр - интенсивность. Измеряется в канделах. Реалистичные значения для бытовых источников света - от 0 до нескольких сотен.

    Если у вас с реалистичными значениями получается что-то не то - стоит уточнить размеры объектов. Чтобы физика работала, у нас 1 условная единица пространства WebGL должна соответствовать 1 метру. Если вы случайно сделали себе размер коробки в 600 метров, а не 0.6, то физика могла дать не тот визуальный эффект, который вы ожидали. Позиция камеры на расстоянии в сотни километров от коробки тоже намекает на то, что нужно проверить размеры.
    Ответ написан
  • Как отображать элементы в зависимости от масштаба содержащего их блока?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Это называется "кластеризация". Типовая задача при работе с картами. Во многих библиотеках для отображения карт решение есть прямо из коробки. Тут не нужно ничего придумывать, можно воспользоваться готовыми алгоритмами.
    Ответ написан
    4 комментария
  • Как назвать классы заказа для паттерна "Состояние"?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Попробуйте вместо попыток натянуть сову на глобус, а задачу на паттерн, действовать от простого. Пусть заказ бывает бесплатным. У заказа есть флаг "является ли он бесплатным". Мы даже можем воспользоваться возможностями языка и прикрутить какой-то геттер для надежности, чтобы флаг менялся в зависимости от устанавливаемой цены (в примерах условно JS):
    class Order {
        get isFree() { return this.price === 0; }
    }

    Мы можем прям сюда присобачить и оплату, но допустим мы не хотим, чтобы заказ что-то знал об урлах для оплаты. Ему это не надо. Заказ - это список товаров, какой-то статус завершенности, адрес доставки и.т.д. Он про данные, не про процессы. Путь будет обработчик, который может провести заказ как кассир в пятерочке:
    class Order { /* --- */ }
    
    class Сashier {
        proceed(order) {
            const url = order.isFree ? "free url" : "paid url";
            // ...редиректим, проводим оплату, предлагаем пакетик и кофе по акции
        }
    }

    Допустим у нас есть много платежных систем, там все сложно. Инфраструктура - не кассира дело. Ок, дадим ему доступ к адаптеру, который скрывает все за собой и проводит непосредственно оплату.
    class Order { /* --- */ }
    
    class PaymentHandler {
        charge(price) {
            // ...редиректим куда надо, в зависимости от цены и привязанной карты
        }
    }
    
    class Cashier {
        proceed(order) {
            const isSuccess = PaymentHandler.charge(order.price);
            
            if (isSuccess) {
                // заказ прошел
            } else {
                throw new Error('ГААААААЛЯЯЯ ОТМЕЕЕЕНА!!!!');
            }
        }
    }

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

    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 комментариев
  • Тормоза браузера из-за стилей, решение?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Для начала для нас важно осознать, что у разных фильтров разная вычислительная сложность. Они не все "плохие". Алгоритмы для brightness, grayscale, hue-rotate и других манипуляций с цветом выполняются за O(1) для каждого пикселя. Т.е. нагрузка на железо растет линейно в зависимости от площади элемента на экране. Это не так страшно. А вот фильтры размытия, blur или drop-shadow, имеют сложность где-то в районе O(R^2). Там есть разные варианты оптимизаций, но в среднем мы говорим именно о квадратичной зависимости от радиуса размытия. И это для каждого пикселя. Именно отсюда мы имеем сильные тормоза при попытке что-то большое размыть на пол экрана. Дохлые видеокарты телефонов и ноутбуков не вывозят. Браузеры не умеют такие вещи переиспользовать, так что это переразмытие происходит снова и снова, и мы имеем что имеем.

    При этом фильтры в CSS, в SVG - это все грубо говоря высокоуровневые обертки над одними и теми же универсальными алгоритмами рендеринга. Мы можем в рамках WebGL написать свои шейдеры, которые будут делать то же самое. Обертки разные, но алгоритмы одинаковые. Поэтому замена одной технологии на другую ничего особо не даст в плане производительности. В вопросах оптимизаций нам нужно не по-тупому менять инструменты-обертки, а смотреть в конечные алгоритмы, которые будут задействованы на странице в реальном времени, и по возможности рассчитывать все заранее и переиспользовать.

    В контексте верстки тут есть полтора варианта, что можно сделать. Можно рассчитывать такие вычислительно-сложные штуки еще при разработке и загружать в страницу сразу в виде картинок или видео. Это не идеальный вариант, пропорции получаются фиксированные, но иногда подходит. Есть вариант рассчитывать такие штуки в фоне на WebGL. Т.е. мы грузим интерфейс, смотрим какого там все размера получается, и один раз в фоновом режиме генерируем картинки нужного размера и потом плавно показываем. Такой вариант частенько встречается в рекламно-конкурсных проектах, когда за прелоадером в начале скрывается в том числе и такая генеративная история. Тут мы получаем гибкость в плане размеров и хорошую производительность сайта в целом, потому что все операции проходят только один раз, а дальше у нас все переиспользуется в виде обычных картинок. Каких-то принципиально других вариантов у нас пока нет. Только дизайн менять.
    Ответ написан
    3 комментария
  • Почему возникает Ошибка синтаксического анализа XML в браузере firefox?

    sfi0zy
    @sfi0zy
    Creative frontend developer
    Между фактами
    Как видно, на первой позиции в первой строке находится {

    и
    Ошибка синтаксического анализа XML

    есть противоречие. То ли речь идет про XML, то ли про JSON. Надо определиться. Вполне вероятно, что у вас сервер левые заголовки отдает и браузер думает, что там XML, а на самом деле там JSON. Отсюда и ошибка.
    Ответ написан
    Комментировать
  • Почему не добавляется класс следующему элементу после 2 клика?

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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Весь затык у нас тут в том, что CSS не позволяет в рамках path жонглировать единицами измерения. Почему? Люди задавались этим вопросом с самого момента появления path в CSS. Но этот функционал всегда был в SVG. Так что можно добавить маску в SVG (тут у нас размер элемента, условные 100% на 100%, считается за 1 на 1):

    <svg width='0' height='0'>
        <defs>
            <clipPath id='example' clipPathUnits='objectBoundingBox'>
                <path d="M 0 0 a 1 1 0 0 0 1 1 h -1 v -1z"/>
            </clipPath>
        </defs>
    </svg>

    И тогда в CSS уже будет все просто:

    .example {
        clip-path: url(#example);
    }

    Это не идеальный вариант, хотелось бы на чистом CSS, но имеем, что имеем.
    Ответ написан
  • Как реализована анимация SVG элементов (персонажей) в web app?

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

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

    sfi0zy
    @sfi0zy
    Creative frontend developer
    я так понимаю, что встраивать нужно будет с помощью JS. Можно ли такое сделать?

    Официальный help в разделе "for developers" говорит, что вам нужен блок T123. Он позволяет интегрировать HTML, CSS и JS код в страницу.
    Ответ написан
  • Какие возможные варианты сделать такую кнопку, чтобы границы кнопок подстраивались под размер текста внутри?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Где-то в светлом будущем у нас будет CSS Painting API, с помощью которого можно будет рисовать какие угодно бордеры. А пока можно его сымитировать обычным канвасом (правда придется отступы подгонять под особенности шрифта, но это уже детали, один раз можно сделать):



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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    порядок действий

    1. Сделать 12 элементов.
    2. Расположить элементы по кругу. Тут абсолютное позиционирование В текущих реалиях вечнозеленых браузеров мы можем использовать нативные функции sin() и cos(), чтобы рассчитать, где какие из них должны быть расположены на окружности не покидая мир CSS. Тут никакой магии, геометрия за 7 класс школы.
    3. Естественным образом в расчетах координат появится угол, который можно менять, тем самым поворачивая всю эту карусель. Его можно уже из скриптов менять по той логике, которая нужна для взаимодействия с пользователем.
    4. Обрезать все штатным clip-path.




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

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Я думал через clip-path но там нет такой плавности... даже чат джипити не понимает...

    Если уж говорить про clip-path, то там есть clip-source, с помощью которого мы можем поиспользовать clipPath из мира SVG, а в рамках SVG уже можно нарисовать себе любую форму. В разделе синтаксиса и на MDN, и в стандарте, это буквально первый предлагаемый вариант использования clip-path. Не доверяйте вашей чатгопоте. Читайте документацию самостоятельно. Там много интересного.
    Ответ написан
    4 комментария
  • Как задать универсальный @keyframes для нескольких разных блоков, без скриптов?

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

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

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

    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 комментарий