I have created a scrollTrigger animation with Morphing on an SVG. Animation action can be found here: http://143.244.130.104/
I am having an issue with making is performant on Macbook Google Chrome Browser. The animation is working not perfectly but well enough in safari, but I can see major issues in chrome. When I did performance profiling I could see a lot of red fps areas when I scrolled past the animation.
What are the things I can try apart from force3D: true
// Make sure to register Morph Plugin.
gsap.registerPlugin(MorphSVGPlugin);
// Morph can only happen between path, make sure to convert any
// other type of element from SVG to path using covertToPath()
MorphSVGPlugin.convertToPath('circle, rect, ellipse, line, polygon, polyline');
// Dynamically Set the height of Hero Section to the
// Height of the screen.
document.querySelector('.location_island').style.height = window.innerHeight;
const screenSize = document.body.clientWidth;
let animationData = [];
let percetageScroll = 80;
if (screenSize <= 900) {
percetageScroll = 50;
animationData = [
{
el: 'svg #stage_1',
title: '.location_1',
index: 6,
label: 'stage1',
},
{
el: 'svg #stage_2_mobile',
title: '.location_1',
index: 5,
label: 'stage2',
in: ['svg #stage_1 #stage_2_el_mobile', '.location_1'],
out: ['#center-title', 'svg #stage_1 #other'],
},
{
label: 'wait_1',
},
{
el: 'svg #stage_3_mobile',
title: '.location_2',
index: 4,
label: 'stage3',
in: ['svg #stage_1 #stage_3_el_mobile', '.location_2'],
out: ['svg #stage_1 #stage_2_el_mobile', '.location_1'],
},
{
label: 'wait_2',
},
];
} else {
animationData = [
{
el: 'svg #stage_1',
title: '.location_1',
index: 1,
label: 'stage1',
},
{
el: 'svg #stage_2',
title: '.location_1',
index: 2,
label: 'stage2',
in: ['svg #stage_1 #stage_2_el', '.location_1'],
out: ['#center-title', 'svg #stage_1 #other'],
},
{
label: 'wait_1',
},
{
el: 'svg #stage_3',
title: '.location_2',
index: 3,
label: 'stage3',
in: ['svg #stage_1 #stage_3_el', '.location_2'],
out: ['svg #stage_1 #stage_2_el', '.location_1'],
},
{
label: 'wait_2',
},
];
}
// Initialize the timeline.
const timeline = gsap.timeline({
scrollTrigger: {
trigger: '.main_location_wrapper',
start: 'top 70px',
end: '+=' + (animationData.length + 1) * percetageScroll + '%', // each section is 60% of the viewport height
scrub: 1,
pin: true,
force3D: true,
},
});
// markers: true
// Remove first item from array and start to Looping to set animation.
animationData.slice(1).forEach((step) => {
timeline.addLabel(step.label);
// Animate Each item together.
if (step.el) {
// Safe Variable Declaration.
let svgMorphOut = 'svg #stage_1';
let svgMorphIn = step.el;
// SAND
let svgInSand = svgMorphIn + ' ' + '#sand' + '-' + step.index;
let svgOutSand = svgMorphOut + ' ' + '#sand';
// LAND
let svgInLand = svgMorphIn + ' ' + '#land' + '-' + step.index;
let svgOutLand = svgMorphOut + ' ' + '#land';
timeline.to(
svgOutSand,
{
morphSVG: svgInSand,
ease: 'power1.out',
},
step.label
);
timeline.to(
svgOutLand,
{
morphSVG: svgInLand,
ease: 'power1.out',
},
step.label
);
// For Stage 2;
if (step.index === 2) {
timeline.to(
'svg',
{
xPercent: 50,
ease: 'power1.inOut',
},
step.label
);
timeline.zoom(
'.location_island',
{
scale: 4.5,
origin: [0.70, 0.40],
ease: 'power1.inOut',
},
step.label
);
}
if (step.index === 3) {
timeline.to(
'svg',
{
xPercent: -40,
ease: 'power1.inOut',
},
step.label
);
timeline.zoom(
'.location_island',
{
scale: 5.5,
origin: [0.10, 0.63],
ease: 'power1.inOut',
},
step.label
);
}
if (step.index === 4) {
timeline.to(
'svg',
{
yPercent: -10,
xPercent: 10,
ease: 'power1.inOut',
},
step.label
);
timeline.zoom(
'.location_island',
{
scale: 2.6,
origin: [0.45, 0.42],
ease: 'power1.inOut',
},
step.label
);
}
if (step.index === 5) {
timeline.to(
'svg',
{
yPercent: -13,
xPercent: 10,
ease: 'power1.inOut',
},
step.label
);
timeline.zoom(
'.location_island',
{
scale: 2.1,
origin: [0.4, 0.42],
ease: 'power1.inOut',
},
step.label
);
}
step.in.forEach((item) => {
timeline.fromTo(
item,
{
autoAlpha: 0,
display: 'none',
},
{
autoAlpha: 1,
display: 'block',
ease: 'power1.inOut',
},
step.label + '+=15%'
);
});
step.out.forEach((item) => {
timeline.fromTo(
item,
{
autoAlpha: 1,
display: 'block',
},
{
autoAlpha: 0,
display: 'none',
ease: 'power1.inOut',
},
step.label + '-=15%'
);
});
} else {
timeline.to('svg', { duration: 0.5 }, step.label);
}
});