usePageInView Hook

usePageInView is a tiny utility hook for tracking page/document visibility. This is useful for improving performance by pausing animations, video playback, or other activity when the user navigates to another tab, and resuming on return.

This saves CPU cycles, improves battery life, and helps ensure a smooth user experience.

To use the usePageInView hook, simply import it from Framer Motion and call it within your component. It returns a boolean value indicating whether the page is currently in view (visible) or not.

Example usage:

import { usePageInView } from "motion/react"

This state can be used to pause animations or videos when the page is hidden:

const videoRef = useRef(null)
const isInView = usePageInView()

useEffect(() => {
  const videoElement = videoRef.current
  if (!videoElement) return

  if (isInView) {
    videoElement.play()
  } else {
    videoElement.pause()
  }
}, [isInView])

Note : The value returned by usePageInView is not a motion value but instead it is a state variable.

Dragging Event in Framer Motion

In previous section we have discussed about dragging in framer motion using drag prop but in this section we will discuss about the dragging event in framer motion. Framer Motion provides several events that can be used to track the dragging state of a component. These events include:

  • onDragStart: This event is triggered when the user starts dragging the component.
  • onDrag: This event is triggered continuously while the user is dragging the component.
  • onDragEnd: This event is triggered when the user stops dragging the component.

example of using dragging events in framer motion:

import React from "react";
import { motion } from "framer-motion";
const App = () => {
  return (
    <div className="bg-black text-white h-screen w-screen items-center justify-center flex">
      <motion.div
        drag
        onDragStart={() => console.log("Drag started")}
        onDrag={() => console.log("Dragging")}
        onDragEnd={() => console.log("Drag ended")}
        className="bg-amber-950 w-36 h-36 rounded-xl font-sans overflow-hidden flex items-center justify-center"
      >
        Drag Me
      </motion.div>
    </div>
  );
};
export default App;

This will log messages to the console when the user starts dragging, is dragging, and stops dragging the component.

Information We get from dragging events

  • point: The current position of the pointer (mouse or touch) in screen coordinates.
  • offset: The distance the pointer has moved from its initial position when the drag started.
  • velocity: The current velocity of the pointer in pixels per second.

Example of using dragging events to get the position, offset and velocity of the pointer while dragging:

import React from "react";
import { motion } from "framer-motion";
const App = () => {
  return (
    <div className="bg-black text-white h-screen w-screen items-center justify-center flex">
      <motion.div
        drag
        onDrag={(event, info) => {
          console.log("Pointer position:", info.point);
          console.log("Pointer offset:", info.offset);
          console.log("Pointer velocity:", info.velocity);
        }}
        className="bg-amber-950 w-36 h-36 rounded-xl font-sans overflow-hidden flex items-center justify-center"
      >
        Drag Me
      </motion.div>
    </div>
  );
};
export default App;

Note: Value obtained through event likes point, offset and velocity are not motion values but instead they are a object containing the current position, offset and velocity of the pointer respectively .

Animation using dragging events

We can also use the dragging events to trigger animations based on the pointer’s position, offset,or velocity. For example, we can change the background color of the component based on the pointer’s velocity while dragging:

import React from "react";
import { motion } from "framer-motion";
const App = () => {
  const [bgColor, setBgColor] = React.useState("#34d399");
  return (
    <div className="bg-black text-white h-screen w-screen items-center justify-center flex">
      <motion.div
        drag
        onDrag={(event, info) => {
          const velocity = info.velocity.x;
          if (velocity > 1) {
            setBgColor("#f87171"); // Change to red if velocity is high
          } else {
            setBgColor("#34d399"); // Change to green if velocity is low
          }
        }}
        style={{ backgroundColor: bgColor }}
        className="w-36 h-36 rounded-xl font-sans overflow-hidden flex items-center justify-center"
      >
        Drag Me
      </motion.div>
    </div>
  );
};
export default App;

You can use motion value too instead of state to change the background color based on the pointer’s velocity while dragging for better performance.

SVG Animation

Framer Motion also supports animating SVG elements. The important thing to consider when animating SVGs. In this section we are covering

  • Component of SVG
  • Concept of ClassName in SVG
  • PathLength

Component of SVG

Generally each SVG contain :

  • path : The path element defines a shape using a series of commands and coordinates. It can be used to create complex shapes and curves.if we remove path element then element corresponding to that path will not be visible.
  • svg : The svg element is the container for all SVG elements. It defines the coordinate system and dimensions of the SVG.
  • stroke : The stroke property defines the color of outline of the shape
  • fill : The fill property defines the color used to fill the shape.

Note: stroke,fill can be applied to any SVG element like path,svg,rect,circle etc.

Concept of ClassName in SVG

In SVG , className is used to apply CSS styles to SVG elements. It allows you to define a class in your CSS. for this you have to set:

  • stroke=“currentColor” : This sets the stroke color to the current text color, allowing you to control the stroke color using CSS.
  • fill=“currentColor” : This sets the fill color to the current text color, allowing you to control the fill color using CSS. and use the className to apply styles to the SVG elements.
  • ‘stoke-red-500’ : This class sets the stroke color to red-500 from Tailwind CSS.
  • ‘fill-green-500’ : This class sets the fill color to green-500 from Tailwind CSS.

example:

<svg stroke="currentColor" fill="currentColor" className="stroke-red-500 fill-green-500">

in path:

<path
  className="stroke-red-500 fill-green-500"
  d="M10 10 H 90 V 90 H 10 Z"
  stroke="currentColor"
  fill="currentColor"
/>

pathLength

Generally pathLength is used to animate the stroke of a path. It defines the total length of the path and can be used in conjunction with the stroke-dasharray and stroke-dashoffset properties to create animations that draw the path over time.if:

  • pathLength is set to 1, the stroke will be drawn from start to end as the animation progresses.
  • pathLength is set to 0.5, the stroke will be drawn from start to the midpoint of the path as the animation progresses.
  • pathLength is set to 0, the stroke will not be drawn at all.

example of using pathLength to animate the stroke of a path:

import React from "react";
import { motion } from "framer-motion";
const App = () => {
  return (
    <div className="bg-black text-white h-screen w-screen items-center justify-center flex">
      <motion.svg
        width="200"
        height="200"
        viewBox="0 0 100 100"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <motion.path
          d="M10 10 H 90 V 90 H 10 Z"
          stroke="currentColor"
          fill="currentColor"
          strokeWidth="2"
          pathLength={1}
          initial={{ pathLength: 0 }}
          animate={{ pathLength: 1 }}
          transition={{ duration: 2 }}
        />
      </motion.svg>
    </div>
  );
};