Lag on GSAP animation for mobile browsers - javascript

I'm playing around with some simple GSAP animations and I'm noticing that there is an issue with them running smoothly on a mobile browser(Brave and Chrome Android). For example the following code looks perfect on desktop devices while on mobile the animations seem to lag.
<div class="container" id="contentContainer">
<div class="content-start">
<div class="medium-box box-1">
The Mekong river originates in the Himalayas in China, where it is known as the Lancang. It flows through the Lower Mekong Basin countries of Myanmar, Laos, Thailand, Cambodia and Vietnam, where it reaches the South China Sea.
</div>
</div>
</div>
let mySplitText = new SplitText('.box-1', { type: "words,chars" }),
chars = mySplitText.chars; //an array of all the divs that wrap each character
gsap.fromTo('.box-1',{y: '100%', opacity: 0},{y: 0, opacity: 1, duration: 1, scrollTrigger: {
trigger: '.box-1',
start: 'top 60%',
end: "bottom 50%",
pin: true,
pinSpacing: false,
markers: true,
onEnter: () => {
gsap.to('.box-1',{duration: 1, y: '0', opacity: 1})
gsap.from(chars, {duration: 0.5,opacity: 1,scale: 0,ease: "back",stagger: 0.01})
},
onLeave: () => {
gsap.to('.box-1',{duration: 1, y: '-100%', opacity: 0})
},
onEnterBack: () => {
gsap.to('.box-1',{duration: 1, y: 0, opacity: 1})
gsap.from(chars, {duration: 0.5, opacity: 1,scale: 0,ease: "back",stagger: 0.01})
},
onLeaveBack: () => {
gsap.to('.box-1',{duration: 1, y: '100%', opacity: 0})
}
}})
I think one of the reasons the animation lags is because of the navigation bar on mobile devices that pops up when scrolling down, resizing the viewport, and changing the start and end triggers.
I also realize since I'm quite new that my code might not be very efficient and that might impact performance.
I would appreciate any tips as to how to make this scrolling experience smooth for all users on all devices.Thanks in advance.

Related

Why scrolling down faster than scrolling up with GSAP?

I'm new to GSAP and JS in general, I'm having some problems figuring out why I have two different speeds while scrolling up and down.
There's also a problem once it scrolls all the way up that automatically reverse the animation, this is not wanted.
https://codepen.io/Mahanon/pen/rNdedwa
gsap.registerPlugin(ScrollTrigger);
gsap.to('#bottom', {
"top": "0",
duration: 1.3,
ease: Quart.easeOut,
scrollTrigger: {
trigger: '#bottom',
start: 'top bottom',
end: 'top top',
toggleActions: 'restart reverse restart reverse'
},
});

GSAP ScrollTrigger background color change animation not working well on Safari

I'm trying to make a gsap animation that switches the viewport's background color depending on your scrolling position. The animation works great on Chrome and on FireFox, but on Safari it just looks bad, very laggy and the colors don't transition into the page, but rather just pop up with a delay.
Here is my animation (I am using Vue.js)
backgroundAnimation() {
let $projects = gsap.utils.toArray(this.htmlID + " .project-wrapper");
let projectListTl = gsap.timeline({
scrollTrigger: {
trigger: this.htmlID,
start: "top center",
end: "bottom center",
ease: "none",
scrub: true,
markers: false,
onLeave: ({ progress, direction, isActive }) =>
document.documentElement.style.setProperty("--background", "white"),
},
});
$projects.forEach(($project, i) => {
projectListTl.to("html", {
duration: 0.1,
"--background": $project.dataset.projectColor,
});
projectListTl.to("html", {
delay: 0.3,
duration: 0.2,
"--background": "transparent",
});
});
},
(The method above runs when there is an update on the component)
updated: function () {
this.$nextTick(function () {
this.backgroundAnimation();
const self = this;
ScrollTrigger.matchMedia({
"(min-width: 1024px)": function () {
self.scrollAnimation();
},
});
});
},
Does anybody have any ideas as to why this is happening on Safari?

Trail mode of hovering events doesnt work in tsParticles(similar to particlejs)

I have got two queries, I am implementing tsParticles in my React application.
First one:.
<Particles
id="tsparticles"
options={{
background: {
color: {
value: "black",
},
},
fpsLimit: 60,
interactivity: {
detectsOn: "window",
events: {
onClick: {
enable: true,
mode: "push",
},
onHover: {
enable: true,
mode: "trail",
},
resize: true,
},
modes: {
bubble: {
distance: 400,
duration: 2,
opacity: 0.8,
size: 40,
},
push: {
quantity: 4,
},
repulse: {
distance: 200,
duration: 0.4,
},
},
},
particles: {
color:{
animation:{
enable:true,
speed:50,
},
value:"#f00"
},
links: {
shadow:{
blur:true,
color:"#00ff00"
},
triangles:{
frequency: 1
},
color: "random",
distance: 150,
enable: true,
frequency:1,
opacity: 0.5,
width: 1,
},
collisions: {
enable: true,
},
move: {
angle:{
offset: 45,
value: 90
},
attract:{
rotate:{
x:3000,
y:3000
}
},
gravity:{
acceleration: 9.81,
enable:false,
maxSpeed:1
},
direction: "none",
enable: true,
outMode: "bounce",
random: false,
speed: 6,
straight: false,
},
number: {
density: {
enable: true,
value_area: 1000,
},
value: 80,
},
opacity: {
value: 0.5,
},
shape: {
type: "circle",
},
size: {
random: true,
value: 5,
},
},
detectRetina: true,
}}
/>
There is a section of onHover and key value of mode in it. There are like 8 different modes to it, can be viewed in https://particles.matteobruni.it/ .
All other modes work fine but the trail mode when I use this code, am I missing some other properties to the Particles component?
Second one:
Also,
I have got two divs, one for the particle and the other for the text to display on top of it. I have achieved this using z-index and positions.
I need the canvas height to be dynamic that is occupy 100% height of its parent whatever the screen size is. I have tried doing this by including Particles component inside a div and keeping its height to 100% but the canvas height decreases with the decrease in the screen size.
Kindly help me, thank you :)
Wow, there's a lot to answer here, but I try to do my best.
First point, the config and mouse trail
The mouse trail needs more configuration, in the modes section of interactivity you have to configure the trail section.
You can see a sample here: https://codepen.io/matteobruni/pen/abdpbBY
If you need more documentation checkout the right section in documentation: https://particles.js.org/interfaces/_options_interfaces_interactivity_modes_itrail_.itrail.html
Second point, the canvas size
If you need a dynamic canvas size the best solution is to use the backgroundMode in the options root object
You can see a sample here: https://codepen.io/matteobruni/pen/MWeqxNL
The background mode if enabled sets the canvas style with a fixed position and the desired zIndex
You can see the documentation here: https://particles.js.org/interfaces/_options_interfaces_backgroundmode_ibackgroundmode_.ibackgroundmode.html
If you are using the backgroundMode, the better results are obtained without setting any style to the containing div (the tsParticles target/container)

How to scroll to a Label in GSAP scrollTrigger scrub Timeline

So I'm having this problem I have a scrollTrigger Timeline and i want a button to scroll to take me to a specific position.
I tried using seek but it didnt work even ScrollTo plugin lack a support for this
I have a gsap Timeline
const tl = gsap.timeline({
paused: true,
scrollTrigger: {
trigger: '.home',
start: 'top top',
end: 'bottom+=1000 top',
pin: true,
scrub: 0.5,
markers: true
},
defaults: {
duration: 2
}
})
// Main home animation
.to(['.left'], {
clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0 100%)',
ease: 'power1.out'
}, 'scene')
// Name scaling animation
.to(['.name-title'], {
scale: 0,
ease: 'power1.out'
}, 'scene')
.from(document.getElementById('achievements'), {
autoAlpha: 0
}, '-=1.5')
// Achievements reveal animation
.from(document.getElementById('achievements').querySelectorAll('.row'), {
motionPath: {
path: [
{
x: 0,
y: 100
}
]
},
autoAlpha: 0,
stagger: 0.2,
ease: 'power3.out'
}, '-=2')
.addLabel('achievements')
// Hide achievements animation
.to(document.getElementById('achievements').querySelectorAll('.row'), {
motionPath: {
path: [
{
x: 0,
y: -100
}
]
},
autoAlpha: 0,
stagger: 0.2,
ease: 'power3.in'
}, '+=2')
and i have a button in my home that should take me to achievements section but i cant find any proper solution.
So i deviced my own workaround solution (P.S: im using Vue)
scrollTo () {
const pos = Math.ceil(document.body.scrollHeight * (this.loadTl.labels.achievements / this.loadTl.duration()))
gsap.to(window, { duration: 2, scrollTo: pos, ease: 'linear' })
}
loadTl here is a computed property for my Timeline i Found the position of achievements and used ScrollToPlugin to scroll to that pixel.
But im looking for a better way of doing this.

revolution slider, bullets strange behaviour

I have a revolution slider carousel with a bullets navigation, that's the js configuration:
var revapi2;
tpj(document).ready(function() {
if(tpj("#rev_slider_2_1").revolution == undefined){
revslider_showDoubleJqueryError("#rev_slider_2_1");
}else{
revapi2 = tpj("#rev_slider_2_1").show().revolution({
sliderType:"carousel",
jsFileLocation:"libs/revolutionSlider/js/",
dottedOverlay:"none",
sliderLayout: "auto",
delay:9000,
navigation: {
keyboardNavigation:"off",
keyboard_direction: "horizontal",
mouseScrollNavigation:"off",
onHoverStop:"off",
arrows: {
style:"",
enable:true,
hide_onmobile:false,
hide_under:300,
hide_onleave:true,
hide_delay:200,
hide_delay_mobile:1200,
tmp:'',
left: {
h_align:"left",
v_align:"center",
h_offset:30,
v_offset:0
},
right: {
h_align:"right",
v_align:"center",
h_offset:30,
v_offset:0
}
},
touch:{
touchenabled:"off",
swipe_treshold : 75,
swipe_min_touches : 1,
drag_block_vertical:true,
swipe_direction:"horizontal"
}
,
bullets: {
enable: true,
container:"slider",
hide_onmobile: false,
style: "ares",
hide_onleave: false,
direction: "horizontal",
h_align: "center",
v_align: "bottom",
h_offset: 20,
v_offset: 20,
space: 0,
rtl:false,
tmp: ''
}
},
carousel: {
horizontal_align: "center",
vertical_align: "center",
fadeout: "off",
maxVisibleItems: 3,
infinity: "on",
space: 0,
stretch: "off"
},
viewPort: {
enable:true,
outof:"pause",
visible_area:"80%"
},
responsiveLevels:[1240,1024,778,320],
gridwidth:[1240,1024,778,320],
gridheight:[600,600,500,300],
lazyType:"none",
parallax: {
type:"mouse",
origo:"slidercenter",
speed:2000,
levels:[2,3,4,5,6,7,12,16,10,50],
},
shadow:0,
spinner:"off",
stopLoop:"on",
stopLoop:"on",
stopAfterLoops:0,
stopAtSlide:1,
shuffle:"off",
autoHeight:"on",
hideThumbsOnMobile:"on",
hideSliderAtLimit:0,
hideCaptionAtLimit:0,
hideAllCaptionAtLilmit:0,
debugMode:false,
fallbacks: {
simplifyAll:"off",
nextSlideOnWindowFocus:"off",
disableFocusListener:false,
}
});
}
});
The bullets appears over my carousel but what i can see is a strange behaviour. During navigation beetween slides, the .selected class is applied correctly to the right index only at the beginning of the sliding process. At the end , when the slide is stopped and loaded, the .selected class is automatic cleared from the correct index and applied to the index 0. I'll try to be more clear in my explaination:
slider with 4 element -> i click on the 3° bullet (the index 2)-> my image begin to slide in the view e my 3° bullet is red (red is the color that i have assigned to the .selected class)-> when the image slide animation is complete my 3° bullet return gray and my 1° bullet became red.
I have tried to intercept the event that cause this automatic change, but i have tried to log every events i have found in docs, and nothing is launched at the same time of my strange behaviour. It's a bug? How i can solve it?

Categories