Проблема повторного использования класса / Непонимание экземпляра - PullRequest
5 голосов
/ 20 марта 2020

Обновление - демонстрация JSFiddle здесь: https://jsfiddle.net/vb2ptmuo/11/

Я играю с интересным эффектом, с которым я столкнулся: https://tympanus.net/codrops/2019/08/07/image-trail-effects/

Для начала у меня есть div, содержащий набор img элементов. Он сбрасывает их в массив, а затем создает эффект следа из тех изображений, которые следуют за мышью. Вы отбрасываете все это через new ImageTrail(".content"). Но что, если у меня есть более одного набора изображений, и я хочу вместо этого повторно запустить его с этими? Пример:

    <div class="content">
        <img src="1.jpg">
        <img src="2.jpg">
        <img src="3.jpg">
    </div>
    <div class="content-2">
        <img src="4.jpg">
        <img src="5.jpg">
        <img src="6.jpg">
    </div>

Выполнение второго new ImageTrail(".content-2") не заменяет первый набор изображений вторым набором, даже если код читается мне так, как должен. Вы все еще просто видите первый набор изображений в следе.

Я также немного обеспокоен производительностью, если я создаю экземпляр класса ImageTrail дважды (если это вообще вещь), но это совершенно вторично по отношению к моя главная проблема.

Я чувствую, что есть простое решение, но мне его не хватает. Прокрутите вниз до конца демонстрации для прокомментированного кода «Это не работает»

Ответы [ 2 ]

4 голосов
/ 24 марта 2020

Основной причиной является requestAnimationFrame как часть конструктора и метода рендеринга.

Для всех случаев, для этого варианта использования один экземпляр должен иметь элемент управления рендерингом, используя requestAnimationFrame.

Я сделал трюк здесь, для этого варианта использования.

Каждый раз, когда создается новый экземпляр, он отменяет запрос рендеринга более раннего экземпляра (выполненный requestAnimationFrame) с помощью cancelAnimationFrame Даже я отменил запрос сделано в методе рендеринга тоже.

Проверьте этот jsfiddle для измененного кода: https://jsfiddle.net/rahultarafdar/mfboqy9g/45/

1 голос
/ 30 марта 2020

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

Причина, по которой отображается только первый набор изображений, заключается в том, что оба экземпляра регистра ImageTrail обратный вызов для следующего кадра анимации с requestAnimationFrame. Обратный вызов (render) первого экземпляра всегда вызывается первым, потому что он первым зарегистрировал слушателя. Эта первая функция рендеринга обновляет глобальные переменные mousePos. Вторая функция рендеринга думает, что мышь не двигалась, потому что lastMousePos и mousePos одинаковы.

Теперь, чтобы решить вашу проблему: сначала вы должны переместить все состояние, которое используется ImageTrail, в класс itsef. Это включает mousePos, cacheMousePos и lastMousePos. Если вы сделали это успешно, вы должны получить оба набора изображений одновременно, если у вас есть два экземпляра. Чтобы активировать / деактивировать рендеринг ImageTrails, вы можете добавить активный атрибут, который проверяется при каждом вызове рендеринга, или вы можете реализовать методы, которые отменяют / настраивают фрейм анимации для указанного c экземпляра. (Подробнее о том, как использовать cancelAnimationFrame, вы можете посмотреть в ответе rahul или в MDN )

...