Как подружить
сферу и навигацию:
меню по кривой
Всем Салют!
Меня зовут Алексей
Я веселый Front-end разработчик
Я создаю сайты, люблю
сложные анимации
творю чудеса в
преподаю в
Задача
Задача
Задача
Задача
- ВАУ эффект
- Показать технологичность компании
Зачем?
Спойлер
The SPHERE - СФЕРА
Стартуем!
Поиск похожих решений
Все не то!
Варианты реализации
- CSS Transform
- Canvas
- SVG - движение по кривой
Сделать видео:)
SVG - движение по кривой
Понеслась!
Сверстал меню :)
GSAP плагин - MotionPath
Размещение на кривой
let navPathSvg = "[data-sphere-path]";
navItemsLevel1.forEach((el) => {
let tl = new gsap.timeline({paused: true});
tl
.to(el, {
duration: 10,
ease: "power1.inOut",
motionPath: {
path: navPath,
align: navPath,
alignOrigin: [0, 0.5],
start: 0.81,
end: 0.21
}
});
}
let distanse = 0.016;
let progressOffset = (1 - length * distanse) / 2;
let navPathSvg = "[data-sphere-path]";
navItemsLevel1.forEach((el) => {
let tl = new gsap.timeline({paused: true});
tl
.to(el, {
duration: 10,
ease: "power1.inOut",
motionPath: {
path: navPath,
align: navPath,
alignOrigin: [0, 0.5],
start: 0.81,
end: 0.21
}
});
progressOffset += distanse;
tl.progress(progressOffset);
tl.pause();
}
Размещение второго уровня
let progressOffset = firstLevelOffset;
//set level 2 pos
if(level2.length){
gsap.set(level2, {autoAlpha:0});
}
level2.forEach((el)=>{
let tl = new gsap.timeline({paused: false});
tl
.to(el, {
duration: 10,
ease: "power1.inOut",
motionPath: {
path: navPath,
align: navPath,
alignOrigin: [0, 0.5],
start: 0.81,
end: 0.21
}
});
tl.progress(progressOffset);
tl.pause();
});
Открытие второго уровня
////Move first level
navItemsLevel1.each(function (i) {
let tl = $(this).data('tl');
let offset = tl.progress() - (2 * distanse + clickedItemIndex * distanse);
gsap.to(tl, {progress: offset});
});
let curTopLevelProgress = clickedItem.data('tl').progress();
//Move second level
level2.each(function (i) {
let tl = $(this).data('tl');
let progress = curTopLevelProgress + (i + 1) * distanse;
gsap.fromTo(tl, {progress: curTopLevelProgress}, {progress: progress});
});
//Move first level after second
nextLevel1.each(function (i) {
let tl = $(this).data('tl');
let offset = tl.progress() + (level2Count) * distanse;
gsap.to(tl, {progress: offset});
});
//Show second level
gsap.to(level2, { autoAlpha: 1, stagger: 0.05});
let distanse = 0.016;
let offset = distanse;
let moveSphereItems = (direction) => {
if (!isNavOpened() || isAnimated ) return;
let isLimit = isScrollLimit();
if (direction === 'up') {
if(isLimit.bottom) return;
offset *= 1;
} else if (direction === 'down') {
if(isLimit.top) return;
offset *= -1;
} else {
return;
}
navItems.forEach((el) => {
let tl = el.dataset.tl;
let itemOffset = tl.progress() + offset;
gsap.to(tl, {duration: 0.2, progress: itemOffset });
}
}
Движение по скролу
Победа...
...почти
Трудности при реализации
- Многоуровневость - 3 уровня
- Линия между пунктами
- К-во элементов динамическое
- Поджимали сроки
Обсудил с дизами!
Производительность
Задача
Реализация
The SPHERE - СФЕРА
Применение в другом проекте
this.distanse = 0.125;
////place items on arc
this.circleItems.forEach((el, index) => {
let tl = new gsap.timeline({paused: false});
tl
.to(el, {
duration: 1,
ease: "none",
motionPath: {
path: this.navPath,
align: this.navPath,
alignOrigin: [0.5, 0.5],
relative: true,
start: 0,
end: 1
}
});
index = index >= 9 ? 1 : index;
let progressOffset = index * this.distanse;
tl.progress(progressOffset);
tl.pause();
});
Спасибо за внимание!
Как подружить сферу и навигацию: меню по кривой
By Alexey Kalyuzhnyi
Как подружить сферу и навигацию: меню по кривой
Поделюсь кейсом создания нестандартной навигации на сайте. Расскажу про путь от постановки задачи, через работу с дизайнерами к финальной реализации и восторгу. История включает в себя нестандартную верстку, CSS переменные, работу с SVG, GreenSock и немного боли.
- 590