How to move elements on scroll in React.js? - css

I am trying to create an E-commerce Store and I'm a beginner in React.JS. What I want is for 5 images to come together on top of eachother when the user scrolls. (so they should move TranslateX on scroll). Previously, on Vanilla Javascript I would have added a window.addEventListener('scroll') and then set a value like value = window.scrollY and then I would have selected the image I wanted to move and simply translateX or Y based on that value.
However, I'm not sure how to do this in React. Where can I set the window event listener? Is there a state needed, or useEffect?
I'm attaching an image so you can clearly see what I am trying to do:
What I have in react is the "Scroll" component which contains 2 divs
-1 div on the left 2/3 flex size containing all the images that should come together
-1 div on the right 1/3 flex size containing the text and the button
inside the left div I have 5 images, and in CSS i've used position absolute to position them on top of eachother (they are all PNGs so they have transparent background).
How would I go about implementing this on my website?
HUGE thanks in advance!

You can save the scrollY in a useState, which you then use to transofrm your images. The window listeners can be loaded inside a useEffect.
It (could) look like this:
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
handleScroll();
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
(You may have to add some ESLint rules if you use it)

Related

Set React Component to Horizonal scroll on mouse wheel

I have a react component that displays a list of images horizontally across the page.
I would like to be able to scroll horizontally through them without having to hold in the SHIFT button.
Is there a way I change the default for just this component using css or react?
Here is my code: https://codesandbox.io/s/team-grid-slicer-2db8d
You can create a ref and bind it to your div which you will scroll. Here is a working codesandbox
Basically you create a ref and assign it to the div
const scrollRef = useRef()
...
<div ref={scrollRef}>
And you listen to the changes on the wheel event within the div:
if(scrollRef.current){
scrollRef.addEventListener('wheel', /* your function */)
}
And you scroll to left, instead of down based on the wheel event's deltaY:
el.scrollTo({
left: el.scrollLeft + e.deltaY * 5,
behavior: "smooth"
});
PS: You can remove * 5 but it looks better imo
just add an id="container to your component and then add
onWheel={(e) => {
e.preventDefault()
var container = document.getElementById('container')
var containerScrollPosition = document.getElementById('container').scrollLeft
container.scrollTo({
top: 0,
left: containerScrollPosition + e.deltaY,
behaviour: 'smooth' //if you want smooth scrolling
})
}}
This will listen to the onWheel and scroll your component.

How to control scrolling of component in React?

I have 4 main components for my React portfolio site called Home, Portfolio, About, Contact. The components are linked in Navigation. If I click on those link, Component appears. But the problem is if I scroll the Portfolio page 50% and click on About. The About page stay automatically scrolled top by 50%. I don't want an automated scroll. Rather I want the component will start from top 0;
I have tried "css-snap-type" but it doesn't work.
How can I solve the problem?
you could solve this using a react component that will scroll the window up everytime you click on a different link.
checkout this documentation is pretty straight forward https://reactrouter.com/web/guides/scroll-restoration
If you are using gatsby it comes with and API called called shouldUpdateScroll you could implement it on the gatsby.browser.js
const transitionDelay= 500
exports.shouldUpdateScroll = ({
routerProps: { location }, //location
getSavedScrollPosition, //last position on the previous page
}) => {
if(location.action === 'PUSH'){
window.setTimeout(()=> window.scrollTo (0,0), transitionDelay)
}
else {
const savedPosition = getSavedScrollPosition(location)
window.setTimeout(
()=> window.scrollTo((savedPosition || [0,0])),
transitionDelay
)
}
return false
}
U need to set window.scrollTo(0, 0) when u click on link so it would start on top of page.

How to move time axis to the right side in Fullcalendar?

If we set a dir property to rtl, then the time axis goes to the right side, I need the same, but the rest of the calendar should be in ltr mode. I tried swapping cells in the grid:
const timeElements = [].slice.call(slats.querySelectorAll('.fc-time'));
timeElements.forEach((item: HTMLElement) => {
const parent = item.parentNode;
if (parent) {
parent.insertBefore(parent.children[1], parent.children[0]);
}
});
But it breaks columns adjustment:
Screenshot
Is there any way to do that without changing the source code?

Using react-Beautiful-dnd, how can you change draggable dimensions before the drag begins (onBeforeCapture)

This is the code I've found to retrieve the correct draggable element and edit it's dimensions, during the onBeforeCapture() responder. Changing dimensions during this responder is in accordance with the documentation. This seems to work in only changing the dimensions, the other problems is that I am using the renderClone method, and so the draggable is just dragging with a huge offset that is not close to the correct mouse position. Also dnd is treating the drop placeholder as if the draggable is the original large size. Is there any way to correct for this mouse position, and placeholder dimensions? I've looked into adding mouseDown/mouseUp handlers on the inner element of the draggable but that doesn't seem to work either.
const cardSize = 140;
const draggableAttr = "data-rbd-drag-handle-draggable-id";
const getAttr = (key: string, value: string) => `[${key}=${value}]`;
const draggableQuery = getAttr(draggableAttr, update.draggableId);
const draggable = document.querySelector(draggableQuery);
draggable.setAttribute("style", `width: ${cardSize}px; height: ${cardSize}px;`);
I noticed onBeforeCapture was triggering after onDragEnd (therefore resizing the draggable improperly), so I created some state to remember the last beforeCaptureResult and return if it is equivalent to the current result.

React Scrollable and lockable side bars

I'm trying to create a scroll implementation similar to Facebook's feed in the way that they conditionally lock the side bars. For example if the content in the side bars is shorter than the viewport then the side bars don't scroll. If it does need to scroll, then it scrolls until the bottom of the side bar and stops at the end(all while allowing the center feed to keep scrolling)
The good part, I have almost all of this done, except for a few small issues and conditionally locking the side bars when they are fully in view.
The side bar contains quite a bit of data, and changes dynamically in height after everything is fetched. So my plan is below:
componentDidUpdate(prevProps) {
const leftSideBar = this.leftSideBar.current;
const scrollableWindow = window.innerHeight;
const sideBarHeight = leftSideBar.scrollHeight;
let offset = sideBarHeight - scrollableWindow;
if (this.state.offset !== offset) {
this.setState({ offset: offset });
if (offset > 0) {
this.setState({ lockScroll: false });
} else {
this.setState({ lockScroll: true });
}
}
}
This seems to be working inconsistently, sometimes the sideBarHeight is incorrect and I think it is because the component is updated and I'm getting that value before it is rendered and the height changes?
Basically I'm wondering if there is a better approach to this?

Resources