I'm playing around with an interesting effect I came across: https://tympanus.net/codrops/2019/08/07/image-trail-effects/
To start, I have a div
containing a bunch of img
elements. It dumps them into an array and then creates a trail effect from those images which follows the mouse. You kick this all off via new ImageTrail(".content")
. But what if I have more than one set of images and I want to re-trigger it again with those, instead? Example:
<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>
Doing a second new ImageTrail(".content-2")
does not replace the first set of images with the second set, even though the code reads to me like it should. You still just see the first set of images in the trail.
I'm also slightly concerned with performance if I'm instantiating the ImageTrail class twice (if that's even a thing), but this is wholly secondary to my main issue.
I feel like there's a simple solution but I'm missing it. Scroll down to the bottom of the demo for the commented code "This doesn't work"
The main cause is requestAnimationFrame
as part of constructor and render method.
Across instances, for this use case, one instance should have the rendering control using requestAnimationFrame
.
I did a trick here, for this use case.
Every time a new instance is created, it will cancel earlier instance's render request (done by requestAnimationFrame
) by means of cancelAnimationFrame
Even i cancelled the request done in render method too.
Check out this jsfiddle for modified code : https://jsfiddle.net/rahultarafdar/mfboqy9g/45/
The Code that you posted has one major problem: it uses global variables to store state of the ImageTrail object. This is a pretty bad programming practice as it leads to unexpected behaviour and defeats the purpose of having a class in the first place.
The reason why only the first set of pictures is shown is because both instances of ImageTrail register a callback for the next animation frame with requestAnimationFrame
. The callback (render
) of the first instance is always called first, because it registered the listener first. This first render function updates the global mousePos
variables. The second render function thinks the mouse has not moved, because lastMousePos
and mousePos
are the same.
Now to address your problem: first you should move all the state that is used by ImageTrail into the class itsef. That includes mousePos
, cacheMousePos
and lastMousePos
. If you have done that successfully, you should get both imagesets diyplaying at the same time, if you have two instances. To activate/deactivate the rendering of ImageTrails, you could add an active attribute, which gets checked at every render call or you could implement methods that cancel/setup the animation frame for a specific instance. (For details how to use cancelAnimationFrame
you could look into the answer from rahul or into the MDN)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With