CSS Var Animate

Welcome to this simple animation lib. This uses js to animate css variables for animations.

useCount

CSS variables can be great for simplifying styles, and separating styles from js. They can now even be animated, however only when we specify the number type with @property. This however does not yet have quite enough browser support, so here is a super simple js library to do that.

Counter Example -

Now you can use this to animate any style with a css var, that would otherwise be impossible (?) or tricky. Let's have a go at the material UI button bling bling, this example is from Lea Verou

useMouseOver

To get the relative position of the mouse over an element use useMouseOver(ref) and pass it the ref of the element that the event should listen to. it will also apply the css vars to this element. --mx and --my

-

Now use that animate anything you want, e.g. this background gradient.

useScroll

A react hook to animate a css variable on Scroll.

All it needs is a ref to the element you want to be observed. I tend to use a container not the element itself.

useScroller({ ref: elRef });

The basic ( and default) functionality of useScroll is to calculate the relative scroll position. By default this is a normalised percentage from the moment it is first visible to the moment it scrolls out of view
0 = Top of element is at (or below) bottom of scroll Window
and
1.0 = Bottom of element is at (or above) top of scroll window.

i.e. from the beginning to the end of the moment the element is within the scroll window.
See the rect below. By default this variable is applied as"--v" : [ 0 to 1.0 ]

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui.

We can animate or style anything in CSS with this custom prop.
E.g. move a block from the left to the right. Just transform usingvar(--v) and use transition to smoothen out the movement

transition: transform 0.1s linear

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui.

Percentage vs Scroll distance

As in the example above, when we are animating with relative values our elements will always go from point A to point B. But this means that the animation's distance / speed will vary with screen width and/or height.

E.g. our ball above will always roll from the left to the right side of screen, for the duration of us scrolling. When animations need to run at a fixed rate, or two animations in sync, we can achieve constant movement using the scroll distance--s (scroll) as a fixed distance rather than relative measure. The drawback here is we cannot guarantee the length / distance of the animation, i.e. the ball will not always reach the right side of the screen, or go out of the screen too early.

So we can rewrite the rolling ball animation using --s, see how it is constant over varying screen sizes.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui.

Default vars

By default view --v and scroll --s are applied to the element, but you can customise this with the customVars callback. This receives an additional top and bottom which vary from 0 to 1 as the top and bottom edge of the element each go from the bottom to the top of the window during scroll. To apply all variables to an element return them from the customVars callback as follows.

useScroller({ ref: elRef, customVars: ({ view, scroll, top, bottom }) => { return { "--s": scroll, "--v": view, "--t": top, "--b": bottom }; }, });

Demonstrated aon the object below, inspect the element to watch the behaviour of the various values.

Custom Vars

You can use the same function to apply extra custom variables by returning them from the function. Certain calculations can get tricky in pure CSS when we dont have access to things like '% modulus' operator or trigonometry sin(), cos() etc.

I know the first thing you are thinking is : Pacman on scroll animation. And yes, we can do that now. With hardly any js we can make him open and close his mouth repeatedly as he moves over the screen.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui.

Thresholds

In many cases however you might only want to trigger an animation when an item scrolls into view at a particular point. For this you can add a callback function to the object called threshold. This receives all the same arguments as the customVars callback above : scroll, view, top & bottom. So you have all the references needed to trigger your change at just the right time.

useScroller({ ref: elRef, threshold: ({ top }) => ({ res: top > 0.5, classTrue: "rollIn", classFalse: "rollOut", }), });

The callback needs to return an object with a result res - a boolean that evaluates if the element is above or below the threshold, as well as the classes classTrue and or classFalse which should be applied in each case.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui.

KERPOW!

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui.

B

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui. Etiam id neque quis sapien rutrum vulputate vitae sit amet tellus. Morbi a feugiat erat, at finibus dui. Fusce feugiat eros in ex mattis tempus. Suspendisse ullamcorper tellus at est tempor, tristique egestas neque hendrerit. Nunc massa leo, sodales at nisl finibus, porta sagittis magna. Nunc ultrices rutrum viverra.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui. Etiam id neque quis sapien rutrum vulputate vitae sit amet tellus. Morbi a feugiat erat, at finibus dui. Fusce feugiat eros in ex mattis tempus. Suspendisse ullamcorper tellus at est tempor, tristique egestas neque hendrerit. Nunc massa leo, sodales at nisl finibus, porta sagittis magna. Nunc ultrices rutrum viverra.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque interdum maximus libero, in ornare nunc tincidunt sit amet. Ut efficitur maximus molestie. Phasellus sed egestas elit, sed pharetra erat. Vivamus et facilisis dui. Etiam id neque quis sapien rutrum vulputate vitae sit amet tellus. Morbi a feugiat erat, at finibus dui. Fusce feugiat eros in ex mattis tempus. Suspendisse ullamcorper tellus at est tempor, tristique egestas neque hendrerit. Nunc massa leo, sodales at nisl finibus, porta sagittis magna. Nunc ultrices rutrum viverra.