@stkterry/react-reanim

1.0.1 • Public • Published

@stkterry/react-reanim

Simplify HTML5 canvas animations in React!

NPM JavaScript Style Guide

This project has two primary goals:

  1. Prevent React from constantly re-rendering when drawing to the canvas. Essentially, turn the canvas into a mostly static component.
  2. Separate the step / draw functionality from the associated boiler-plate common to virtually every canvas animation.

Install

npm install --save @stkterry/react-reanim

Usage

The following results in a simple, spinning cube as a basic example.

import React, { Component } from 'react'

import Reanim from '@stkterry/react-reanim'

export default function Simple() {

  const [angle, setAngle] = useState(0);

  const [style, setStyle] = useState();
  useEffect(() => {
    setStyle({ width: "250px", height: "250px",});
  }, [])

  const step = () => setAngle(angle + 1);

  const draw = ctx => {
    const width = ctx.canvas.width;
    const height = ctx.canvas.height;
    ctx.save();
    ctx.beginPath();
    ctx.clearRect(0, 0, width, height);
    ctx.translate(width / 2, height / 2);
    ctx.rotate(angle * Math.PI / 180);
    ctx.fillStyle = '#4397AC';
    ctx.fillRect(-width / 4, -height / 4, width / 2, height / 2);
    ctx.restore();
  };

  return (
    <Reanim
      step={step}
      draw={draw}
      width="250px"
      height="250px"
      style={style}
    />
  )
}

Reanim Options

Name Type Description Default
step function Animation step, updated each frame | REQUIRED
draw function Drawn to canvas each frame, must be written to include a canvas context input | REQUIRED
onClick function Normal 'onClick' functionality, automatically gets memoized*
onClickVars function onClick variables that you want to trigger a re-render when onClick is called* [ ]
run boolean Starts/stops the animation loop true
* onClick is passed to a useCallback to prevent constant re-render of the canvas component. If a re-render is required, users can pass the variables associated with onClick here that they wish to trigger the re-render. onClick is essentially: useCallback(yourOnClickFunction, [...onClickVars])


Reanim will accept any other attributes that are common to React/canvas and pass them accordingly (className, onMouseOver, style, width, height, etc...).

Important!

If you pass functions or objects to Reanim (excluding step/draw/onClick) without wrapping them in a useCallback or otherwise effectively memoizing them, you will trigger re-renders of the component on every frame! While not necessarily a problem, this can/will affect performance! I'm working on a solution that will auto-memoize commonly passed variables.

Other

Common canvas weirdness still applies to Reanim. It's up to you to know how to wield HTML5 canvas effectively. This component is just a wrapper to separate the step/draw functions from the typical boiler-plate necessary to get a canvas up and running.

Canvas

If you so desire, you can make use of the inner canvas component directly.

import React, { useState } from 'react';

import { Canvas } from '@stkterry/react-reanim';

export default function Example(props) {

  // ... some code here
  // ...
  // ...
  const [ctx, setCtx] = useState();
  // do something with ctx

  return (
    <Canvas setCtx={setCtx} />
  )
};

Note that the only variable Canvas requires is a setCtx function which should assign a 2d context off the node when mounted, otherwise Canvas will accept anything your standard canvas will. Canvas is memoized by default but remember that the contents you pass it may constantly trigger re-renders anyway.

Canvas is just a memoized regular canvas element with a passback for setting context.

Bonus Hooks!

useWindowDims

This hook returns the inner width and height of the current window. It's lightweight and will automatically add/remove the event listener. Updates on resize.

import React from 'react';

import { useWindowDims } from '@stkterry/react-reanim';

export default function Example(props) {

  const windowDims = useWindowDims();

  return (
    <div>
      <h2>innerWidth: {windowDims.width}</h2>
      <h2>innerHeight: {windowDims.height}</h2>
    </div>
  )
}

You may find this useful if you need to dynamically style or control your canvas based on window size.

To Do

  • Add target frame-rate functionality
  • Add collection of convenient hooks for working with the canvas
  • Implement a context simplification library for drawing
  • Add real tests...

License

MIT © stkterry

Package Sidebar

Install

npm i @stkterry/react-reanim

Weekly Downloads

1

Version

1.0.1

License

MIT

Unpacked Size

21.7 kB

Total Files

7

Last publish

Collaborators

  • stkterry