Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Announcement bar] Slides animation. #2595

Merged
merged 38 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
91326a8
Add animation to the announcement bar.
eugenekasimov May 1, 2023
9b9de46
Add animation for the current and next slides.
eugenekasimov May 1, 2023
72ba2e2
Make animation works for auto-rotating.
eugenekasimov May 4, 2023
beb668f
Ensure the slider rotates in reverse when it reaches the end/begining.
eugenekasimov May 9, 2023
50069e5
Add condition to apply delay for announcement-bar only
eugenekasimov May 10, 2023
8d729b6
Refactor and update some logic.
eugenekasimov May 12, 2023
1b40cdf
Refactoring.
eugenekasimov May 15, 2023
4443433
Merge branch 'main' into animation-announcement-bar
eugenekasimov May 15, 2023
2575861
Remove unneccessary css code.
eugenekasimov May 15, 2023
a683dec
Merge branch 'main' into animation-announcement-bar
eugenekasimov May 24, 2023
aeae987
Refactor css. Change the order.
eugenekasimov Jun 6, 2023
2931bc8
Refactor JS.
eugenekasimov Jun 7, 2023
f472919
Merge branch 'main' into animation-announcement-bar
ludoboludo Jun 7, 2023
120d4f3
Refactor css.
eugenekasimov Jun 8, 2023
25600bc
Isolate all logic in slideshowComponent.
eugenekasimov Jun 8, 2023
7cf4a3e
Simplify applyAnimation method.
eugenekasimov Jun 8, 2023
932903b
Reuse currentPage
eugenekasimov Jun 8, 2023
80d3a90
Apply animation on selected slides.
eugenekasimov Jun 9, 2023
b4b8fa2
Adjust duration of animation and shifting.
eugenekasimov Jun 9, 2023
cc6972d
Refactoring
eugenekasimov Jun 14, 2023
7ef82a7
Another refactoring
eugenekasimov Jun 16, 2023
9327404
Remove timeout and add delay in css
eugenekasimov Jun 16, 2023
e4b07e7
Refactoring
eugenekasimov Jun 16, 2023
dbdd4f4
Add no-js
eugenekasimov Jun 19, 2023
6f767bd
Prevent snapping during animation
eugenekasimov Jun 20, 2023
94f243f
Fix auto-rotation positioning
eugenekasimov Jun 20, 2023
66b85cc
Refactor applyAnimation
eugenekasimov Jun 20, 2023
8dd224a
Refactor and remove unused elements
eugenekasimov Jun 21, 2023
55f20ca
[Announcement bar] Add social icons (#2497)
eugenekasimov Jun 9, 2023
a06ec50
Use live region to announce recipient form (#2672)
fredma Jun 15, 2023
455d26e
Merge branch 'main' into animation-announcement-bar
eugenekasimov Jun 21, 2023
6862e85
Safari fix and addressing feadback
eugenekasimov Jun 23, 2023
9975886
Merge branch 'main' into animation-announcement-bar
eugenekasimov Jun 23, 2023
7412b11
Correct typo
eugenekasimov Jun 23, 2023
1013873
Remove unnecessary code
eugenekasimov Jun 23, 2023
1c4dd25
Prevent applying animation when you scroll
eugenekasimov Jun 23, 2023
419b151
Remove console.log
eugenekasimov Jun 27, 2023
9af7783
Refactoring
eugenekasimov Jun 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions assets/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ details > * {
:root {
--duration-short: 100ms;
--duration-default: 200ms;
--duration-announcement-bar: 250ms;
--duration-medium: 300ms;
--duration-long: 500ms;
--duration-extra-long: 600ms;
Expand Down Expand Up @@ -2171,6 +2172,11 @@ product-info .loading-overlay:not(.hidden) ~ *,

.announcement-bar .slider--everywhere {
margin-bottom: 0;
scroll-behavior: auto;
}

.utility-bar__grid .announcement-bar-slider {
width: 100%;
}

.utility-bar__grid .announcement-bar-slider {
Expand Down Expand Up @@ -2253,6 +2259,51 @@ product-info .loading-overlay:not(.hidden) ~ *,
letter-spacing: 0.1rem;
}

.announcement-bar-slider--fade-in-next .announcement-bar__message,
.announcement-bar-slider--fade-in-previous .announcement-bar__message,
.announcement-bar-slider--fade-out-next .announcement-bar__message,
.announcement-bar-slider--fade-out-previous .announcement-bar__message {
animation-duration: var(--duration-announcement-bar);
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}

.announcement-bar-slider--fade-in-next .announcement-bar__message {
--announcement-translate-from: -1.5rem;
/* Prevent flicker */
opacity: 0;
animation-name: translateAnnouncementSlideIn;
animation-delay: var(--duration-announcement-bar);
}

.announcement-bar-slider--fade-in-previous .announcement-bar__message {
--announcement-translate-from: 1.5rem;
/* Prevent flicker */
opacity: 0;
animation-name: translateAnnouncementSlideIn;
animation-delay: var(--duration-announcement-bar);
}

.announcement-bar-slider--fade-out-next .announcement-bar__message {
--announcement-translate-to: 1.5rem;
animation-name: translateAnnouncementSlideOut;
}

.announcement-bar-slider--fade-out-previous .announcement-bar__message {
--announcement-translate-to: -1.5rem;
animation-name: translateAnnouncementSlideOut;
}

@keyframes translateAnnouncementSlideIn {
0% {opacity: 0; transform: translateX(var(--announcement-translate-from))}
100% {opacity: 1; transform: translateX(0)}
}

@keyframes translateAnnouncementSlideOut {
0% {opacity: 1; transform: translateX(0)}
100% {opacity: 0; transform: translateX(var(--announcement-translate-to))}
}

/* section-header */
.section-header.shopify-section-group-header-group {
z-index: 3;
Expand Down
79 changes: 67 additions & 12 deletions assets/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -700,8 +700,12 @@ class SliderComponent extends HTMLElement {
event.currentTarget.name === 'next'
? this.slider.scrollLeft + step * this.sliderItemOffset
: this.slider.scrollLeft - step * this.sliderItemOffset;
this.setSlidePosition(this.slideScrollPosition);
}

setSlidePosition(position) {
this.slider.scrollTo({
left: this.slideScrollPosition,
left: position,
});
}
}
Expand All @@ -719,12 +723,16 @@ class SlideshowComponent extends SliderComponent {
this.sliderFirstItemNode = this.slider.querySelector('.slideshow__slide');
if (this.sliderItemsToShow.length > 0) this.currentPage = 1;

this.announcementBarSlider = this.querySelector('.announcement-bar-slider');
// Value below should match --duration-announcement-bar CSS value
this.announcerBarAnimationDelay = this.announcementBarSlider ? 250 : 0;

this.sliderControlLinksArray = Array.from(this.sliderControlWrapper.querySelectorAll('.slider-counter__link'));
this.sliderControlLinksArray.forEach((link) => link.addEventListener('click', this.linkToSlide.bind(this)));
this.slider.addEventListener('scroll', this.setSlideVisibility.bind(this));
this.setSlideVisibility();

if (this.querySelector('.announcement-bar-slider')) {
if (this.announcementBarSlider) {
this.announcementBarArrowButtonWasClicked = false;

this.desktopLayout = window.matchMedia('(min-width: 750px)');
Expand Down Expand Up @@ -771,20 +779,35 @@ class SlideshowComponent extends SliderComponent {

onButtonClick(event) {
super.onButtonClick(event);
this.wasClicked = true;

const isFirstSlide = this.currentPage === 1;
const isLastSlide = this.currentPage === this.sliderItemsToShow.length;

if (!isFirstSlide && !isLastSlide) return;
if (!isFirstSlide && !isLastSlide) {
this.applyAnimationToAnnouncementBar(event.currentTarget.name);
return;
}

if (isFirstSlide && event.currentTarget.name === 'previous') {
this.slideScrollPosition =
this.slider.scrollLeft + this.sliderFirstItemNode.clientWidth * this.sliderItemsToShow.length;
} else if (isLastSlide && event.currentTarget.name === 'next') {
this.slideScrollPosition = 0;
}
this.slider.scrollTo({
left: this.slideScrollPosition,
});

this.setSlidePosition(this.slideScrollPosition);

this.applyAnimationToAnnouncementBar(event.currentTarget.name);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I noticed is that all the logic is added to be tackled onButtonClick when it should also be running on scroll/swipe 😬

If you use it on mobile and swipe instead of you will see that it doesn't apply all the changes necessary.

So I think you could either look into:

  • applying some of the announcement-bar-slider--fade-*** class in liquid by default. Since you know which slide will be showing on page load and which ones won't.
  • look at applying the same transitions in the update() function where it's checking what is the current page and what's the previous page. If you apply the logic you added to onButtonClick there it should work in all cases. Tho it might be triggered too late compared to when the button is clicked 🤔

From what I'm seeing it's working ok on page load. No animation is applied but at least all slides are being shown. If you click on the previous or next button though, and then swipe later, the slides are hidden. Ideally they would work whatever the method you're using to go to the next slide is.

RPReplay_Final1687551919.MP4

Copy link
Contributor Author

@eugenekasimov eugenekasimov Jun 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for flagging this Ludo.

This is happening because when you start scrolling/swiping we don't apply animation but some slides still have animation classes because we remove them only with the next cycle. I added code to prevent it. Now it looks good to me.

I would not apply animation for cases when we scroll/swipe because I think it looks better and more natural to have the effect we have now for scrolling.

Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having the animation on scroll/swipe would be good but I don't think we should delay this PR more for it. It could be a thing we look into adding in the future.


setSlidePosition(position) {
if (this.setPositionTimeout) clearTimeout(this.setPositionTimeout);
this.setPositionTimeout = setTimeout (() => {
this.slider.scrollTo({
left: position,
});
Comment on lines +807 to +809
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we use the new function you added here ? setSlidePosition(position)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inside itself?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh no, I didn't realize. It got me confused cause the function is so similar for the SliderComponent and SlideshowComponent. And named the same way as well though does it differently, one with a timeout and one without.

}, this.announcerBarAnimationDelay);
}

update() {
Expand Down Expand Up @@ -832,7 +855,7 @@ class SlideshowComponent extends SliderComponent {
} else if (this.autoplayButtonIsSetToPlay) {
this.pause();
}
} else if (this.querySelector('.announcement-bar-slider').contains(event.target)) {
} else if (this.announcementBarSlider.contains(event.target)) {
this.pause();
}
}
Expand Down Expand Up @@ -862,13 +885,13 @@ class SlideshowComponent extends SliderComponent {
const slideScrollPosition =
this.currentPage === this.sliderItems.length
? 0
: this.slider.scrollLeft + this.slider.querySelector('.slideshow__slide').clientWidth;
this.slider.scrollTo({
left: slideScrollPosition,
});
: this.slider.scrollLeft + this.sliderItemOffset;

this.setSlidePosition(slideScrollPosition);
this.applyAnimationToAnnouncementBar();
}

setSlideVisibility() {
setSlideVisibility(event) {
this.sliderItemsToShow.forEach((item, index) => {
const linkElements = item.querySelectorAll('a');
if (index === this.currentPage - 1) {
Expand All @@ -887,6 +910,38 @@ class SlideshowComponent extends SliderComponent {
item.setAttribute('tabindex', '-1');
}
});
this.wasClicked = false;
}

applyAnimationToAnnouncementBar(button = 'next') {
if (!this.announcementBarSlider) return;

const itemsCount = this.sliderItems.length;
const increment = button === 'next' ? 1 : -1;

const currentIndex = this.currentPage - 1;
let nextIndex = (currentIndex + increment) % itemsCount;
nextIndex = nextIndex === -1 ? itemsCount - 1 : nextIndex;

const nextSlide = this.sliderItems[nextIndex];
const currentSlide = this.sliderItems[currentIndex];

const animationClassIn = 'announcement-bar-slider--fade-in';
const animationClassOut = 'announcement-bar-slider--fade-out';

const isFirstSlide = currentIndex === 0;
const isLastSlide = currentIndex === itemsCount - 1;

const shouldMoveNext = (button === 'next' && !isLastSlide) || (button === 'previous' && isFirstSlide);
const direction = shouldMoveNext ? 'next' : 'previous';

currentSlide.classList.add(`${animationClassOut}-${direction}`);
nextSlide.classList.add(`${animationClassIn}-${direction}`);

setTimeout(() => {
currentSlide.classList.remove(`${animationClassOut}-${direction}`);
nextSlide.classList.remove(`${animationClassIn}-${direction}`);
}, this.announcerBarAnimationDelay * 2);
}

linkToSlide(event) {
Expand Down