React useTornis - Hooks for Tornis
Hooks for Tornis which allow your components to track mouse and scroll position and velocity, and viewport size.
Install with npm:
npm i react-use-tornis
or yarn:
yarn add react-use-tornis
useTornis(
updateCallback: (TornisState) => void,
callOnWatch?: boolean = true,
dependencies?: Array<string> = []
) => void
This hook is a direct equivalent to the basic usage of Tornis. The callback passed to it will be called with the Tornis state object as a parameter. The callback function is called on subscribe if callOnWatch
is true. You can also specify dependencies, in which case the hook will only be called when one of the dependencies changed.
import React, { useState } from 'react';
import useTornis from 'react-use-tornis';
const ProgressBar = () => {
const [percent, setPercent] = useState(0);
useTornis(({ scroll, size }) => {
setPercent(scroll.top / (document.body.scrollHeight - size.y));
}, true, ['scroll', 'size']);
return (
<div className="progress-bar" style={{ transform: `scaleX(${percent})` }} />
);
};
export default ProgressBar;
This library also exposes specialised hooks that focus on a subset of the values Tornis handles. These work the same way as the useTornis
hook, but do not take any dependencies.
The available hooks are:
- useMouse
- useScroll
- useSize
- useOrientation
- This hook will always return
undefined
in the current version, as it is not supported by Tornis yet.
- This hook will always return
withTornis(
updateCallback: (HTMLElement, TornisState, ReactProps) => void,
ChildComponent: React.Component
) => void
You can use the withTornis
HOC to avoid using setState
to update your components, and cause a re-render on each viewport state update. However, only a single element can be controlled while using the HOC, so if your component updates multiple elements, you need to abstract them into separate components.
The component needs to be wrapped into a forwardRef
call and consume the ref on the HTML element to update. Note that the referenced element does not have to be the root element.
import React, { forwardRef } from 'react';
import { withTornis } from 'react-use-tornis';
const ProgressBar = withTornis(
(element, { scroll, size }, props) => {
if (scroll.changed || size.changed) {
const percent = scroll.top / (document.body.scrollHeight - size.y);
element.style.transform = `scaleX(${percent})`;
}
},
forwardRef(({ percent }, ref) => (
<div className="progress-bar" style={{ transform: `scaleX(${percent})` }} />
)),
);
export default ProgressBar;